Manpower

Check-in [b1cd9f7086]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Rev bump
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b1cd9f708623260ea276b4898b1a3531ceb05acd
User & Date: kevin 2018-04-23 02:05:08
Context
2018-04-26
03:20
Fix errors in softwareupdate package check-in: f97787a0ac user: kevin tags: trunk
2018-04-23
02:05
Rev bump check-in: b1cd9f7086 user: kevin tags: trunk
2017-12-09
05:27
Further tweak of services api check-in: 9950b08b34 user: kevin tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to libs/machelp/help.txt.

140
141
142
143
144
145
146




147
148
149
150
151
152
153
 * The "rman" tool for man page formatting. Website and license: [http://polyglotman.sourceforge.net/].
 * The "aem" package for custom Apple Event handling.  Website and license: [http://fossil.codebykevin.com].


-------------------
title: Manpower Version History
alias: Version History





'''6.6 (December 1, 2017):'''
 * UI enhancements.

'''6.5 (May 1, 2017):'''
 * Improved scrolling performance, security support on macOS.








>
>
>
>







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
 * The "rman" tool for man page formatting. Website and license: [http://polyglotman.sourceforge.net/].
 * The "aem" package for custom Apple Event handling.  Website and license: [http://fossil.codebykevin.com].


-------------------
title: Manpower Version History
alias: Version History

'''6.7 (April 20, 2018):'''
 * Migrate to new source code server. 
 * Minor bug fixes.

'''6.6 (December 1, 2017):'''
 * UI enhancements.

'''6.5 (May 1, 2017):'''
 * Improved scrolling performance, security support on macOS.

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

-------------------
title: License
alias: License
 
'''The MIT License (MIT)'''

Manpower source code: [http://fossil.codebykevin.com/fossil.cgi/manpower/]

Copyright (c) 2017 WordTech Communications LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.







|

|






245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

-------------------
title: License
alias: License
 
'''The MIT License (MIT)'''

Manpower source code: [https://www.codebykevin.com/fossil.cgi/manpower/]

Copyright (c) 2018 WordTech Communications LLC

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Changes to libs/manpower/manpower-main.tcl.

1
2
3
4
5
6
7
8
9
10
# Manpower: Man page browser and viewer 

#Copyright (C) 2017  WordTech Communications LLC

#MIT license

#let's get started

package require Img
package require BWidget


|







1
2
3
4
5
6
7
8
9
10
# Manpower: Man page browser and viewer 

#Copyright (C) 2018  WordTech Communications LLC

#MIT license

#let's get started

package require Img
package require BWidget
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
    global appversion
    global datadir
    global rmanpath
    global cachedir
    global searchterm
    global mynode
    
    appname::setAppName Manpower 6.6


    set rmanpath [file join [file dirname [info script]] rman]

    
    #check for app support directory
    set appdir [file join $::env(HOME) "Library" "Application Support" "Manpower"]







|







1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
    global appversion
    global datadir
    global rmanpath
    global cachedir
    global searchterm
    global mynode
    
    appname::setAppName Manpower 6.7


    set rmanpath [file join [file dirname [info script]] rman]

    
    #check for app support directory
    set appdir [file join $::env(HOME) "Library" "Application Support" "Manpower"]
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
    singleManPage
}


#custom "about" dialog
proc aboutWindow {} {

 tk_messageBox -parent . -icon info -title "About Manpower" -message "Manpower: Man Page Viewer" -detail "Version 6.6\n(c)2017 WordTech Communications LLC"

}

#raise window if closed--dock click
proc ::tk::mac::ReopenApplication {} {

    if { [wm state .] == "withdrawn"} {







|







1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
    singleManPage
}


#custom "about" dialog
proc aboutWindow {} {

 tk_messageBox -parent . -icon info -title "About Manpower" -message "Manpower: Man Page Viewer" -detail "Version 6.7\n(c)2018 WordTech Communications LLC"

}

#raise window if closed--dock click
proc ::tk::mac::ReopenApplication {} {

    if { [wm state .] == "withdrawn"} {

Changes to libs/softwareupdate/softwareupdate.tcl.

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	variable currentversion
	variable versionnumber

	set appname $app

	softwareupdate::checkingForUpdates

	set versionurl https://www.codebykevin.com/$appname-version.tcl
	http::config -useragent "$appname Update Check"

	if [catch {http::geturl $versionurl} msg] {
	    puts "error: $msg"
	    tk_messageBox -icon warning -title "Unable to Connect to Server" -message "Unable to Connect to Server" -detail "Unable to connect to www.codebykevin.com to check for updates. Please make sure you are connected to the Internet." -parent .
	catch {destroy .updateprogress}
	    return
	} 

	set versionnumber [string trim [http::data [http::geturl $versionurl]]]
	if [expr $currentversion < $versionnumber] {







|



|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
	variable currentversion
	variable versionnumber

	set appname $app

	softwareupdate::checkingForUpdates

	set versionurl [string tolower https://www.codebykevin.com/$appname-version.tcl]
	http::config -useragent "$appname Update Check"

	if [catch {http::geturl $versionurl} msg] {
	    if {[tk windowingsystem] ne "win32"} { puts "error: $msg"}
	    tk_messageBox -icon warning -title "Unable to Connect to Server" -message "Unable to Connect to Server" -detail "Unable to connect to www.codebykevin.com to check for updates. Please make sure you are connected to the Internet." -parent .
	catch {destroy .updateprogress}
	    return
	} 

	set versionnumber [string trim [http::data [http::geturl $versionurl]]]
	if [expr $currentversion < $versionnumber] {
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

	catch {destroy .updateprogress}

	catch {destroy .update}
	
	variable appname

	set changeurl https://www.codebykevin.com/$appname-changes.tcl

        if [catch {http::geturl $changeurl} msg] {
	    puts "error: $msg"
	    tk_messageBox -icon warning -title "Unable to Connect to Server" -message "Unable to Connect to Server" -detail "Unable to connect to www.codebykevin.com to check for updates. Please make sure you are connected to the Internet." -parent .
	    catch {destroy .updateprogress}
	    return
	} 


	set changelist [http::data [http::geturl $changeurl]]







|


|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

	catch {destroy .updateprogress}

	catch {destroy .update}
	
	variable appname

	set changeurl [string tolower https://www.codebykevin.com/$appname-changes.tcl]

        if [catch {http::geturl $changeurl} msg] {
	    if {[tk windowingsystem] ne "win32"} { puts "error: $msg"}
	    tk_messageBox -icon warning -title "Unable to Connect to Server" -message "Unable to Connect to Server" -detail "Unable to connect to www.codebykevin.com to check for updates. Please make sure you are connected to the Internet." -parent .
	    catch {destroy .updateprogress}
	    return
	} 


	set changelist [http::data [http::geturl $changeurl]]

Deleted libs/tablelist5.16/CHANGES.txt.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
What is new in Tablelist 5.16?
------------------------------

1.  Added the "-autofinishediting" configuration option, relevant for
    interactive cell editing via a combobox or menubutton widget (thanks
    to Alexandru Dadalau for his proposal).

2.  On Windows Vista, 7, 8, and 10, the sort arrows are now shown
    horizontally centered in the header labels and attached to their top
    edges.

3.  Added the arrow style "photo7x4" as well as its automatically scaled
    versions "photo9x5", "photo11x6", and "photo15x8", used as defaults
    on Windows Vista, 7, and 8.

4.  Added the tree style "mint2", suiting version 18 of the Linux Mint
    distribution.

5.  Support for fully qualified edit window names of the form "::ttk::*"
    (thanks to Adrian Medrano Calvo for his proposal).

6.  Worked around a text widget issue introduced in Tk 8.6.6 (thanks to
    Peter Spjuth, Harald Oehlmann, and Rene Zaumseil for their valuable
    input).

7.  Improvements related to the "move" and "movecolumn" subcommands as
    well as to the management of the images used in sort arrows (thanks
    to Adrian Medrano Calvo and Torsten Berg for their proposals).

8   Drastically increased the speed of the "collapse" and "collapseall"
    subcommands with the "-fully" option (thanks to Ulrich Seidl for
    reporting the pure performance of "collapseall -fully").

9.  Adapted the implementation of the "delete" subcommand to the changed
    text widget behavior in Tk 8.6.5 (thanks to Ulrich Seidl for his bug
    report).

10. Fixed a bug related to the "curcellselection" subcommand (thanks to
    Juge for his bug report).

What was new in Tablelist 5.15?
-------------------------------

1. Support for Windows 10, including the new tree style "win10", whose
   size is automatically adapted to the display's scaling level.

2. Added the arrow styles "flatAngle11x6" and "flatAngle15x8", needed
   for automatic scaling of the default arrow style "flatAngle7x4" on
   Windows 10.

3. The variable "tablelist::scalingpct", used by Tablelist when adapting
   the sizes of several tree styles to the display's DPI scaling level,
   is now documented in Tablelist Programmer's Guide.

4. Worked around a text widget bug introduced in Tk 8.5.18 and 8.6.4
   (fixed for the next Tk versions).

5. Fixed a bug that prevented the subcommands "see end", "see last", and
   "yview moveto 1" from working as expected if the tablelist widget
   contains multi-line cells or large images (thanks to Harald Oehlmann
   for his bug report and to Francois Vogel for discussions on this
   subject).

What was new in Tablelist 5.14?
-------------------------------

1. Added the "-colorizecommand" configuration option, enabling you to
   change the colors of arbitrary character regions within the cells of
   the currently visible tablelist rows (thanks to Peter Spjuth for his
   proposal).

2. The "curcellselection" and "curselection" subcommands now accept an
   optional argument with the possible values "-all", "-nonhidden", and
   "-viewable" (thanks to Will Duquette for his proposal).

3. Added the tree styles "plain1", ..., "plain4", "bicolor1", ...,
   "bicolor4", and "classic1", ..., "classic4", suitable for use with
   large fonts and images (needed on high-resolution displays).  In
   addition, the sizes used by the tree styles "vistaAero",
   "vistaClassic", "win7Aero", and "win7Classic" are now automatically
   adapted to the display's scaling level (thanks to Harald Oehlmann for
   his proposal).

4. On Windows Vista and later, automatic scaling is now performed for
   the default arrow style, too.  This made is necessary to add the
   arrow styles "flat11x6" and "flat15x8".

5  Added the arrow style "flat8x4" and the tree style "ubuntu2", suiting
   version 15.04 of the Ubuntu Linux distribution.  Similarly, added the
   tree style "yuyo", inspired by the GTK+ theme Yuyo on Ubuntu MATE.

6. Changed the default arrow color "" and arrow style "sunken10x9" to
   "black" and "flat7x5" on the windowing system "x11" and for the tile
   themes "alt", "clam", "default", "kroc", "sriv", "srivlg", and "step"
   (POTENTIAL INCOMPATIBILITY!).

7. In case of "-selecttype cell", the row containing the active cell is
   now displayed with raised relief (thanks to Holger Jakobs for his
   proposal).

8. Guarded against invocations of the "update" command from within
   binding scripts associated with the <<TablelistSelect>> virtual
   event (thanks to Martyn Smith for his bug report and discussions on
   this topic).

9. Worked around some unexpected events in certain X11 environments,
   which prevented Tablelist 5.13 from starting the interactive cell
   editing in such environments (thanks to Toni Giorgino for his bug
   report and helping me to reproduce this problem).

What was new in Tablelist 5.13?
-------------------------------

1. Added support for Mac OS X 10.10 (Yosemite) (thanks to Kevin Walzer
   for his proposal).

2. Renamed the four arrow styles having the shape of an angle from
   "flat7x5", ..., "flat10x6" to "flatAngle7x5", ..., "flatAngle10x6"
   (POTENTIAL INCOMPATIBILITY!); added the arrow styles "flat7x5",
   "flat9x6", "flatAngle7x4" (which is now the default on Yosemite),
   "flatAngle9x5", and "flatAngle10x7".

3. Added the tree style "mate", inspired by a few GTK+ themes of the
   MATE desktop.

4. Added the "-showeditcursor" configuration option, used to let the
   cursor take on the shape of a pencil whenever a mouse click would
   start an editing session (thanks to Rene Zaumseil and Cesare
   Bavazzano for their proposals).

5. New column configuration option "-changetitlesnipside", which allows
   you to override the alignment-specific default snip side for the
   column's title (thanks to John Vella for his proposal).

6. Support for the word "last" as row, column, cell, or child index,
   indicating the last row/column/cell of the tablelist or the last
   child of a given parent node (remember that the meaning of "end" as a
   row, column, or child index is subcommand-specific).

7. The description of the "imagelabelpath" subcommand in the reference
   manual now contains an example showing how to define bindings for the
   embedded images.

8. Eliminated the endless loop generated by the "yview" subcommand when
   synchronizing two or more tablelist widgets (thanks to Paul Obermeier
   for his bug report).

What was new in Tablelist 5.12.1?
---------------------------------

This is a bugfix-only release.  The corrected files in the "scripts"
directory are "tablelistEdit.tcl" and "tablelistUtil.tcl".

1. Appended the missing 4th argument to the two invocations of the
   procedure "tablelist::moveOrActivate" in the file
   "tablelistEdit.tcl" (thanks to Patrick Fradin and Ralf Fassel for
   their bug reports).

2. Fixed a typo in the file "tablelistUtil.tcl" (Thanks to Patrick
   Fradin for reporting this bug).

What was new in Tablelist 5.12?
-------------------------------

1. Added the "-customdragsource" configuration option, used to indicate
   whether the tablelist widget is a drag source for some drag & drop
   implementation other than TkDND and the drag & drop framework
   included in BWidget.

2. Improvements and extensions in the default binding scripts.  Besides
   providing full compatibility with the Tk listbox, they now perform an
   automatic drag-friendly handling of the selection and of pointer
   movements with mouse button 1 down if the "-customdragsource" option
   was set to true or the tablelist's body was registered as a TkDND or
   BWidget drag source (thanks to Will Duquette for his proposal).  The
   same holds true for the local drag & drop via the "move" subcommand.

3. Added the "hidetargetmark", "showtargetmark", "targetmarkpath", and
   "targetmarkpos" subcommands, for enhanced drop target support (thanks
   to Trevor Williams for his proposal).

4. Added a "Drag & Drop Support" section to the reference manual, with
   examples demonstrating the use of the new subcommands mentioned
   above in a tablelist widget registered as a TkDND or BWidget drop
   target.

5. The visibility of the horizontal separator placed just below the last
   tablelist row if the value of the "-showseparators" option is true
   and that of the "-fullseparators" option is false, can now be 
   controlled with the aid of the new "-showhorizseparator"
   configuration option (thanks to Martyn Smith for his proposal).

6. New values "flat5x3" and "flat5x4" for the "-arrowstyle"
   configuration option, suiting current versions of the Ubuntu Linux
   distribution.

7. Adapted the look & feel of the tree styles "adwaita", "ubuntu", and
   "mint" to current versions of the GTK+ 3 theme Adwaita and of the
   Linux distributions Ubuntu Linux and Linux Mint, respectively.

8. Fixed a long-standing bug related to horizontal scrolling in an empty
   tablelist widget with positve "-titlecolumns" value (thanks to Ulrich
   Seidl for his bug report).

What was new in Tablelist 5.11?
-------------------------------

1. Added the "findrowname" and "findcolumnname" subcommands (thanks to
   Adrian Medrano Calvo for his proposal and discussions on this
   subject).

2. Collapsing a row no longer leads to renumbering the lines for the
   purpose of updating a column configured to display the line numbers
   (thanks to Will Duquette for his proposal).

3. For improved appearance, if the value of the "-showseparators" option
   is true and that of the "-fullseparators" option is false, then a
   horizontal separator is now placed just below the last tablelist row
   (thanks to Allan Silverstein for his proposal).

4. Worked around a peculiarity of Tk on Windows, which caused problems
   when resizing the tablelist window in the presence of embedded images
   or multi-line elements (thanks to Will Duquette for his bug report).

5. Added the missing actualization of the active and anchor row indices
   after moving an item to a different position (thanks to Will Duquette
   for his bug report).

6. Fixed two bugs in Tablelist_tile, related to header labels with
   embedded images (thanks to Ulrich Seidl for his bug reports).

7. Numerous further improvements in the code and documentation.

What was new in Tablelist 5.10?
-------------------------------

1.  Added the "-acceptdropcommand" configuration option, used to control
    whether the local drag & drop may move a specified item just before
    a given row (thanks to Nagu and Georgios Petasis for discussions on
    this subject).

2.  Added the "-instanttoggle" configuration option, related to the cell
    editing with the aid of a Tk or tile checkbutton (thanks to Rich
    Wellner for his proposal and discussions on this topic).

3.  Added the "-tight" configuration option, used to eliminate the
    one-pixel additional space left below each tablelist row for Tk
    listbox compatibility (thanks to Koen Breugelmans for his proposal
    and discussions on this subject).

4.  Added the "isviewable" and "viewablerowcount" subcommands (thanks to
    Nagu for proposing the latter).

5.  Improvements related to the value of the "-data" option for the
    virtual events <<TablelistColumnMoved>> and <<TablelistRowMoved>>
    (thanks to Georgios Petasis for discussions on this topic).

6.  The item deletion has become significantly faster, especially in
    tablelists used as tree widgets and in the presence of embedded
    images and/or multi-line elements (thanks to Rob Ratcliff and Rene
    Zaumseil for requesting this performance improvement).

7.  Guarded against column deletions from within non-default binding
    scripts for the header labels (thanks to Ulrich Seidl for his
    input).

8.  Restored the support for Tcl/Tk versions earlier than 8.3, by
    cleaning up the use of elided text in the underlying text widget.
    Similarly, restored the support for Tcl/Tk 8.0, by cleaning up the
    use of "regsub" and that of the <MouseWheel> event (thanks to Joerg
    Mueck for reporting the first two issues).

9.  Improved the package loading mechanism (thanks to Paul Obermeier for
    his bug report).

10. Guarded against potential item insertions or deletions from within
    the command specified as the value of the "-editendcommand" option
    (thanks to Julian H J Loaring for his bug report).

11. Guarded against deletion of embedded images or windows from within
    the command specified as the value of the "-tooltipaddcommand"
    option (thanks to Jan Kandziora for his bug report).

12. Fixed a bug related to column deletion if the "-selecttype" option
    has the value "cell" (thanks to Ulrich Seidl for his bug report).

13. Several further code improvements and minor bug fixes.

What was new in Tablelist 5.9?
------------------------------

1. Added the "-valign" column and cell configuration option, for
   controlling the vertical alignment of embedded images and windows
   (thanks to Trevor Williams for his proposal).

2. The "-stripebackground" and "-stripeforeground" options can now be
   specified at column level, too (thanks to Christian Gollwitzer for
   his proposal).

3. Improvements related to the Windows 7 platform.

4. Worked around a text widget bug in Tk versions 8.5 and later, related
   to getting the index of the last line in the window if some of the
   lines are elided (thanks to Bernhard Wallner for his bug report).

5. Corrected a typo in the implementation of the "rowconfigure"
   subcommand, introduced in the last Tablelist version (thanks to Jerzy
   Witkowski for reporting this bug).

6. Fixed a bug related to resetting the "-(select)background" and
   "-(select)foreground options at column, row, and cell levels,
   introduced in the previous Tablelist version (thanks to Christian
   Gollwitzer for his bug report).

7. Several further improvements in the code, demo scripts, and
   documentation.

What was new in Tablelist 5.8?
------------------------------

1.  Support for interactive cell editing with the aid of the ctext
    widget (thanks to Sait Dogru for his proposal).

2.  Added the "canceledediting" subcommand (thanks to Martyn Smith for
    his proposal).

3.  The "selection" and "cellselection" subcommands have become by
    orders of magnitude faster (thanks to Jean-Francois Beaud for his
    input that motivated me to speed up these subcommands).

4.  The "-(select)background" and "-(select)foreground options at
    column, row, and cell levels now impose by far less performance
    penalty than in earlier Tablelist versions.

5.  The keyboard traversal during interactive cell editing is now aware
    of changes like appending a new row, performed by the procedure
    specified as the value of the "-editendcommand" configuration option
    (thanks to Andreas Leitgeb for his proposal).

6.  For Tk versions 8.5 or later, most virtual events are now generated
    with the "-data" option set to a suitable event-specific value
    (thanks to Christian Gollwitzer, Andreas Leitgeb, and Nagu for their
    proposals).

7.  Improvements related to the selection mode "extended".

8.  Worked around a peculiarity of Tk on Windows, related to deleting an
    embedded window while resizing a text widget interactively (thanks
    to Harald Oehlmann for his bug report and discussions on this
    topic).

9.  Eliminated a regression introduced in Tablelist version 5.6, related
    to vertical scrolling under Tk 8.5 or later in the presence of
    embedded images or windows (thanks to Patrick Fradin for reporting
    this bug).

10. Fixed a screen refresh problem introduced in Tablelist version 5.6,
    related to wrapped multiline elements (thanks to Rob for his bug
    report).

11. Further code improvements (thanks to Harald Oehlmann for his
    valuable contribution).

12. Added a "Virtual Events" section to the reference manual (thanks to
    Andreas Leitgeb for his proposal).

What was new in Tablelist 5.7?
------------------------------

1.  Added the "cellbbox" subcommand.

2.  Added the "editinfo" subcommand (thanks to Trevor Williams for his
    proposal).

3.  Adapted the tree styles "ubuntu" and "mint" to the latest Ubuntu
    Linux and Linux Mint releases.

4.  Minor change related to the ttk::combobox widget used as edit window
    (thanks to Julian H J Loaring for his input).

5.  Improved the multi-platform support by increased use of virtual
    events.

6.  Worked around a bug in some earlier Tk versions, related to
    checkbuttons without indicator (thanks to Allan Silverstein for his
    input).

7.  Restored the support for Tcl/Tk versions earlier than 8.4, which has
    been broken since the previous Tablelist release, due to the use of
    the "namespace exists" command, introduced in Tcl 8.4 (thanks to
    Ralf Fassel for drawing my attention to this issue).

8.  Fixed a copy & paste bug related to embedded windows, introduced in
    the previous Tablelist version (thanks to Heng Li and David Hanks
    for their bug reports).

9.  Fixed a long-standing bug related to the "cancelediting" subcommand
    and the "-forceeditendcommand" option (thanks to Julian H J Loaring
    for his bug report).

10. Fixed a long-standing minor bug that caused the "-labelbg" column
    configuration option to be accepted by Tablelist_tile, contrary to
    the option of the same name at widget level (thanks to Bernhard
    Wallner for his bug report).

11. Several further improvements in the code and demo scripts (thanks to
    Patrick Fradin for his valuable contribution and to Marianne Baumann
    for her input related to the "-showlabels" option).

What was new in Tablelist 5.6?
------------------------------

1.  Added the tree styles "adwaita", "mint", and "ubuntu", inspired by a
    few GTK+ 3 themes on popular Linux distributions.

2.  Added the "-windowupdate" cell configuration option (thanks to
    Trevor Williams for his valuable contribution).

3.  The item insertion and sorting have become significantly faster,
    especially when using static-width columns.

4.  Embedded windows are now hidden during interactive cell editing
    (thanks to Trevor Williams for discussions on this subject).

5.  Extended the support for the "tileqt" theme to work on KDE 4, too.

6.  Improvements in the documentation (thanks to Glenn Herteg for his
    proposal).

7.  Guarded against the case that a tablelist widget is deleted and its
    name is reused for a widget of a different class (thanks to Roger
    Niva for his valuable input).

8.  Guarded against scripts that start by destroying all children of the
    root window (thanks to Helmut Giese and Gerhard Kraus for drawing my
    attention to this case).

9.  Fixed two bugs related to the "move" subcommand, introduced in
    Tablelist version 5.2 (thanks to "DrS" and Trevor Williams for their
    bug reports).

10. Several further improvements and minor bug fixes.

What was new in Tablelist 5.5?
------------------------------

1. Hidden tablelist elements are no longer excluded from the selection
   (thanks to Martyn Smith for his proposal).  (They are, however,
   ignored when exporting the selection.)

2. Added the "cornerpath" and "cornerlabelpath" subcommands.  The first
   one makes it quite easy to respect the native Mac OS X look & feel,
   where the vertical scrollbar appears placed under the header (thanks
   to Torsten Berg for a related page on the Wiki, which provided me the
   idea for these subcommands).  The "cornerpath" subcommand is now used
   in all demo scrips that contain vertical scrollbars.

3. Added support for the appearance-related changes introduced in Mac
   OS X 10.7 (Lion).

4. On Mac OS X Aqua, the default values of the "-move(column)cursor"
   and "-resizecursor" options are now native cursors.  Besides
   improving the look & feel of tablelist widgets on the Mac, this
   change also works around the problem that on Mac OS X 10.7, Tk
   versions 8.5 and 8.6 can only use native and native-mapped cursors.

5. Removed the "-labelbackground" option from Tablelist_tile, because
   current versions of the tile engine no longer support setting the
   background color for the header labels (and even with earlier tile
   versions, some themes ignored any attempt to change the background
   color of the header labels).

6. Adapted the code to some changes in current tile versions, to make
   sure that in disabled state the tile-based column labels will appear
   in the theme-specific disabled foreground color, as it was the case
   with earlier tile versions (thanks to "tombert" for his related
   posting on comp.lang.tcl).

7. Improved a few binding scripts (thanks to Ulrich Seidl for his bug
   report and testing).

8. Fixed a bug related to embedded windows in a tablelist used as a
   tree widget (again, thanks to Ulrich Seidl for his bug report and
   testing).

9. Several further improvements in the code, demo scripts, and
   documentation.

What was new in Tablelist 5.4?
------------------------------

1. Added the "-populatecommand" configuration option, used by the
   "searchcolumn" subcommand to insert child items on demand before
   checking whether they contain the specified pattern.
   
2. Added the "-autoscan" configuration option, which can be used to
   deactivate the automatic scrolling triggered by leaving the
   tablelist window with mouse button 1 down, in order to avoid any
   conflicts with drag & drop via tkdnd (thanks to Patrick Fradin for
   his valuable contribution).

3. New "isexpanded" subcommand.

4. New value "flat9x6" for the "-arrowstyle" configuration option.

5. Adapted the tree style "oxygen2" to the look of current KDE 4
   versions.

6. Worked around some peculiarities of Tk on Mac OS X Aqua (thanks to
   Torsten Berg for her problem report and discussions on this topic).

7. Improved the check for PNG support in Tk (thanks to Ian Gay for his
   posting on the Wiki related to this subject).

8. Fixed a bug related to the tree style "aqua", introduced in
   Tablelist version 5.3 (thanks to Julian H J Loaring for his bug
   report).

9. Numerous further improvements in the code and documentation.

What was new in Tablelist 5.3.1?
--------------------------------

This release contains just one bug-fix and an enhancement:

1. Fixed a bug related to the "-hide" row configuration option,
   introduced in the previous Tablelist version (thanks to Ralf Fassel
   and Michal Sosnowski for their bug reports).

2. Extended the support for the native "Aqua-blue" background for the
   header label of the sort column (which in the previous Tablelist
   release was restricted to Tk versions 8.6 and above) to the Cocoa-
   based Tk patch levels 8.5.9 and above (thanks to Kevin Walzer for
   discussions on this topic and to Paul Obermeier for enabling me to
   access the ActiveTcl 8.5.8 distribution for the Mac).

What was new in Tablelist 5.3?
------------------------------

1. The interactive row move operation (i.e., local drag & drop) now
   supports moving an item outside its parent and dropping it under
   another item as a child (thanks to Dr. Detlef Groth for his
   proposal, thorough testing, and discussions on this topic).

2. Added the "-acceptchildcommand" configuration option, related to the
   local drag & drop.

3. New "searchcolumn" subcommand, supporting a rich set of options
   (thanks to Matthew Callaghan, Adrian Davis, and Jeff Godfrey for
   their proposals).

4. New "getformatted", "getformattedcolumns", and "getformattedcells"
   subcommands.

5. Support for interactive cell editing with the aid of the Tk core and
   tile menubutton widgets (thanks to Georgios Petasis for his
   proposal).

6. Support for the row indices "top" and "bottom" (thanks to Julian H J
   Loaring and Paul Obermeier for their proposals).  Likewise, support
   for the column indices "left" and "right".

7. New value "photo7x7" for the "-arrowstyle" configuration option,
   needed for the "aqua" theme.

8. Adapted the appearance of tablelist widgets on the Macintosh to
   current versions of OS X Aqua.

9. Numerous further improvements and minor bug fixes.

What was new in Tablelist 5.2?
------------------------------

1.  Added the "-fullseparators" configuration option (thanks to Kevin
    Partin, Martyn Smith, and Harald Oehlmann for their proposals).

2.  Added the tree styles "ambiance", "dust", "dustSand", "newWave",
    "plastik", and "radiance".

3.  The implementation of the "collapse(all)" and "expand(all)"
    subcommands no longer makes use of the "-hide" row configuration
    option, hence you are now free to set the latter (via
    "rowconfigure", "configrowlist", "configrows", or "togglerowhide"),
    regardless of whether the tablelist widget displays a tree
    hierarchy or just a plain list.

4.  The "move" subcommand now supports moving an item outside its
    parent.

5.  Deleting the whole content of a tablelist widget has become
    significantly faster (thanks to Harold Campbell for his input).

6.  Worked around a peculiarity of the text widget related to tag
    handling when deleting a range of lines from its end (thanks to
    Batox for his bug report).

7.  Minor improvements and bug-fixes in the binding scripts (thanks to
    Bernhard Wallner, Batox, and Roger Niva for their bug reports).

8.  Fixed a bug related to the "-selecttype cell" configuration option,
    (re)introduced in Tablelist version 5.0 (thanks to Harold Campbell
    and Dietmar Mueller for their bug reports).

9.  Fixed a bug related to row hiding via "configrowlist" or
    "configrows", introduced in Tablelist version 5.0 (thanks to Michal
    Sosnowski for his bug report).

10. Fixed a long-standing bug related to tooltip support (thanks to
    Trevor Williams for his bug report).

11. Several further improvements and minor bug fixes.

What was new in Tablelist 5.1?
------------------------------

This is a bugfix-only release.  The corrected files in the "scripts"
directory are "tablelistBind.tcl", "tablelistSort.tcl",
"tablelistUtil.tcl", and "tablelistWidget.tcl".

1. Fixed a bug related to item deletion, introduced in the previous
   Tablelist version (thanks to Aric Bills and Roger Niva for their bug
   reports).

2. Fixed a bug related to multi-column sorting, introduced in the
   previous Tablelist version (thanks to Albrecht Mucha for his bug
   report).

3. Fixed a long-standing bug related to column deletion (thanks to
   Liang Sian Yin for his bug report).

4. Fixed a few further minor bugs and typos, introduced in the previous
   Tablelist version (thanks to Patrick Fradin, Roger Niva, Harald
   Oehlmann, and Peter Spjuth for their bug reports).

What was new in Tablelist 5.0?
------------------------------

1.  A tablelist widget is now not only a multi-column listbox, but also
    a multi-column tree widget (thanks to Sebastien Barre, Tillmann
    Basien, Jos Decoster, Dr. Detlef Groth, Kai Morich, Georgios
    Petasis, and Kevin Walzer for their proposals, as well as to Paul
    Obermeier for testing the preliminary version).  This is achieved
    with the aid of the new configuration options "-collapsecommand",
    "-expandcommand", "-treecolumn", and "-treestyle", along with the
    new subcommands "childcount", "childindex", "childkeys", "collapse",
    "collapseall", "depth", "descendantcount", "expand", "expandall",
    "expandedkeys", "insertchild(ren)", "insertchildlist", "noderow",
    "parentkey", and "toplevelkey".

2.  Added the "-editselectedonly" configuration option, related to
    starting the interactive cell editing with mouse button 1 (thanks to
    Julian H J Loaring for discussions on this topic).

3.  New values "flat6x4", "flat9x7", and "flat10x6" for the
    "-arrowstyle" configuration option.

4.  New value "asciinocase" for the "-sortmode" column configuration
    option.

5.  New subcommands "applysorting", "getfullkeys", and "refreshsorting".

6.  Two new demo scripts (and their tile-based counterparts)
    illustrating the use of a tablelist as multi-column tree widget.

7.  The subcommands "insert", "insertlist", "insertchild(ren)", and
    "insertchildlist" now return the list of full keys corresponding to
    the items just inserted.

8.  Fixed a long-standing bug related to the "-labelfont" option (thanks
    to Jacek Jendrysik for his bug report).

9.  Fixed a bug related to the "-text" column configuration option
    (thanks to Paul Obermeier for his bug report).

10. Fixed a long-standing bug related to embedded windows in right-
    aligned columns (thanks to Jerzy Witkowski for his bug report).

11. Numerous further improvements in the code and documentation.

What was new in Tablelist 4.12?
-------------------------------

1.  Added the "labeltag" subcommand and the helper command "tablelist::
    getTablelistColumn", designed to be used in non-default binding
    scripts for the header labels.

2.  Support for interactive cell editing with the aid of the tile
    spinbox widget.  The demo script "tileWidgets.tcl" now uses this
    widget when available.

3.  Support for interactive cell editing with the aid of the new mentry
    widget for IPv6 addresses.

4.  Improved the support for Windows Vista and added explicit support
    for the "vista" theme.

5.  Updated the support for the themes "plastik" and "keramik"; added
    support for the "keramik_alt" theme.

6.  Support for the native "Aqua-blue" background, set for the header
    label of the sort column (thanks to Kevin Walzer for his proposal
    and valuable contribution).  For technical reasons, this feature is
    only supported for Mac-Tk versions using Cocoa.

7.  Further improvements in the support for Mac OS X Aqua (thanks to
    Daniel Steffen and Kevin Walzer for their valuable feedback).

8.  Improvements in the binding scripts related to interactive cell
    editing (thanks to Hadas Porat for discussions on this subject).

9.  The binding for the <Double-Button-1> event in the resize area of a
    column header now works as expected for large lists, too.

10. Eliminated a minor regression related to interactive cell editing,
    introduced in the previous Tablelist version (thanks to Kai Morich
    for his valuable input).

11. Fixed a small bug related to interactive cell editing with the aid
    of a text widget (thanks to Bryan Oakley for his bug report and
    valuable suggestion).

12. Fixed a long-standing bug related to the "-listvariable" option in
    disabled state (thanks to Ralf Fassel for his bug report).

13. Added a version-related hint to the "How to use it?" section of the
    Tablelist Programmer's Guide.

What was new in Tablelist 4.11?
-------------------------------

1.  Added the "-columntitles" configuration option, which is mainly a
    simplified form of the "-columns" option (thanks to Roy Terry for
    his proposal).

2.  Added the virtual events <<TablelistColHiddenStateChanged>> and
    <<TablelistRowHiddenStateChanged>>, generated after toggling the
    hidden state of a column or row, respectively (thanks to Jeff 
    Godfrey for his proposal).

3.  Besides with <Button-3>, the optimal column width can now be set
    with <Double-Button-1> in the resize area of the column's header.
    Similarly, the effect of <Shift-Button-3> can also be achieved with
    <Shift-Double-Button-1> in the column label's resize area.

4.  Support for Windows Vista (thanks to Jeremy Cowgar for his input).

5.  The recommended package name is now "tablelist" rather than
    "Tablelist", for compatibility with the ActiveTcl distribution; the
    demo scripts have been changed accordingly.

6.  Made sure that the "-tooltipdelcommand" configuration option won't
    affect other widgets (thanks to Jeff Godfrey for drawing my
    attention to this issue).

7.  Fixed a long-standing nasty bug related to the "yview" subcommand
    (thanks to Nestor Patino for his bug report and very helpful example
    script).

8.  Fixed two bugs related to the "-listvariable" configuration option
    (again, thanks to Nestor Patino for his valuable input).

9.  Fixed a bug related to the item deletion when using Tcl/Tk 8.5
    (thanks to Jos Decoster and Sven Wuytack for their valuable
    contribution to finding and fixing this bug).

10. Fixed a bug related to the "-windowdestroy" cell configuration
    option, introduced in Tablelist 4.9 (thanks to Sebastien Barre for
    his bug report).

What was new in Tablelist 4.10?
-------------------------------

1.  Support for individual binding scripts controlling the interactive
    cell editing, with the aid of the new "editwintag" subcommand
    (thanks to Oscar Fuentes for his valuable input).

2.  Complemented the "attrib" subcommand with the new subcommands
    "hasattrib" and "unsetattrib".

3.  Support for column-, row-, and cell-specific attributes, with the
    aid of the new subcommands "columnattrib", "hascolumnattrib",
    "unsetcolumnattrib", "rowattrib", "hasrowattrib", "unsetrowattrib",
    "cellattrib", "hascellattrib", and "unsetcellattrib".

4.  Support for interactive cell editing with the aid of the new mentry
    widget of type "DateTime", introduced in version 3.2 of the Mentry
    package (thanks to Florian Murr for his proposal).

5.  Made sure that the default bindings are set up immediately when
    loading the package, prior to creating any tablelist widget (thanks
    to Schelte Bron for his proposal and discussions on this topic).

6.  Re-established the support for tile widgets as edit windows in non-
    tile-based tablelist widgets (again, thanks to Schelte Bron for
    reporting that this was broken in the last few Tablelist versions).

7.  Adapted the handling of the tile checkbutton as edit window in the
    "xpnative" theme to some changes made in tile 0.8 (thanks to Jeff
    Godfrey for his bug report).

8.  Guarded against potential widget deletion from within user-defined
    binding scripts or "update (idletasks)" (thanks to Schelte Bron and
    Jan Kandziora for their bug reports).

9.  Updated the (very rarely needed) distribution file "repair.tcl" to
    work with current Tablelist versions (thanks to Robert Stollf for
    his bug report).

10. Corrected the description of the "-height" option in the reference
    manual (thanks to Glenn Herteg for his bug report concerning the
    case "-height 0").

11. Improved the color handling in the "disabled" state (thanks to Rolf
    Ade for his bug report and discussions on this topic).

12. Made the handling of elided text more robust (thanks to Jos Decoster
    for his bug report and valuable contribution).

13. Several further improvements and minor bug fixes (thanks to Albrecht
    Mucha for his valuable input).

What was new in Tablelist 4.9?
------------------------------

1.  Added the "-wrap" column configuration option, which makes it
    possible to display long texts in word-wrapped multi-line rather
    than snipped form (thanks to Alexander Schoepe and Anant Adke for
    their proposals).  Also, added support for interactive cell editing
    with a word- or char-wrapped text widget when using Tk 8.5 (thanks
    to Juberi Rajib for discussions on this topic).

2.  Support for dynamic-width embedded windows, with the aid of the new
    "-stretchwindow" cell configuration option (thanks to Kurt Kurczyk,
    Bryan Oakley, and Rasmus Debitsch for their proposals). The demo
    script "embeddedWindows.tcl" and its tile-based counterpart now make
    use of this option.

3.  New "formatinfo" subcommand, returning information about the cell
    whose content is being formatted by a command specified as the value
    of the "-formatcommand" column configuration option (thanks to Goran
    Ivankovic and Sebastien Barre for their proposals).

4.  Changed the default value of the "-activestyle" configuration option
    from "underline" to "frame" and that of the "-setfocus" option from
    0 to 1, making them conform to similar changes in Tk 8.5 related to
    the listbox widget.

5.  Improved the appearance of the header labels for the "aqua" theme
    (thanks to Torsten Berg for discussing this topic on the Wiki).

6.  Eliminated the potential invocation of the "unknown" command from
    within the Tablelist code (thanks to Roger Niva for discussions on
    this topic).

7.  When starting the interactive cell editing with the aid of a
    combobox widget, the list associated with the latter is only dropped
    down if the combobox is read-only (thanks to Bryan Oakley for his
    proposal).

8.  The "setThemeDefaults" command no longer throws an error if the
    current theme is not explicitly supported by Tablelist.  Instead, it
    uses the options set by the current theme and falls back to the
    "default" one for the rest (thanks to Schelte Bron for his valuable
    contribution).

9.  Improved the tablelist widget's appearance when the header labels
    are not shown (thanks to Mark Garvey for his input).

10. Fixed two bugs related to the optimized item insertion (thanks to
    Harold Campbell and Bryan Oakley for their bug reports).

11. Fixed a bug related to the "-showlinenumbers" column configuration
    option (thanks to Martin Lemburg for his bug report).

12. Several further improvements and minor bug fixes.

What was new in Tablelist 4.8?
------------------------------

This release fixes a few nasty bugs related to the optimized item
insertion, introduced in the previous Tablelist version (thanks to
Harold Campbell, Roger Niva, and Joerg Klingseisen for their bug
reports).

What was new in Tablelist 4.7?
------------------------------

1.  Significant performance improvements related to the "insert",
    "rowconfigure", "sort", "sortbycolumn", and "sortbycolumnlist"
    subcommands (thanks to Harold Campbell for his valuable
    contribution to speeding up the item insertion).  The extent of the
    speed-up depends on the configuration options present at column,
    row, and cell levels.

2.  Support for cell- and column label-specific balloon help, with the
    aid of the new configuration options "-tooltipaddcommand" and
    "-tooltipdelcommand".

3.  New subcommands "iselemsnipped" and "istitlesnipped", which make it
    very easy to display the full cell texts and column titles as
    tooltips for cells and header labels with snipped contents.

4.  New subcommands "configcolumnlist", "configcolumns",
    "configrowlist", "configrows", "configcelllist", and "configcells",
    which allow you to configure several columns/rows/cells with a
    single command invocation (thanks to Harold Campbell, Jeff Godfrey,
    and Paul Obermeier for their proposals).

5.  Worked around some performance problems regarding the "switch"
    command in Tcl 8.5a6/8.5b1 and ActiveTcl 8.4.14.

6.  Made sure that ActiveState's "style::as" package won't break the
    mousewheel bindings (thanks to Michael Schlenker for drawing my
    attention to this problem).

7.  Improved the focus handling when resizing a column interactively
    (thanks to Jorge Enderr for his bug report).

8.  Corrected a typo in the adaptation of vertical scrolling to the
    text widget changes made in Tk 8.5 (thanks to Julian M Noble for
    his posting on the Wiki related to this subject).

9.  Fixed a bug related to hidden rows when having "-selecttype cell",
    introduced in Tablelist version 4.3 (thanks to Harold Campbell for
    his bug report and discussions on this subject).

10. Fixed a bug in the "cellconfigure" subcommand, introduced in the
    previous Tablelist release (thanks to Roy Terry for reporting this
    problem on the Wiki).

11. Fixed a bug in the "-changesnipside" option (thanks to Kai Morich
    for his bug report).

12. Numerous further improvements in the code and documentation.

What was new in Tablelist 4.6?
------------------------------

1.  Tablelist_tile now supports tile 0.8 and Tk 8.5a6/8.5b1 (where tile
    is integrated in the core).  The new commands "tablelist::setTheme",
    "tablelist::getCurrentTheme", and "tablelist::getThemes" enable you
    to set and get the current theme and to query the available ones,
    without having to worry about the incompatibilities between the
    various tile versions.

2.  New column configuration option "-changesnipside", which allows you
    to override the alignment-specific default snip side (thanks to
    Georgios Petasis for his proposal).

3.  New "columnwidth" subcommand, with the options "-requested",
    "-stretched", and "-total" (thanks to Matthew Callaghan, Richard
    Finstad, Lieven Forrez, and Tom Roeder for their proposals).

4.  Support for the new virtual event <<TablelistColumnResized>>,
    generated after resizing a column interactively (thanks to Kurt
    Kurczyk for his proposal).

5.  Visual improvement:  Within an active row, the gap to the left or
    right of an embedded image or window no longer appears underlined
    (when the "-activestyle" option has its default value "underline").

6.  Embedded images and windows are no longer hidden during interactive
    cell editing (except the editing with the aid of a Tk or tile
    checkbutton widget).

7.  Significantly improved the redraw and stretching behavior when
    resizing a column interactively.

8.  Eliminated some annoying visual effects caused by hidden columns
    when displaying the items of an already visible tablelist widget
    (thanks to Rolf Ade for discussions on this topic).

9.  Adapted the implementation of vertical scrolling to the text widget
    changes made in Tk 8.5 (thanks to Julian M Noble for his posting on
    the Wiki related to this subject).

10. Fixed a bug related to hidden rows, introduced in Tablelist version
    4.3 (thanks to Matthew Callaghan for his bug report).

11. Eliminated the possible endless loop caused by some option database
    settings in the "seecell" subcommand (thanks to Erik Allaert and
    Mauro Comin for reporting this bug).

12. Added a detailed performance-related hint to the description of the
    "-listvariable" configuration option.

13. Numerous further improvements and minor bug fixes.

What was new in Tablelist 4.5?
------------------------------

1.  Static-width columns are now displayed much faster than in earlier
    Tablelist releases.

2.  Quite significantly reduced the performance penalty imposed by
    various column, row, and cell configuration options when sorting,
    redisplaying, moving, or deleting tablelist items.

3.  Embedded images are now handled much more efficiently and are
    displayed much faster than in earlier Tablelist versions.

4.  New column configuration option "-showlinenumbers" (thanks to Rolf
    Schroedter and Sean Xu for their proposals and to Kathrin Klaes for
    testing the implementation).

5.  Support for tile-based multi-entry widgets (introduced in Mentry
    3.0) used as edit windows.

6.  Significantly improved the handling of the <<ThemeChanged>> virtual
    event.

7.  Defined more reasonable windowing system- and theme-specific default
    values for the "-arrowdisabledcolor" option.

8.  Improved and simplified the package loading mechanism (thanks to
    Andreas Kupries for his valuable contribution).

9.  Eliminated the "togglevisibility" subcommand, which was deprecated
    in the previous Tablelist version in favor of "togglecolumnhide".

10. Fixed a bug in the implementation of the "deletecolumns" subcommand,
    introduced in the previous Tablelist release (thanks to Kai Morich,
    Kurt Kurczyk, and Dave Leslie for their bug reports).

11. Fixed two binding-related bugs (thanks to Mark Garvey and Kurt
    Kurczyk for their bug reports).

12. Fixed a bug related to the handling of the "tileqt" theme (thanks to
    Andres Garcia for his bug report).

13. Fixed a small but annoying bug related to the "-maxwidth" column
    configuration option, introduced in the previous Tablelist version.

14. Numerous further improvements and minor bug fixes (thanks to
    Patrick Fradin and Georgios Petasis for their valuable feedback).

What was new in Tablelist 4.4?
------------------------------

1.  New row configuration option "-hide" (thanks to Jeff Godfrey,
    Patrick Fradin. Hemang Lavana, and Martyn Smith for their
    proposals, and especially to Harold Campbell for providing the
    initial implementation and testing the final one.)  For performance
    reasons this option is implemented by using elided text in the
    underlying text widget, and therefore it is not supported for Tk
    versions earlier than 8.3.

2.  New subcommand "togglerowhide" for hiding/unhiding several rows at
    a time (not supported for Tk versions earlier than 8.3).

3.  Renamed the "togglevisibility" subcommand to "togglecolumnhide".
    The old name is still supported, but will be eliminated in the next
    Tablelist release.

4.  New command "tablelist::setThemeDefaults", which can be used to
    make sure that classical Tk widgets, e.g., text, will have a theme-
    specific appearance, just like the tile widgets.  The tile-based
    demo scripts now make use of this command.

5.  When using the "tileqt" theme, the version number of TileQt must be
    0.3 or higher (thanks to Georgios Petasis for providing the new
    "tileqt" features used in this Tablelist release).

6.  For Tk 8.3 or later, hidden columns are now handled by using elided
    text, which results in very significant performance improvements
    (thanks to Harold Campbell for his valuable contribution).

7.  Improved the handling of the "-listvariable" option in connection
    with snit widgetadaptors (thanks to Rolf Ade for his bug-fix).

8.  Corrected a typo in the implementation of the "move" subcommand,
    introduced in the previous release (thanks to Jerome Siot for his
    bug report).

9.  Improved the handling of the virtual event <<ThemeChanged>> (thanks
    to Wofgang Grosser for his bug report).

10. Fixed a long-standing bug related to hidden columns (thanks to Dave
    Leslie for his bug report).

11. Worked around a peculiarity of the "place" command on Windows,
    which caused refresh problems in column labels with images (thanks
    to Sebastien Barre for his bug report).

12. Numerous further improvements and minor bug fixes.

What was new in Tablelist 4.3?
------------------------------

1. Support for multi-line cells:  Newline characters now force line
   breaks when displaying the items (thanks to Sebastien Barre,
   Tillmann Basien, Cameron Laird, Kai Morich, and Vaclav Snajdr for
   their proposals).  In addition, interactive cell editing can now
   take place with the aid of a text widget, too (this has caused a few
   minor changes in the default key bindings for the edit window).

2. Support for multi-column sorting with the aid of the new subcommands
   "sortbycolumnlist", "sortcolumnlist", and "sortorderlist", as well
   as of the new command "tablelist::addToSortColumns".  The latter is
   designed to be specified as the value of the new widget and column
   configuration option "-labelcommand2", whose value is invoked on 
   <Shift-Button-1> events.  Multi-column sorting is visualized by
   means of multiple sort arrows, which are displayed together with the
   corresponding sort ranks.  (Thanks to Harold Campbell for proposing
   most of these features, providing the initial implementation, and
   testing the final one.)

3. New configuration option "-setfocus", specifying whether mouse
   button 1 should set the focus to the tablelist's body (thanks to
   Tillmann Basien for discussions on this topic).

4. Replaced the contents of the directory "images" with a script file
   containing procedures that create the bitmap images from inline data
   (thanks to Mats Bengtsson, Patrick Fradin, and Kai Morich for their
   proposals).

5. Fixed a bug related to the use of a tile entry within a non-tile-
   based tablelist widget on Windows XP (thanks to Schelte Bron for his
   bug report).

6. The handling of <Command-Key> events during interactive cell editing
   is now explicitly restricted to Mac OS Classic and Mac OS X Aqua,
   because, strangely enough, on Windows these events are generated by
   simple keypresses if Num Lock is active.

7. Numerous further code improvements, minor bug-fixes, and support for
   several recent changes in tile.

8. Cleaned up the documentation, to make sure that the HTML files
   generated for the ActiveTcl distribution with the tool HTML Tidy
   will be syntactically identical to the original ones.

What was new in Tablelist 4.2?
------------------------------

1.  The resize area of the header labels now consists of a few pixels
    on both sides of the right edge (thanks to Bryan Oakley for
    suggesting this improvement).

2.  Made sure that the header labels have the right appearance in the
    "aqua" theme when using tile version 0.6.4 or later (thanks to
    Bryan Oakley for his bug report).

3.  Several further improvements related to Mac OS X Aqua (for example,
    support for the "Command" key during keyboard navigation between
    the editable cells).

4.  Fixed a very long-standing bug in the "containing" subcommand
    (thanks to Mats Bengtsson, Schelte Bron, and Mark Garvey for their
    bug reports).

5.  Fixed a bug related to the "xpnative" theme, introduced in the
    previous release (thanks to Mark Garvey, Jeff Godfrey, and Uwe
    Koloska for their bug reports).

6.  Fixed another very long-standing bug, related to insertion and
    deletion of columns having images in their labels (thanks to
    Sebastien Barre for his bug report).

7.  Fixed an old bug related to embedding images or windows into hidden
    cells (again, thanks to Sebastien Barre for reporting this bug).

8.  The demo scripts now work independently of their location (this
    small improvement reflects the fact that Tablelist is now included
    in tklib, where the examples are in a location different from
    "$tablelist::library/demos").

9.  Adapted two tile-based demo scripts to the recently released tile
    version 0.7.

10. Several further improvements in the code and documentation (thanks
    to Patrick Fradin for his valuable contribution).

What was new in Tablelist 4.1?
------------------------------

1.  Significantly extended the tile support in the Tablelist_tile
    package:  Header labels now look and behave like the column
    headings of treeview widgets, and over a dozen configuration
    options have theme-specific default values (thanks to Paul
    Obermeier for his excellent "poImgview" application, which helped
    me a lot during this work, as well as to Georgios Petasis for his
    Qt-related hints).

2.  Header labels containing the mouse cursor are now set into active
    state.  Their appearance is controlled in the Tablelist package by
    the new configuration options "-labelactivebackground" and
    "-labelactiveforeground", while the Tablelist_tile package uses
    theme-specific background and foreground colors for the active and
    pressed states of the labels.

3.  New configuration option "-arrowstyle", specifying the flat or
    sunken relief and the dimensions of the arrow indicating the
    sorting order.  This option has windowing system- and theme-
    specific default values.

4.  New configuration option "-protecttitlecolumns", used to protect
    the title column boundary from being crossed when moving a column
    interactively (thanks to Schelte Bron for his proposal).

5.  New configuration option "-spacing", specifying additional space to
    provide above and below each tablelist row (thanks to Sebastien
    Barre for his proposal).

6.  New column configuration option "-stretchable", complementing the
    global "-stretch" option (thanks to Sebastien Barre for his
    proposal).

7.  New row configuration option "-name", whose value can also be used
    as a row index and as the first component of a cell index (thanks
    to John Kozura for his proposal).

8.  New cell configuration option "-windowdestroy", specifying a script
    to be invoked when a window embedded into the cell is destroyed
    (thanks to Sebastien Barre for his proposal).

9.  New "imagelabelpath" subcommand (thanks to Schelte Bron for his
    proposal).

10. Keyboard navigation during interactive cell editing now works on
    Mac OS X Aqua, too.

11. Restored the support for Tcl/Tk versions earlier than 8.3, by
    cleaning up the handling of the "-titlecolumns" option (thanks to
    Andreas Flach and Brian O'Hagan for their bug reports).

12. Restored the support for Tcl/Tk versions earlier than 8.0.4, which
    has been broken since release 3.5, due to the use of the
    <MouseWheel> event, introduced in Tk 8.0.4 (thanks to Brian O'Hagan
    for his valuable contribution).

13. Worked around a peculiarity of the text widget's "dump -window"
    command (thanks to Greg Reynolds for his bug-fix).

14. Fixed a binding-related bug in "extended" selection mode (thanks to
    David Mattinson for his bug-fix).

15. Numerous further improvements and minor bug fixes (thanks to
    Schelte Bron, Patrick Fradin, Silas Justiniano, and Uwe Koloska for
    their bug reports and valuable contributions).

What was new in Tablelist 4.0?
------------------------------

1.  Support for the tile entry, combobox, and checkbutton widgets for
    interactive cell editing (thanks to Miguel Bagnon, Andy Black,
    Adrian Chan, and Mark Garvey for their proposals and to Mats
    Bengtsson and Kevin Walzer for their support on the Macintosh).
    See the new reference page "tablelistTile.html" for details.

2.  Support for tile-compatibility:  By just specifying "package
    require Tablelist_tile" instead of "package require Tablelist", the
    tablelist widgets will have a modern theme-specific appearance
    (again, thanks to the above-mentioned Tablelist users for their
    suggestions and assistance).  See the "How to use it?" and "More on
    Tablelist_tile" sections of the tutorial "tablelist.html" for
    details.

3.  New demo script "tileWidgets.tcl", illustrating the use of tile
    widgets for interactive cell editing and of the Tablelist_tile
    package.  All the other demo scripts are now provided in both a
    traditional and a tile-based version.  See the "Tile-based demo
    scripts" section of the tutorial "tablelist.html" for an example
    and some screenshots.

4.  The Tk checkbutton used for interactive cell editing is now a
    platform-specific checkbutton widget on Windows and the Macintosh
    (thanks to Mats Bengtsson for his help related to the Macintosh
    platform).

5.  The "-editwindow" option is now available at cell level, too
    (thanks to Kenneth Green for his proposal).

6.  New subcommand "togglevisibility" for hiding/unhiding several
    columns at a time (thanks to Stefan Finzel and Kai Morich for their
    proposals).

7.  Support for the new virtual event <<TablelistSelectionLost>>,
    generated when a tablelist widget having "-exportselection 1" loses
    the selection (thanks to Aldo Buratti for his proposal).

8.  After sorting the items, the "most important" row is automatically
    brought into view (thanks to Kai Morich for his valuable input).

9.  Worked around a peculiarity of Tk for Windows, related to mouse
    events (thanks to Tore Morkemo and Mike Collins for their bug
    reports).

10. Worked around a problem related to the visibility of the up/down-
    arrow on Mac OS X Aqua (thanks to Kevin Walzer for his bug report).

11. Fixed a bug in the "seecell" subcommand, introduced in Tablelist
    version 3.7 (thanks to Stefan Finzel for his bug report).

12. Fixed a bug in the "rowconfigure" subcommand, introduced in the
    previous Tablelist release (thanks to Tore Morkemo for his bug
    report).

13. Eliminated the memory leak caused by incomplete cleanup on deleting
    rows with embedded windows (thanks to David Cockerell for his bug
    report).

14. Fixed a small timing-related bug in the "editcell" subcommand
    (thanks to Kenneth Green for his bug report).

15. Numerous further improvements and minor bug fixes (thanks to Greg
    Reynolds for his valuable input).

What was new in Tablelist 3.8?
------------------------------

1. New configuration option "-forceeditendcommand", controlling the
   invocation of the script corresponding to the value of the
   "-editendcommand" option (thanks to Nestor Patino for his proposal).
 
2. New subcommands "getcells" and "windowpath" (thanks to Jeff Godfrey
   and Mike Collins for their proposals).

3. Support for the new virtual event <<TablelistCellRestored>>,
   generated by the "cancelediting" subcommand.

4. Significantly improved the performance of the "delete",
   "deletecolumns", and "movecolumn" subcommands for tablelist widgets
   having color or font options set at column, row, or cell level
   (thanks to Michael Bahr for his valuable feedback).

5. Improved the autoscrolling with the left mouse button in both the
   body and the header of a tablelist widget having title columns.

6. Fixed a bug related to the "-titlecolumns" option, introduced in the
   previous Tablelist release (thanks to Alexander Schoepe for his bug
   report).

7. Fixed a typo in the implementation of the "seecell" subcommand,
   introduced in the previous Tablelist release (thanks to Patrick
   Fradin for his bug report).

8. Improved the demo script "embeddedWindows.tcl" (thanks to Patrick
   Fradin for his valuable input).

9. Several further improvements and minor bug fixes.

What was new in Tablelist 3.7?
------------------------------

1. New configuration option "-titlecolumns", specifying the number of
   the non-scrollable columns at the left edge of the window (thanks to
   Goran Ivankovic, Paul Kienzle, Hemang Lavana, and Takeshi Sakamoto
   for their proposals).  For technical reasons (the use of the
   "-elide" option for a text widget tag), this option is not supported
   for Tk versions earlier than 8.3.

2. Extended the "separatorpath" and "separators" subcommands, to
   support the new special separator, which is displayed to mark the
   end of the title columns, independently of the value of the
   "-showseparators" option.

3. The "-stripebackground" and "-stripeforeground" options now have a
   higher priority than the "-background" and "-foreground" column
   configuration options, respectively (see the demo script
   "styles.tcl", which has been extended to illustrate this change).

4. Improved the handling of embedded images with transparent
   background, complementing the changes made in the previous Tablelist
   release (thanks to Kai Morich for his valuable contribution).

5. Improved the implementation of the "seecell" subcommand for centered
   and right-aligned columns.

6. Fixed two bugs related to the "rowconfigure" subcommand, introduced
   in Tablelist version 3.5 (thanks to Ted Branscomb and Roger Niva for
   their bug reports).

7. Fixed an old bug related to the "movecolumn" subcommand.

8. Several further improvements and minor bug fixes.

What was new in Tablelist 3.6?
------------------------------

1.  Support for embedded windows, with the aid of the new cell
    configuration option "-window" (thanks to Wolf Grossi, Glenn
    Herteg, Takeshi Sakamoto, and Keesang Song for proposing this
    option).

2.  New demo script "embeddedWindows.tcl" illustrating the use of
    embedded windows in tablelist widgets; this is discussed in a new
    section of the tutorial "tablelist.html".

3.  Significantly improved and optimized the handling of embedded
    images.

4.  Simplified the support for user-defined binding scripts with the
    aid of the new commands "tablelist::getTablelistPath" and
    "tablelist::convEventFields", as well as of a new binding tag whose
    name is returned by the new "bodytag" subcommand (which is now used
    in the demo script "browse.tcl").

5.  Support for the new virtual events <<TablelistRowMoved>>,
    <<TablelistColumnMoved>>, <<TablelistColumnSorted>> and
    <<TablelistCellUpdated>> (thanks to John Vidolich for his
    proposal).  In addition, the new virtual event <<TablelistSelect>>
    can now be used instead of <<ListboxSelect>> (which is supported
    for compatibility reasons).

6.  New subcommand "itemlistvar", for accessing the tablelist widget's
    internal list (thanks to Patrick Fradin for his valuable input).

7.  Fixed a bug related to the "-listvariable" option, introduced in
    the previous Tablelist release (thanks to Torsten Reincke for his
    bug report).

8.  Fixed two bugs related to the "cellselection" subcommand (thanks to
    John Vidolich for his bug report).

9.  Fixed a few typos and minor bugs in the default binding scripts
    (thanks to Patrick Fradin, Tore Morkemo, and Torsten Reincke for
    their bug reports).

10. Numerous further improvements and minor bug fixes.

What was new in Tablelist 3.5?
------------------------------

1.  New configuration option "-selecttype" with the values "row" and
    "cell", and new binding scripts supporting these two selection
    types (thanks to Kevin Partin for his proposal and to Dietmar
    Mueller for his valuable contribution).

2.  New subcommands "activatecell", "cellselection", and
    "curcellselection", used in the binding scripts mentioned above.

3.  The words "active" and "anchor" are now recognized as valid column
    and cell indices, too.

4.  New configuration options "-movablerows" and "-movecursor", and new
    mouse bindings for moving a row interactively (thanks to Dan Rogahn
    for his valuable contribution).

5.  The key sequences used for navigation between the editable cells
    now also move the active item or element and change the
    (cell)selection and the (cell)selection anchor in the body of the
    tablelist widget.

6.  Improved the handling and appearance of the checkbutton widget when
    used as edit window (thanks to Kevin Partin for reporting a problem
    experienced when the tablelist is embedded into an Iwidgets
    dialogshell).

7.  The "-listvariable" option now supports variable names returned by
    the "itcl::scope" command, too (thanks to Nicolae Mihalache for his
    bug report).

8.  Fixed a very long-standing bug related to horizontal scrolling when
    using a non-default font (thanks to Brand Hilton for his bug report
    and fix).

9.  Fixed another very long-standing bug, related to list variables
    (thanks to Dr. Detlef Groth and John R. Smith for their bug
    reports).

10. Numerous further improvements and minor bug fixes (thanks to
    Patrick Fradin for his valuable input).

What was new in Tablelist 3.4?
------------------------------

1.  New column configuration option "-editwindow", specifying the
    widget type used for interactive cell editing in the respective
    column (thanks to Damon Courtney, Patrick Fradin, and Keesang Song
    for their proposals and to Mats Bengtsson and Benny Riefenstein for
    their help related to the Macintosh platform).  The edit window may
    be a Tk core entry, spinbox, or checkbutton, or one of the 16
    supported widgets from the packages BWidget, Iwidgets, combobox (by
    Bryan Oakley), and Mentry.

2.  New subcommand "editwinpath".

3.  Three new demo scripts illustrating the use of the "-editwindow"
    option; these are discussed in a new section of the tutorial
    "tablelist.html".

4.  New column configuration option "-maxwidth" (thanks to Tore Morkemo
    for his proposal).

5.  The <Shift-Button-3> event in a column label now restores the
    column's last static width (thanks to Dietmar Mueller for his
    valuable input).

6.  Changing a tablelist's font now updates the column widths
    accordingly.

7.  Improved the handling of the "-setgrid" option.

8.  Improved the error handling related to the option database in the
    general mega-widget utility module "mwutil.tcl".

9.  Fixed a minor bug in the "containingcolumn" subcommand (thanks to
    David Mattinson for his bug report).

10. Restored the support for Tcl/Tk versions earlier than 8.0.4, which
    has been broken since release 3.0, due to the use of the
    <MouseWheel> event, introduced in Tk 8.0.4.

11. Further code improvements (thanks to Patrick Fradin for his
    valuable input).

12. Many improvements in the documentation, including a new Quick
    Reference section (thanks to Dietmar Mueller for his valuable
    contribution).

What was new in Tablelist 3.3?
------------------------------

1. New column configuration option "-text" (thanks to Paul Kienzle for
   his proposal).

2. New subcommands "containing", "containingcolumn", "containingcell",
   and "fillcolumn".

3. New subcommands "deletecolumns", "insertcolumns", and
   "insertcolumnlist" (thanks to Kevin Partin and Paul Kienzle for
   their proposals).

4. Renamed the subcommands "getcolumn" and "getkey" to "getcolumns" and
   "getkeys", respectively.  (This won't break any existing scripts,
   because the old command names are abbreviations of the new ones.)

5. Restored the support for Tcl/Tk versions earlier than 8.4, which was
   broken in Tablelist 3.1 and 3.2, due to the use of the improved
   syntax of the "place configure" command, introduced in Tk 8.4
   (thanks to David Mattinson, Kurt Braganza, and Alexander Baath for
   reporting this problem).

6. Fixed a bug in the "editcell" subcommand, introduced in Tablelist
   3.1 (thanks to Damon Courtney for his bug report).

7. Improved the demo script "config.tcl" (thanks to Mats Bengtsson for
   his input).

8. Restructured the code by moving several procedures from the
   distribution file "tablelistWidget.tcl" into smaller, more
   manageable modules.

9. Numerous further improvements and minor bug fixes.

What was new in Tablelist 3.2?
------------------------------

1. The key associated with a tablelist item can now be used as a row
   index and as the first component of a cell index of the form
   "row,col".

2. The "delete", "get", "getcolumn", "getkey", "selection clear", and
   "selection set" subcommands now also accept a list of indices as
   single argument (thanks to Damon Courtney and Erik Leunissen for
   their proposals).

3. Made the interactive "movecolumn" operation more intuitive and
   compatible with the behavior exhibited by similar actions in popular
   applications on various platforms (thanks to Paul Kienzle for his
   suggestion).  For example, the target position of the column being
   moved is now indicated by a temporary gap displayed in the
   tablelist's header.

4. New configuration option "-targetcolor", used to set the color of
   the gap mentioned above.

5. Fixed a bug related to the <MouseWheel> event, caused by a missing
   close-bracket in the last release (thanks to Patrick Fradin for his
   bug report).

6. Fixed a bug that raised an error in the "movecolumn" command for an
   empty tablelist widget (thanks to Paul Kienzle for his bug report).

7. The workaround in the "xview" and "yview" subcommands for a Tk bug
   under Mac OS X Aqua is now only activated for that windowing system,
   since (as reported by Patrick Fradin) it caused problems on some
   other systems.

8. Further minor code improvements.

What was new in Tablelist 3.1?
------------------------------

1.  New configuration options "-movablecolumns" and
    "-movecolumncursor".

2.  New column configuration option "-name", whose value can also be
    used as a column index and as the second component of a cell index
    of the form "row,col".

3.  New subcommands "move", "movecolumn", "getcolumn", "getkey", and
    "finishediting" (thanks to Damon Courtney, Daniel Fehrenbach, Jeff
    Godfrey, and Kevin Partin for their proposals).

4.  Extended the scope of the "cancelediting" subcommand.

5.  New mouse bindings for moving a column interactively.

6.  The autoscrolling, as described in the "DEFAULT BINDINGS" section
    of the "listbox" manual entry, is now implemented for the header of
    a tablelist widget, too.

7.  The interactive cell editing is now finished by any mouse click in
    the tablelist's body, outside the cell just being edited (thanks to
    Patrick Fradin and Jeff Godfrey for this suggestion).

8.  The value returned by the "selection includes" command no longer
    depends on the tablelist's state.

9.  Worked around a bug in Tk 8.4.0 and 8.4.1 related to the "selection
    handle" command, which caused crashes under KDE 3.0 (thanks to
    Andres Garcia for reporting this and to Joe English for suggesting
    the workaround and fixing the bug in Tk 8.4.2).

10. Improved the support of Mac OS X Aqua and Mac OS Classic (thanks to
    Mats Bengtsson, Raymond Calande, Techin Alex Kang, Bernhard
    Spinnler, and especially to Benny Riefenstein for their valuable
    contributions).

11. Fixed a bug related to the invocation of the "cellconfigure"
    subcommand from within a pre-edit callback (thanks to Dr. Johannes-
    Heinrich Vogeler for his bug report).

12. Several performance improvements (thanks to Patrick Fradin for his
    valuable suggestions).

13. Improved the platform-specific stuff in the demo scripts
    "config.tcl" and "browse.tcl".

14. Numerous further improvements in the code and documentation.

What was new in Tablelist 3.0?
------------------------------

The main new feature provided by this release is the support for
interactive cell editing (thanks to Juri Shimon, Dr. Johannes-Heinrich
Vogeler, and Jeff Godfrey for their proposal).  The first three items
below are related to this subject:

1. New configuration options "-editstartcommand" and "-editendcommand".

2. New column and cell configuration option "-editable".

3. New subcommands "editcell", "entrypath", "cancelediting", and
   "rejectinput".

Further changes:

4. New subcommands "seecolumn" and "seecell".

5. Tabulator and newline characters are now retained in the internal
   list, displayed as "\t" and "\n", and supported by interactive cell
   editing (thanks to Jacek Jenrysik for his query concerning multi-
   line items).

6. The redisplay and sorting of tablelist items have become
   dramatically faster (thanks to Matt Becker for his input that
   determined me to optimize these operations, and also for his
   testing).

7. Further performance improvements (thanks to Patrick Fradin for his
   valuable contribution).

8. The option values displayed by the demo script "config.tcl" can now
   be edited interactively.

9. Minor improvements in the code and documentation.

What was new in Tablelist 2.8?
------------------------------

1. The trailing or leading ellipsis ("...") used when displaying the
   elements that don't fit into their cells can now be replaced with an
   arbitrary string specified with the aid of the new "-snipstring"
   configuration option (thanks to Tore Morkemo for his proposal).

2. New value "none" for the "-activestyle" configuration option.

3. When exporting the selection, the elements of the hidden columns are
   now skipped and the contents of the visible cells are transformed
   according to the value of the "-formatcommand" option for the
   corresponding columns.

4. Improved and simplified the focus control (thanks to Juri Shimon and
   Gopal Reddy for their bug reports).

5. Further minor code improvements.

What was new in Tablelist 2.7?
------------------------------

1. Increased the speed of the "insert" and "insertlist" subcommands as
   well as that of item insertions with the aid of the "-listvariable"
   option by a factor of about 1.3.  The "insert" subcommand is now
   about 2.3 times faster than in version 2.4.  Compared to version
   2.4, item insertion with the aid of the "-listvariable" option has
   become more than 10 times faster.

2. The number of pixels by which a column is stretched is now
   proportional to its width in pixels.  Based on this change,
   significantly improved the stretching behavior after an interactive
   column resize operation (thanks to Mats Bengtsson for his valuable
   suggestions).

3. Fixed a bug in the "-(label)font" and "-labelborderwidth"
   configuration options, introduced in version 2.5 (thanks to Bastien
   Chevreux for his bug report).

4. Fixed a bug in the "columncget", "rowcget", and "cellcget"
   subcommands, introduced in version 2.3 (again, thanks to Bastien
   Chevreux for reporting this bug).

5. Fixed a bug in the binding scripts for the binding tag
   "TablelistBody" (thanks to Miguel Bagnon for his bug report).

6. Applied a patch proposed by Jeff Adamczak that works around a bug in
   the "lsort" command, present in Tcl versions 8.0 - 8.3.2.

7. Applied a patch proposed (in a slightly different form) by Mats
   Bengtsson that works around a bug in the "info script" command on
   the Macintosh.

8. Further minor code improvements.

What was new in Tablelist 2.6?
------------------------------

The only change in this version is a bug-fix eliminating a rather nasty
bug in the "insert" and "insertlist" subcommands, introduced in the
previous release.  Thanks to Mats Bengtsson for his bug report and to
Jeffrey Hobbs for suggesting me to bump the version number to 2.6.

What was new in Tablelist 2.5?
------------------------------

1. Increased the speed of the "insert" subcommand by a factor of about
   1.8 and that of item insertions with the aid of the "-listvariable"
   option by a factor of about 8.  (These figures are based on speed
   measurements made with two tablelist widgets: one having 1000 rows
   and 10 columns and another one with 5000 rows and 20 columns.)

2. The "delete", "sort", and "sortbycolumn" subcommands, as well as row
   and cell updates with the aid of the "rowconfigure" and
   "cellconfigure" operations have also become significantly faster.

3. New "insertlist" subcommand.

4. New "-stripeheight" configuration option (thanks to Gregory Samoluk
   for his proposal).

5. If no columns are to be stretched then the blank space following the
   header labels is now filled with a dummy, insensitive label having
   the same background, borderwidth, and relief as the "normal" header
   labels.

6. Fixed a bug concerning the placement of the arrow indicating the
   sorting order (thanks to Robert Minichino for his bug report).

7. Improved the handling of header labels with embedded images, to
   eliminate some peculiarities experienced on Windows.

8. Several further improvements and minor bug fixes.

What was new in Tablelist 2.4?
------------------------------

1. New column configuration option "-formatcommand" (thanks to Jeff
   Godfrey for his proposal).  This option is now used in the demo
   script "browse.tcl".

2. New row configuration option "-selectable" (thanks to Tore Morkemo
   for this proposal).

3. Significantly improved the performance of the row and cell updates,
   as well as of the "delete" subcommand (thanks to Emanuele Lupi for
   her input that determined me to optimize these operations).

4. The widget implementation is now fully compatible with the recent
   changes made in Tk 8.4a4 (thanks to Patrick Fradin for his input).

5. Pop-up menus as children of a tablelist widget cause no problem any
   longer (thanks to Andres Garcia and Bastien Chevreux for reporting
   this bug, introduced in the previous release).

6. Fixed a bug caused by the delayed redisplay after changing the
   number of columns (thanks to Tore Morkemo for his bug report).

7. Minor improvements in the code and documentation.

What was new in Tablelist 2.3?
------------------------------

1. New configuration option "-activestyle", enabling to surround the
   active item with a frame instead of underlining it.

2. The columns can now be separated with borders, by making use of the
   new configuration option "-showseparators".

3. A nice distinguishing effect for the rows can now be obtained with
   the aid of the new configuration options "-stripebackground" and
   "-stripeforeground".

4. New tablelist widget subcommands "separatorpath" and "separators".

5. Fixed a bug related to the column index if the header labels are
   hidden (thanks to Emanuele Lupi for her bug report).

6. New demo script "styles.tcl", showing several ways to improve the
   appearance of a tablelist widget.

7. The demo scripts "config.tcl" and "browse.tcl" now make use of the
   new "-stripebackground" option.

8. Numerous further improvements and minor bug fixes (thanks to Patrick
   Fradin for his valuable input).

What was new in Tablelist 2.2?
------------------------------

1. The "-font" configuration option can now be specified at column,
   row, and cell level, too (this was proposed and partly implemented
   by Patrick Fradin).  The data will be aligned properly, no matter if
   the fonts are of different sizes.

2. Significantly improved the performance of the Tcl command associated
   with a tablelist widget, especially that of the "delete", "sort",
   and "sortbycolumn" subcommands for a large number (i.e., several
   thousands) of items.

3. Corrected the creation of the arrow indicating the sorting order, to
   make sure that it works under all supported Tcl/Tk versions (thanks
   to Juri Shimon and Andres Garcia for their bug reports).

4. Several improvements in the demo scripts "config.tcl" and
   "browse.tcl".  Among others, the GUIs generated by these scripts now
   have a better platform-specific look & feel (many thanks to Mats
   Bengtsson for his valuable suggestions concerning the Macintosh
   platform).

5. Further minor improvements in the code.

What was new in Tablelist 2.1?
------------------------------

1. The up- or down-arrow indicating the sorting order now has a 3-D
   border, giving the arrow a sunken relief.

2. Due to the new 3-D look of the arrow, the default values of the
   "-arrowcolor" and "-arrowdisabledcolor" configuration options have
   been changed to an empty string, indicating that the arrow will
   inherit the background color of the label in which it is placed.

3. Several improvements in the demo script "browse.tcl".

4. Minor improvements in the code and documentation.

5. The distribution file "tablelist2_1.zip" for Windows now includes
   the "tablelist2.1" directory, hence it is no longer necessary to
   create this folder before unpacking the distribution file (thanks to
   Kevin Partin for this suggestion).

What was new in Tablelist 2.0?
------------------------------

1.  New cell configuration option "-image", used to set and retrieve
    the image to be displayed (by itself or together with a text) in a
    cell of a tablelist widget.

2.  New column configuration option "-labelimage" specifying the image
    to be displayed (by itself or combined with a text) in a column
    label.

3.  The alignment of a header label can now be defined to be different
    from that of the elements contained in its column, by using the new
    column configuration option "-labelalign".

4.  Renamed the column configuration option "-justify" to "-align",
    because (at least in the case of the header labels) this actually
    specifies not only the justification, but also the anchor point.
    Hopefully, this POTENTIAL INCOMPATIBILITY will not break too many
    existing applications, because the column alignments are usually
    specified within the "-columns" global option.

5.  Fixed a bug that raised an error when some configuration options
    were specified at widget creation time before the "-columns" option
    (thanks to Bastien Chevreux for his bug report).

6.  Reverted the implementation of the focus control to that contained
    in the pre-1.6 Tablelist releases, because its simplified version
    from the last release failed to work as expected if a tablelist was
    the only widget taking the focus during keyboard traversal (thanks
    to Juri Shimon for his bug report).

7.  Fixed a bug that caused an erronous return value of the "labels"
    subcommand if the arrow indicating the sorting order was displayed.

8.  Several performance improvements, kindly contributed by Patrick
    Fradin.

9.  To improve the performance even further, the invocations of "info
    exists" for array elements are no longer replaced with a call to a
    helper procedure (introduced in Tablelist 1.2), because the Tcl bug
    that made this necessary for Tcl versions 8.2, 8.3.0 - 8.3.2, and
    8.4a1 was fixed in Tcl 8.3.3 and 8.4a2.  If for some reason you
    cannot upgrade your Tcl/Tk version, then you should patch the file
    "tablelistWidget.tcl" with the aid of the script "repair.tcl", as
    described in the files "README.txt" and "tablelist.html".

10. The demo script "browse.tcl" now inserts an image into the first
    cell of each row of the tablelist widget.

11. Numerous further improvements and minor bug fixes.

What was new in Tablelist 1.6?
------------------------------

1. The value of the "-stretch" configuration option is now ignored if
   the width of the tablelist widget was specified as zero or less.
   This change was necessary in order to improve the behavior of
   dynamic-width tablelist widgets with the "-setgrid" option set to
   true.

2. By pressing mouse button 1 over a header label, the label's relief
   is now only changed to "sunken" if the value of the global or
   column-specific "-labelcommand" option is nonempty.

3. Several improvements concerning hidden columns (thanks to Juri
   Shimon for his bug report).

4. Made the focus control more straight-forward.

5. Extended the "How to use it?" section of the tutorial
   "tablelist.html".

What was new in Tablelist 1.5?
------------------------------

This version contains mainly bug fixes and small improvements.  Many
thanks to Andres Garcia, Bastien Chevreux, and Patrick Fradin for their
valuable contributions.

1. Fixed a bug concerning the "-label*" configuration options.

2. Fixed the erronous invocation of "getSubCmd" in the selection
   handler "fetchSelection" (this bug was introduced in version 1.1).

3. Elements that don't fit into their cells are now displayed with a
   trailing or leading ellipsis ("..."), depending on the column
   alignment.

4. Several further improvements and minor bug fixes.

What was new in Tablelist 1.4?
------------------------------

1. New "-stretch" configuration option specifying the columns that are
   to be stretched in order to eliminate the blank space that might
   appear at the right of the table.

2. Improved the error handling in the "attrib", "configure",
   "columnconfigure", "rowconfigure", and "cellconfigure" subcommands.

3. Improved the demo scripts "browse.tcl" and "config.tcl".

What was new in Tablelist 1.3?
------------------------------

1. The "sortbycolumn" subcommand now per default places an up- or
   down-arrow indicating the sorting order into the respective column's
   label.  This can be enabled or disabled with the new "-showarrow"
   configuration option, at both widget and column level.

2. New configuration options "-arrowcolor", "-arrowdisabledcolor", and
   "-incrarrowtype" to control the appearance of the arrow mentioned
   above.

3. New "resetsortinfo" subcommand, used to reset the information about
   the sorting of the items.

4. Improved the demo script "browse.tcl".

5. Further improvements in the code and documentation.

What was new in Tablelist 1.2?
------------------------------

1. Whereever possible, eliminated the invocations of "info exists" for
   array elements.  This works around a severe bug in Tcl versions 8.2
   and 8.3 (fixed in 8.4a2), which causes excessive memory use when
   calling "info exists" on a non-existent array element.  Some serious
   memory leaks in earlier Tablelist versions when run under Tcl/Tk 8.2
   or 8.3 (reported by Henning Hanusa and Christian Burrini) could be
   tracked down to this very annoying Tcl bug (which I was not aware of
   until recently).

2. The help variables used in the initialization of the "tablelist"
   namespace are now declared with the "variable" keyword, in order to
   avoid any conflicts with global variables.

3. Improved the parsing of configuration and command options.

What was new in Tablelist 1.1?
------------------------------

This version contains mainly bug fixes and small improvements.  Many
thanks to Patrick Fradin, Bastien Chevreux, and Mats Bengtsson for
their valuable contributions.

1. Fixed some bugs in the implementation of the "-listvariable" option.
   Also, the value of this option can now be an array element, not only
   a scalar variable.

2. Fixed a bug in the implementation of the "get" subcommand.

3. New "sortcolumn" and "sortorder" subcommands to query the arguments
   of the last sorting.

4. Improved the look & feel of tablelist widgets on the Macintosh.

5. Worked around a bug in Tk 8.3.0 (fixed in 8.3.1) concerning listbox
   widgets with configured "-cursor" option.

6. Several further improvements and minor bug fixes.

What was new in Tablelist 1.0?
------------------------------

1.  New "-resizable" option for the "columnconfigure" subcommand.

2.  New "labels" subcommand, returning the list of the header labels.

3.  The "-disabledforeground" and "-state" configuration options no
    longer require Tk version 8.3 or higher.

4.  All "-label*" column configuration options can now have an empty
    string as value, meaning that the corresponding global option will
    be used instead of the column-specific one.

5.  Improved the output of the "columnconfigure" subcommand.

6.  The help variables used in the coordinate transformations within
    the scripts defined for the "TablelistBody" binding tag have been
    moved into the "tablelist" namespace, in order to avoid any
    conflicts with global variables.

7.  Improved cross-platform support with the aid of the new <<Button3>>
    virtual event.

8.  Fixed a bug in the "compareAsSet" procedure of the demo script
    "config.tcl".

9.  New demo script "browse.tcl", containing a simple widget browser
    based on a tablelist.

10. Both demo scripts now use a namespace for their procedures, to
    avoid any conflicts when evaluating them with the "source" command.

11. The tutorial "tablelist.html" is now completed and includes a
    detailed discussion of both demo scripts mentioned above.

12. Numerous further improvements in the code and documentation.

What was new in Tablelist 0.9?
------------------------------

1. The documentation now includes the tutorial "tablelist.html" (part
   of which is still work in progress), as well as reference pages for
   the two exported commands "tablelist::tablelist" and
   "tablelist::sortByColumn".

2. The "-listvariable" configuration option is now fully implemented.

3. A column of a tablelist widget can now be made invisible by using
   the new "-hide" option of the "columnconfigure" subcommand.

4. The contents of a row can now be updated with the new "-text" option
   of the "rowconfigure" subcommand.

5. For Tk versions 8.3 or higher the "tablelist::tablelist" command now
   supports the "-disabledforeground", "-labeldisabledforeground", and
   "-state" configuration options.

6. Replaced "[focus]" with "[focus -displayof $win]", so that the code
   will work properly in applications using multiple displays.
   Similarly, the "font measure" command is now invoked with the
   "-displayof $win" option.  This also works around a peculiarity of
   the "font measure" command.

7. Renamed "tablelistBindingTag" to "Tablelist".

8. Fixed a bug in the private procedure "colIndex", for arguments of
   the form "@x,y".  This procedure is invoked (directly or indirectly)
   in the implementation of all commands that take a column or cell
   index or an x coordinate as argument.

9. Numerous further improvements and minor bug fixes.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/COPYRIGHT.txt.

1
2
3
4
5
6
7
8
9
10
Multi-column listbox and tree widget package Tablelist, version 5.16
Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)

This library is free software; you can use, modify, and redistribute it
for any purpose, provided that existing copyright notices are retained
in all copies and that this notice is included verbatim in any
distributions.

This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
<
<
<
<
<
<
<
<
<
<




















Deleted libs/tablelist5.16/README.txt.

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
       The Multi-Column Listbox and Tree Widget Package Tablelist

                                   by

                             Csaba Nemethi

                       csaba.nemethi@t-online.de 


What is Tablelist?
------------------

Tablelist is a library package for Tcl/Tk versions 8.0 or higher,
written in pure Tcl/Tk code.  It contains:

  - the implementation of the "tablelist" mega-widget, including a
    general utility module for mega-widgets;
  - a demo script containing a useful procedure that displays the
    configuration options of an arbitrary widget in a tablelist and
    enables you to edit their values interactively;
  - a demo script implementing a widget browser based on a tablelist
    used as multi-column listbox;
  - a demo script implementing a widget browser based on a tablelist
    used as multi-column tree widget;
  - a demo script implementing a directory viewer based on a tablelist
    used as multi-column tree widget;
  - a demo script showing several ways to improve the appearance of a
    tablelist widget;
  - four further demo scripts, illustrating the interactive cell
    editing with the aid of various widgets from the Tk core and from
    the packages tile, BWidget, Iwidgets, combobox (by Bryan Oakley),
    and Mentry;
  - one further demo script, with a tablelist widget containing
    embedded windows;
  - tile-based counterparts of the above-mentioned demo scripts;
  - a tutorial in HTML format;
  - reference pages in HTML format.

A tablelist is a multi-column listbox and tree widget.  The width of
each column can be dynamic (i.e., just large enough to hold all its
elements, including the header) or static (specified in characters or
pixels).  The columns are, per default, resizable.  The alignment of
each column can be specified as "left", "right", or "center".

The columns, rows, and cells can be configured individually.  Several
of the global and column-specific options refer to the headers,
implemented as label widgets.  For instance, the "-labelcommand" option
specifies a Tcl command to be invoked when mouse button 1 is released
over a label.  The most common value of this option sorts the items
based on the respective column.

The Tablelist package provides a great variety of tree styles
controlling the look & feel of the column that displays the tree
hierarchy with the aid of indentations and expand/collapse controls.

Interactive editing of the elements of a tablelist widget can be
enabled for individual cells and for entire columns.  A great variety
of widgets from the Tk core and from the packages tile, BWidget,
Iwidgets, combobox, ctext, and Mentry (or Mentry_tile) is supported for
being used as embedded edit window.  In addition, a rich set of keyboard
bindings is provided for a comfortable navigation between the editable
cells.

The Tcl command corresponding to a tablelist widget is very similar to
the one associated with a normal listbox.  There are column-, row-, and
cell-specific counterparts of the "configure" and "cget" subcommands
("columnconfigure", "rowconfigure", "cellconfigure", ...).  They can be
used, among others, to insert images into the cells and the header
labels, or to insert embedded windows into the cells.  The "index",
"nearest", and "see" command options refer to the rows, but similar
subcommands are provided for the columns and cells ("columnindex",
"cellindex", ...).  The items can be sorted with the "sort",
"sortbycolumn", and "sortbycolumnlist" command options.

The bindings defined for the body of a tablelist widget make it behave
just like a normal listbox.  This includes the support for the virtual
event <<ListboxSelect>> (which is equivalent to <<TablelistSelect>>).
In addition, version 2.3 or higher of the widget callback package Wcb
(written in pure Tcl/Tk code as well) can be used to define callbacks
for the "activate", "selection set", and "selection clear" commands,
and Wcb version 3.0 or higher also supports callbacks for the
"activatecell", "cellselection set", and "cellselection clear"
commands.  The download location of Wcb is

    http://www.nemethi.de

How to get it?
--------------

Tablelist is available for free download from the same URL as Wcb.  The
distribution file is "tablelist5.16.tar.gz" for UNIX and
"tablelist5_16.zip" for Windows.  These files contain the same
information, except for the additional carriage return character
preceding the linefeed at the end of each line in the text files for
Windows.

Tablelist is also included in tklib, which has the address

    http://core.tcl.tk/tklib

How to install it?
------------------

Install the package as a subdirectory of one of the directories given
by the "auto_path" variable.  For example, you can install it as a
directory at the same level as the Tcl and Tk script libraries.  The
locations of these library directories are given by the "tcl_library"
and "tk_library" variables, respectively.

To install Tablelist on UNIX, "cd" to the desired directory and unpack
the distribution file "tablelist5.16.tar.gz":

    gunzip -c tablelist5.16.tar.gz | tar -xf -

This command will create a directory named "tablelist5.16", with the
subdirectories "demos", "doc", and "scripts".

On Windows, use WinZip or some other program capable of unpacking the
distribution file "tablelist5_16.zip" into the directory
"tablelist5.16", with the subdirectories "demos", "doc", and "scripts".

The file "tablelistEdit.tcl" in the "scripts" directory is only needed
for applications making use of interactive cell editing.  Similarly, the
file "tablelistMove.tcl" in the same directory is only required for
scripts invoking the "move" or "movecolumn" tablelist command.  Finally,
the file "tablelistThemes.tcl" is only needed for applications using
the package Tablelist_tile (see next section).

Next, you should check the exact version number of your Tcl/Tk
distribution, given by the "tcl_patchLevel" and "tk_patchLevel"
variables.  If you are using Tcl/Tk version 8.2.X, 8.3.0 - 8.3.2, or
8.4a1, then you should proceed as described in the "How to install it?"
section of the file "tablelist.html", located in the "doc" directory.

How to use it?
--------------

The Tablelist distribution provides two packages, called Tablelist and
Tablelist_tile.  The main difference between the two is that
Tablelist_tile enables the tile-based, theme-specific appearance of
tablelist widgets; this package requires Tcl/Tk 8.4 or higher and tile
0.6 or higher.  It is not possible to use both packages in one and the
same application, because both are implemented in the same "tablelist"
namespace and provide identical commands.

To be able to use the commands and variables implemented in the package
Tablelist, your scripts must contain one of the lines

    package require tablelist ?version?
    package require Tablelist ?version?

Likewise, to be able to use the commands and variables implemented in
the package Tablelist_tile, your scripts must contain one of the lines

    package require tablelist_tile ?version?
    package require Tablelist_tile ?version?

Since the packages Tablelist and Tablelist_tile are implemented in the
"tablelist" namespace, you must either import the procedures you need,
or use qualified names like "tablelist::tablelist".

For a detailed description of the commands and variables provided by
Tablelist and of the examples contained in the "demos" directory, see
the tutorial "tablelist.html" and the reference pages, all located in
the "doc" directory.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































Deleted libs/tablelist5.16/demos/browse.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# the children of an arbitrary widget.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 5.16

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config.tcl]

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Path Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-labelcommand demo::labelCmd -yscrollcommand [list $vsb set] -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"
    button $b2 -text "Parent"
    button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	set choice [tk_messageBox -title "Error" -icon warning \
		    -message "Bad window path name \"$w\" -- replacing\
			      it with nearest existent ancestor" \
		    -type okcancel -default ok -parent [winfo toplevel $tbl]]
	if {[string compare $choice "ok"] == 0} {
	    while {![winfo exists $w]} {
		set last [string last "." $w]
		if {$last != 0} {
		    incr last -1
		}
		set w [string range $w 0 $last]
	    }
	} else {
	    return ""
	}
    }

    set top [winfo toplevel $tbl]
    wm title $top "Children of the [winfo class $w] Widget \"$w\""

    $tbl resetsortinfo
    $tbl delete 0 end

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl insert end $item

	#
	# Insert an image into the first cell of the row
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure end,0 -image $leafImg
	} else {
	    $tbl cellconfigure end,0 -image $compImg
	}
    }

    #
    # Configure the "Refresh" and "Parent" buttons
    #
    $top.bf.b1 configure -command [list demo::putChildren $w $tbl]
    set b2 $top.bf.b2
    set p [winfo parent $w]
    if {[string compare $p ""] == 0} {
	$b2 configure -state disabled
    } else {
	$b2 configure -state normal -command [list demo::putChildren $p $tbl]
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the contents of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl cellcget $row,0 -text]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl cellcget [$tbl curselection],0 -text]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/browseTree.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# the children of an arbitrary widget.
#
# Copyright (c) 2010-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.3
package require tablelist 5.16

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config.tcl]

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Path Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-expandcommand demo::expandCmd -labelcommand demo::labelCmd \
	-yscrollcommand [list $vsb set] -setgrid no -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"
    button $b2 -text "Parent"
    button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl root
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl, as child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning \
			-message "Bad window path name \"$w\" -- replacing\
				  it with nearest existent ancestor" \
			-type okcancel -default ok \
			-parent [winfo toplevel $tbl]]
	    if {[string compare $choice "ok"] == 0} {
		while {![winfo exists $w]} {
		    set last [string last "." $w]
		    if {$last != 0} {
			incr last -1
		    }
		    set w [string range $w 0 $last]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	set top [winfo toplevel $tbl]
	wm title $top "Children of the [winfo class $w] Widget \"$w\""

	$tbl resetsortinfo
	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl insertchild $nodeIdx end $item

	#
	# Insert an image into the first cell of the row; mark the
	# row as collapsed if the child widget has children itself
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure $row,0 -image $leafImg
	} else {
	    $tbl cellconfigure $row,0 -image $compImg
	    $tbl collapse $row
	}

	$tbl rowattrib $row pathName $c
	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	$top.bf.b1 configure -command [list demo::refreshView $w $tbl]
	set b2 $top.bf.b2
	set p [winfo parent $w]
	if {[string compare $p ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal -command \
		[list demo::putChildren $p $tbl root]
	}
    }
}

#------------------------------------------------------------------------------
# demo::expandCmd
#
# Outputs the data of the children of the widget whose leaf name is displayed
# in the first cell of the specified row of the tablelist widget tbl, as child
# items of the one identified by row.
#------------------------------------------------------------------------------
proc demo::expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set w [$tbl rowattrib $row pathName]
	putChildren $w $tbl $row

	#
	# Apply the last sorting (if any) to the new items
	#
	$tbl refreshsorting $row
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the contents of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl rowattrib $row pathName]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl root
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl rowattrib [$tbl curselection] pathName]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# demo::refreshView
#
# Redisplays the data of the children of the widget w in the tablelist widget
# tbl and restores the expanded states of the items as well as the vertical
# view.
#------------------------------------------------------------------------------
proc demo::refreshView {w tbl} {
    #
    # Save the vertical view and get the path names of
    # the child widgets displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedWidgets($pathName) 1
    }

    #
    # Redisplay the data of the widget's (possibly changed) children and
    # restore the expanded states of the children, along with the vertical view
    #
    putChildren $w $tbl root
    restoreExpandedStates $tbl root expandedWidgets
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# demo::restoreExpandedStates
#   
# Expands those children of the parent identified by nodeIdx that display the
# data of child widgets whose path names are the names of the elements of the
# array specified by the last argument.
#------------------------------------------------------------------------------
proc demo::restoreExpandedStates {tbl nodeIdx expandedWidgetsName} {
    upvar $expandedWidgetsName expandedWidgets

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[info exists expandedWidgets($pathName)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedWidgets
	}
    }
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/browseTree_tile.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# the children of an arbitrary widget.
#
# Copyright (c) 2010-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config_tile.tcl]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    ttk::frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Path Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-expandcommand demo::expandCmd -labelcommand demo::labelCmd \
	-yscrollcommand [list $vsb set] -setgrid no -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    ttk::scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a tile frame child of the top-level widget
    #
    set bf $top.bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -text "Refresh"
    ttk::button $b2 -text "Parent"
    ttk::button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl root
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl, as child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning \
			-message "Bad window path name \"$w\" -- replacing\
				  it with nearest existent ancestor" \
			-type okcancel -default ok \
			-parent [winfo toplevel $tbl]]
	    if {[string compare $choice "ok"] == 0} {
		while {![winfo exists $w]} {
		    set last [string last "." $w]
		    if {$last != 0} {
			incr last -1
		    }
		    set w [string range $w 0 $last]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	set top [winfo toplevel $tbl]
	wm title $top "Children of the [winfo class $w] Widget \"$w\""

	$tbl resetsortinfo
	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl insertchild $nodeIdx end $item

	#
	# Insert an image into the first cell of the row; mark the
	# row as collapsed if the child widget has children itself
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure $row,0 -image $leafImg
	} else {
	    $tbl cellconfigure $row,0 -image $compImg
	    $tbl collapse $row
	}

	$tbl rowattrib $row pathName $c
	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	$top.bf.b1 configure -command [list demo::refreshView $w $tbl]
	set b2 $top.bf.b2
	set p [winfo parent $w]
	if {[string compare $p ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal -command \
		[list demo::putChildren $p $tbl root]
	}
    }
}

#------------------------------------------------------------------------------
# demo::expandCmd
#
# Outputs the data of the children of the widget whose leaf name is displayed
# in the first cell of the specified row of the tablelist widget tbl, as child
# items of the one identified by row.
#------------------------------------------------------------------------------
proc demo::expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set w [$tbl rowattrib $row pathName]
	putChildren $w $tbl $row

	#
	# Apply the last sorting (if any) to the new items
	#
	$tbl refreshsorting $row
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the contents of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl rowattrib $row pathName]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl root
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl rowattrib [$tbl curselection] pathName]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# demo::refreshView
#
# Redisplays the data of the children of the widget w in the tablelist widget
# tbl and restores the expanded states of the items as well as the vertical
# view.
#------------------------------------------------------------------------------
proc demo::refreshView {w tbl} {
    #
    # Save the vertical view and get the path names of
    # the child widgets displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedWidgets($pathName) 1
    }

    #
    # Redisplay the data of the widget's (possibly changed) children and
    # restore the expanded states of the children, along with the vertical view
    #
    putChildren $w $tbl root
    restoreExpandedStates $tbl root expandedWidgets
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# demo::restoreExpandedStates
#   
# Expands those children of the parent identified by nodeIdx that display the
# data of child widgets whose path names are the names of the elements of the
# array specified by the last argument.
#------------------------------------------------------------------------------
proc demo::restoreExpandedStates {tbl nodeIdx expandedWidgetsName} {
    upvar $expandedWidgetsName expandedWidgets

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[info exists expandedWidgets($pathName)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedWidgets
	}
    }
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/browse_tile.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# children of an arbitrary widget.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config_tile.tcl]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    ttk::frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Path Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-labelcommand demo::labelCmd -yscrollcommand [list $vsb set] -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    ttk::scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a tile frame child of the top-level widget
    #
    set bf $top.bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -text "Refresh"
    ttk::button $b2 -text "Parent"
    ttk::button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	set choice [tk_messageBox -title "Error" -icon warning \
		    -message "Bad window path name \"$w\" -- replacing\
			      it with nearest existent ancestor" \
		    -type okcancel -default ok -parent [winfo toplevel $tbl]]
	if {[string compare $choice "ok"] == 0} {
	    while {![winfo exists $w]} {
		set last [string last "." $w]
		if {$last != 0} {
		    incr last -1
		}
		set w [string range $w 0 $last]
	    }
	} else {
	    return ""
	}
    }

    set top [winfo toplevel $tbl]
    wm title $top "Children of the [winfo class $w] Widget \"$w\""

    $tbl resetsortinfo
    $tbl delete 0 end

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl insert end $item

	#
	# Insert an image into the first cell of the row
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure end,0 -image $leafImg
	} else {
	    $tbl cellconfigure end,0 -image $compImg
	}
    }

    #
    # Configure the "Refresh" and "Parent" buttons
    #
    $top.bf.b1 configure -command [list demo::putChildren $w $tbl]
    set b2 $top.bf.b2
    set p [winfo parent $w]
    if {[string compare $p ""] == 0} {
	$b2 configure -state disabled
    } else {
	$b2 configure -state normal -command [list demo::putChildren $p $tbl]
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the contents of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl cellcget $row,0 -text]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl cellcget [$tbl curselection],0 -text]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/bwidget.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the BWidget package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.4				;# because of "-compound"
package require tablelist 5.16
package require BWidget

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*Checkbutton.background		white
option add *Tablelist*Checkbutton.activeBackground	white
option add *Tablelist*Entry.background			white

#
# Register some widgets from the BWidget package for interactive cell editing
#
tablelist::addBWidgetEntry
tablelist::addBWidgetSpinBox
tablelist::addBWidgetComboBox

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow Entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow ComboBox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow SpinBox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow ComboBox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow ComboBox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow ComboBox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow Entry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow Entry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -range {5 8 1} -editable no
	}

	parity {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {None Even Odd Mark Space} -editable no
	}

	stopBits {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {1 1.5 2} -editable no
	}

	handshake {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {XON/XOFF RTS/CTS None} -editable no
	}

	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 contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
	available {
	    #
	    # Update the image contained in the cell
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/bwidget_tile.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the BWidget package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16
package require BWidget

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*Checkbutton.background		white
option add *Tablelist*Checkbutton.activeBackground	white
option add *Tablelist*Entry.background			white

#
# Register some widgets from the BWidget package for interactive cell editing
#
tablelist::addBWidgetEntry
tablelist::addBWidgetSpinBox
tablelist::addBWidgetComboBox

#
# 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
#
set f [ttk::frame .f]

#
# 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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow Entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow ComboBox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow SpinBox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow ComboBox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow ComboBox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow ComboBox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow Entry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow Entry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -range {5 8 1} -editable no
	}

	parity {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {None Even Odd Mark Space} -editable no
	}

	stopBits {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {1 1.5 2} -editable no
	}

	handshake {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {XON/XOFF RTS/CTS None} -editable no
	}

	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 contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
	available {
	    #
	    # Update the image contained in the cell
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/checked.gif.

cannot compute difference between binary files

Deleted libs/tablelist5.16/demos/clsdFolder.gif.

cannot compute difference between binary files

Deleted libs/tablelist5.16/demos/comp.xbm.

1
2
3
4
5
#define comp_width 14
#define comp_height 12
static unsigned char comp_bits[] = {
   0xff, 0x3f, 0x01, 0x20, 0xfd, 0x3f, 0x05, 0x20, 0xf5, 0x3f, 0x15, 0x20,
   0xd5, 0x3f, 0x55, 0x20, 0x55, 0x3f, 0x55, 0x21, 0x55, 0x21, 0xff, 0x3f};
<
<
<
<
<










Deleted libs/tablelist5.16/demos/config.tcl.

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
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying and editing the
# configuration options of an arbitrary widget.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 5.16

namespace eval demo {
    #
    # Get the current windowing system ("x11", "win32", "classic", or "aqua")
    # and add some entries to the Tk option database for the following
    # widget hierarchy within a top-level widget of the class DemoTop:
    #
    # Name		Class
    # -----------------------------
    # tf		Frame
    #   tbl		  Tabellist
    #   vsb, hsb	  Scrollbar
    # bf		Frame
    #   b1, b2, b3	  Button
    #
    variable winSys
    if {[catch {tk windowingsystem} winSys] != 0} {
	switch $::tcl_platform(platform) {
	    unix	{ set winSys x11 }
	    windows	{ set winSys win32 }
	    macintosh	{ set winSys classic }
	}
    }
    if {[string compare $winSys "x11"] == 0} {
	#
	# Create the font TkDefaultFont if not yet present
	#
	catch {font create TkDefaultFont -family Helvetica -size -12}

	option add *DemoTop*Font			TkDefaultFont
	option add *DemoTop*selectBackground		#678db2
	option add *DemoTop*selectForeground		white
    } else {
	option add *DemoTop.tf.borderWidth		1
	option add *DemoTop.tf.relief			sunken
	option add *DemoTop.tf.tbl.borderWidth		0
	option add *DemoTop.tf.tbl.highlightThickness	0
    }
    option add *DemoTop.tf.tbl.background		white
    option add *DemoTop.tf.tbl.stripeBackground		#f0f0f0
    option add *DemoTop.tf.tbl.setGrid			yes
    option add *DemoTop.tf.tbl*Entry.background		white
    option add *DemoTop.bf.Button.width			10
}

#------------------------------------------------------------------------------
# demo::displayConfig
#
# Displays the configuration options of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayConfig w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .configTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .configTop$n
    }
    toplevel $top -class DemoTop
    wm title $top "Configuration Options of the [winfo class $w] Widget \"$w\""

    #
    # Create a scrolled tablelist widget with 5 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Command-Line Name"
		  0 "Database/Alias Name"
		  0 "Database Class"
		  0 "Default Value"
		  0 "Current Value"} \
	-labelcommand tablelist::sortByColumn -sortcommand demo::compareAsSet \
	-editendcommand demo::applyValue -height 15 -width 100 -stretch all \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set]
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 3 -maxwidth 30
    $tbl columnconfigure 4 -maxwidth 30 -editable yes
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"     -command [list demo::putConfig $w $tbl]
    button $b2 -text "Sort as Set" -command [list $tbl sort]
    button $b3 -text "Close"       -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the configuration options of the given widget
    #
    putConfig $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putConfig
#
# Outputs the configuration options of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putConfig {w tbl} {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    #
    # Display the configuration options of w in the tablelist widget tbl
    #
    $tbl delete 0 end
    foreach configSet [$w configure] {
	#
	# Insert the list configSet into the tablelist widget
	#
	$tbl insert end $configSet

	if {[llength $configSet] == 2} {
	    $tbl rowconfigure end -foreground gray50 -selectforeground gray75
	    $tbl cellconfigure end -editable no
	} else {
	    #
	    # Change the colors of the first and last cell of the row
	    # if the current value is different from the default one
	    #
	    set default [lindex $configSet 3]
	    set current [lindex $configSet 4]
	    if {[string compare $default $current] != 0} {
		foreach col {0 4} {
		    $tbl cellconfigure end,$col \
			 -foreground red -selectforeground yellow
		}
	    }
	}
    }

    $tbl sortbycolumn 0
    $tbl activate 0
    $tbl attrib widget $w
}

#------------------------------------------------------------------------------
# demo::compareAsSet
#
# Compares two items of a tablelist widget used to display the configuration
# options of an arbitrary widget.  The item in which the current value is
# different from the default one is considered to be less than the other; if
# both items fulfil this condition or its negation then string comparison is
# applied to the two option names.
#------------------------------------------------------------------------------
proc demo::compareAsSet {item1 item2} {
    foreach {opt1 dbName1 dbClass1 default1 current1} $item1 \
	    {opt2 dbName2 dbClass2 default2 current2} $item2 {
	set changed1 [expr {[string compare $default1 $current1] != 0}]
	set changed2 [expr {[string compare $default2 $current2] != 0}]
	if {$changed1 == $changed2} {
	    return [string compare $opt1 $opt2]
	} elseif {$changed1} {
	    return -1
	} else {
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# demo::applyValue
#
# Applies the new value of the configuraton option contained in the given row
# of the tablelist widget tbl to the widget whose options are displayed in it,
# and updates the colors of the first and last cell of the row.
#------------------------------------------------------------------------------
proc demo::applyValue {tbl row col text} {
    #
    # Try to apply the new value of the option contained in
    # the given row to the widget whose options are displayed
    # in the tablelist; reject the value if the attempt fails
    #
    set w [$tbl attrib widget]
    set opt [$tbl cellcget $row,0 -text]
    if {[catch {$w configure $opt $text} result] != 0} {
	bell
	tk_messageBox -title "Error" -icon error -message $result \
	    -parent [winfo toplevel $tbl]
	$tbl rejectinput
	return ""
    }

    #
    # Replace the new option value with its canonical form and
    # update the colors of the first and last cell of the row
    #
    set text [$w cget $opt]
    set default [$tbl cellcget $row,3 -text]
    if {[string compare $default $text] == 0} {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col \
		 -foreground "" -selectforeground ""
	}
    } else {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col \
		 -foreground red -selectforeground yellow
	}
    }

    return $text
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display the configuration options of an arbitrary\
	    widget, enter\n\n\tdemo::displayConfig <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/config_tile.tcl.

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
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying and editing the
# configuration options of an arbitrary widget.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16

namespace eval demo {
    #
    # Get the current windowing system ("x11", "win32", or "aqua")
    # and add some entries to the Tk option database for the following
    # widget hierarchy within a top-level widget of the class DemoTop:
    #
    # Name		Class
    # -----------------------------
    # tf		TFrame
    #   tbl		  Tabellist
    #   vsb, hsb	  TScrollbar
    # bf		TFrame
    #   b1, b2, b3	  TButton
    #
    if {[tk windowingsystem] eq "x11"} {
	option add *DemoTop*Font			TkDefaultFont
    } else {
	option add *DemoTop.tf.borderWidth		1
	option add *DemoTop.tf.relief			sunken
	option add *DemoTop.tf.tbl.borderWidth		0
    }
    tablelist::setThemeDefaults
    set foreground [winfo rgb . $tablelist::themeDefaults(-foreground)]
    set selectFg   [winfo rgb . $tablelist::themeDefaults(-selectforeground)]
    set selectFgEqForeground [expr {$selectFg eq $foreground}]
    variable currentTheme [tablelist::getCurrentTheme]
    if {$currentTheme ne "aqua"} {
	option add *DemoTop*selectBackground \
		   $tablelist::themeDefaults(-selectbackground)
	option add *DemoTop*selectForeground \
		   $tablelist::themeDefaults(-selectforeground)
	option add *DemoTop*selectBorderWidth \
		   $tablelist::themeDefaults(-selectborderwidth)
    }
    option add *DemoTop.tf.tbl.background		white
    option add *DemoTop.tf.tbl.stripeBackground		#f0f0f0
    option add *DemoTop.tf.tbl.setGrid			yes
    option add *DemoTop.tf.tbl*Entry.background		white
    option add *DemoTop.bf.TButton.width		10
}

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {$demo::currentTheme eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# demo::displayConfig
#
# Displays the configuration options of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayConfig w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .configTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .configTop$n
    }
    toplevel $top -class DemoTop
    wm title $top "Configuration Options of the [winfo class $w] Widget \"$w\""

    #
    # Create a scrolled tablelist widget with 5 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    ttk::frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Command-Line Name"
		  0 "Database/Alias Name"
		  0 "Database Class"
		  0 "Default Value"
		  0 "Current Value"} \
	-labelcommand tablelist::sortByColumn -sortcommand demo::compareAsSet \
	-editendcommand demo::applyValue -height 15 -width 100 -stretch all \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set]
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 3 -maxwidth 30
    $tbl columnconfigure 4 -maxwidth 30 -editable yes
    ttk::scrollbar $vsb -orient vertical   -command [list $tbl yview]
    ttk::scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create three buttons within a tile frame child of the top-level widget
    #
    set bf $top.bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -text "Refresh"     -command [list demo::putConfig $w $tbl]
    ttk::button $b2 -text "Sort as Set" -command [list $tbl sort]
    ttk::button $b3 -text "Close"       -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the configuration options of the given widget
    #
    putConfig $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putConfig
#
# Outputs the configuration options of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putConfig {w tbl} {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    #
    # Display the configuration options of w in the tablelist widget tbl
    #
    $tbl delete 0 end
    foreach configSet [$w configure] {
	#
	# Insert the list configSet into the tablelist widget
	#
	$tbl insert end $configSet

	if {[llength $configSet] == 2} {
	    $tbl rowconfigure end -foreground gray50 -selectforeground gray75
	    $tbl cellconfigure end -editable no
	} else {
	    #
	    # Change the colors of the first and last cell of the row
	    # if the current value is different from the default one
	    #
	    set default [lindex $configSet 3]
	    set current [lindex $configSet 4]
	    if {[string compare $default $current] != 0} {
		foreach col {0 4} {
		    $tbl cellconfigure end,$col -foreground red
		    if {$demo::selectFgEqForeground} {
			$tbl cellconfigure end,$col -selectforeground red
		    } else {
			$tbl cellconfigure end,$col -selectforeground yellow
		    }
		}
	    }
	}
    }

    $tbl sortbycolumn 0
    $tbl activate 0
    $tbl attrib widget $w
}

#------------------------------------------------------------------------------
# demo::compareAsSet
#
# Compares two items of a tablelist widget used to display the configuration
# options of an arbitrary widget.  The item in which the current value is
# different from the default one is considered to be less than the other; if
# both items fulfil this condition or its negation then string comparison is
# applied to the two option names.
#------------------------------------------------------------------------------
proc demo::compareAsSet {item1 item2} {
    foreach {opt1 dbName1 dbClass1 default1 current1} $item1 \
	    {opt2 dbName2 dbClass2 default2 current2} $item2 {
	set changed1 [expr {[string compare $default1 $current1] != 0}]
	set changed2 [expr {[string compare $default2 $current2] != 0}]
	if {$changed1 == $changed2} {
	    return [string compare $opt1 $opt2]
	} elseif {$changed1} {
	    return -1
	} else {
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# demo::applyValue
#
# Applies the new value of the configuraton option contained in the given row
# of the tablelist widget tbl to the widget whose options are displayed in it,
# and updates the colors of the first and last cell of the row.
#------------------------------------------------------------------------------
proc demo::applyValue {tbl row col text} {
    #
    # Try to apply the new value of the option contained in
    # the given row to the widget whose options are displayed
    # in the tablelist; reject the value if the attempt fails
    #
    set w [$tbl attrib widget]
    set opt [$tbl cellcget $row,0 -text]
    if {[catch {$w configure $opt $text} result] != 0} {
	bell
	tk_messageBox -title "Error" -icon error -message $result \
	    -parent [winfo toplevel $tbl]
	$tbl rejectinput
	return ""
    }

    #
    # Replace the new option value with its canonical form and
    # update the colors of the first and last cell of the row
    #
    set text [$w cget $opt]
    set default [$tbl cellcget $row,3 -text]
    if {[string compare $default $text] == 0} {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col \
		 -foreground "" -selectforeground ""
	}
    } else {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col -foreground red
	    if {$demo::selectFgEqForeground} {
		$tbl cellconfigure $row,$col -selectforeground red
	    } else {
		$tbl cellconfigure $row,$col -selectforeground yellow
	    }
	}
    }

    return $text
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display the configuration options of an arbitrary\
	    widget, enter\n\n\tdemo::displayConfig <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/dirViewer.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
#!/usr/bin/env wish

#==============================================================================
# Demonstrates how to use a tablelist widget for displaying the contents of a
# directory.
#
# Copyright (c) 2010-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.3
package require tablelist 5.16

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create three images
#
image create photo clsdFolderImg -file [file join $dir clsdFolder.gif]
image create photo openFolderImg -file [file join $dir openFolder.gif]
image create photo fileImg       -file [file join $dir file.gif]

#------------------------------------------------------------------------------
# displayContents
#
# Displays the contents of the directory dir in a tablelist widget.
#------------------------------------------------------------------------------
proc displayContents dir {
    #
    # Create a scrolled tablelist widget with 3 dynamic-
    # width columns and interactive sort capability
    #
    set tf .tf
    frame $tf -class ScrollArea
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Name"	    left
		  0 "Size"	    right
		  0 "Date Modified" left} \
	-expandcommand expandCmd -collapsecommand collapseCmd \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] \
	-movablecolumns no -setgrid no -showseparators yes -height 18 -width 80
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 0 -formatcommand formatString -sortmode dictionary
    $tbl columnconfigure 1 -formatcommand formatSize -sortmode integer
    $tbl columnconfigure 2 -formatcommand formatString
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create a pop-up menu with one command entry; bind the script
    # associated with its entry to the <Double-1> event, too
    #
    set menu .menu
    menu $menu -tearoff no
    $menu add command -label "Display Contents" \
		      -command [list putContentsOfSelFolder $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list postPopupMenu %X %Y]
    bind $bodyTag <Double-1>   [list putContentsOfSelFolder $tbl]

    #
    # Create three buttons within a frame child of the main widget
    #
    set bf .bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -width 10 -text "Refresh"
    button $b2 -width 10 -text "Parent"
    button $b3 -width 10 -text "Close" -command exit

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    global winSys
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the contents of the given directory
    #
    $tbl sortbycolumn 0
    putContents $dir $tbl root
}

#------------------------------------------------------------------------------
# putContents
#
# Outputs the contents of the directory dir into the tablelist widget tbl, as
# child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc putContents {dir tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {[string compare $dir ""] != 0 &&
	(![file isdirectory $dir] || ![file readable $dir])} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning -message \
			"Cannot read directory \"[file nativename $dir]\"\
			-- replacing it with nearest existent ancestor" \
			-type okcancel -default ok]
	    if {[string compare $choice "ok"] == 0} {
		while {![file isdirectory $dir] || ![file readable $dir]} {
		    set dir [file dirname $dir]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	if {[string compare $dir ""] == 0} {
	    if {[llength [file volumes]] == 1} {
		wm title . "Contents of the File System"
	    } else {
		wm title . "Contents of the File Systems"
	    }
	} else {
	    wm title . "Contents of the Directory \"[file nativename $dir]\""
	}

	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Build a list from the data of the subdirectories and
    # files of the directory dir.  Prepend a "D" or "F" to
    # each entry's name and modification date & time, for
    # sorting purposes (it will be removed by formatString).
    #
    set itemList {}
    if {[string compare $dir ""] == 0} {
	foreach volume [file volumes] {
	    lappend itemList [list D[file nativename $volume] -1 D $volume]
	}
    } else {
	foreach entry [glob -nocomplain -types {d f} -directory $dir *] {
	    if {[catch {file mtime $entry} modTime] != 0} {
		continue
	    }

	    if {[file isdirectory $entry]} {
		lappend itemList [list D[file tail $entry] -1 \
		    D[clock format $modTime -format "%Y-%m-%d %H:%M"] $entry]
	    } else {
		lappend itemList [list F[file tail $entry] [file size $entry] \
		    F[clock format $modTime -format "%Y-%m-%d %H:%M"] ""]
	    }
	}
    }

    #
    # Sort the above list and insert it into the tablelist widget
    # tbl as list of children of the row identified by nodeIdx
    #
    set itemList [$tbl applysorting $itemList]
    $tbl insertchildlist $nodeIdx end $itemList

    #
    # Insert an image into the first cell of each newly inserted row
    #
    foreach item $itemList {
	set name [lindex $item end]
	if {[string compare $name ""] == 0} {			;# file
	    $tbl cellconfigure $row,0 -image fileImg
	} else {						;# directory
	    $tbl cellconfigure $row,0 -image clsdFolderImg
	    $tbl rowattrib $row pathName $name

	    #
	    # Mark the row as collapsed if the directory is non-empty
	    #
	    if {[file readable $name] && [llength \
		[glob -nocomplain -types {d f} -directory $name *]] != 0} {
		$tbl collapse $row
	    }
	}

	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	.bf.b1 configure -command [list refreshView $dir $tbl]
	set b2 .bf.b2
	if {[string compare $dir ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal
	    set p [file dirname $dir]
	    if {[string compare $p $dir] == 0} {
		$b2 configure -command [list putContents "" $tbl root]
	    } else {
		$b2 configure -command [list putContents $p $tbl root]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# formatString
#
# Returns the substring obtained from the specified value by removing its first
# character.
#------------------------------------------------------------------------------
proc formatString val {
    return [string range $val 1 end]
}

#------------------------------------------------------------------------------
# formatSize
#
# Returns an empty string if the specified value is negative and the value
# itself in user-friendly format otherwise.
#------------------------------------------------------------------------------
proc formatSize val {
    if {$val < 0} {
	return ""
    } elseif {$val < 1024} {
	return "$val bytes"
    } elseif {$val < 1048576} {
	return [format "%.1f KB" [expr {$val / 1024.0}]]
    } elseif {$val < 1073741824} {
	return [format "%.1f MB" [expr {$val / 1048576.0}]]
    } else {
	return [format "%.1f GB" [expr {$val / 1073741824.0}]]
    }
}

#------------------------------------------------------------------------------
# expandCmd
#
# Outputs the contents of the directory whose leaf name is displayed in the
# first cell of the specified row of the tablelist widget tbl, as child items
# of the one identified by row, and updates the image displayed in that cell.
#------------------------------------------------------------------------------
proc expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set dir [$tbl rowattrib $row pathName]
	putContents $dir $tbl $row
    }

    if {[$tbl childcount $row] != 0} {
	$tbl cellconfigure $row,0 -image openFolderImg
    }
}

#------------------------------------------------------------------------------
# collapseCmd
#
# Updates the image displayed in the first cell of the specified row of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc collapseCmd {tbl row} {
    $tbl cellconfigure $row,0 -image clsdFolderImg
}

#------------------------------------------------------------------------------
# putContentsOfSelFolder
#
# Outputs the contents of the selected folder into the tablelist widget tbl.
#------------------------------------------------------------------------------
proc putContentsOfSelFolder tbl {
    set row [$tbl curselection]
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		bell
	    } else {
		putContents $dir $tbl root
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	bell
    }
}

#------------------------------------------------------------------------------
# postPopupMenu
#
# Posts the pop-up menu .menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its only entry, depending upon
# whether the selected item represents a readable directory or not.
#------------------------------------------------------------------------------
proc postPopupMenu {rootX rootY} {
    set tbl .tf.tbl
    set row [$tbl curselection]
    set menu .menu
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		$menu entryconfigure 0 -state disabled
	    } else {
		$menu entryconfigure 0 -state normal
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	$menu entryconfigure 0 -state disabled
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# refreshView
#
# Redisplays the contents of the directory dir in the tablelist widget tbl and
# restores the expanded states of the folders as well as the vertical view.
#------------------------------------------------------------------------------
proc refreshView {dir tbl} {
    #
    # Save the vertical view and get the path names
    # of the folders displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedFolders($pathName) 1
    }

    #
    # Redisplay the directory's (possibly changed) contents and restore
    # the expanded states of the folders, along with the vertical view
    #
    putContents $dir $tbl root
    restoreExpandedStates $tbl root expandedFolders
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# restoreExpandedStates
#
# Expands those children of the parent identified by nodeIdx that display
# folders whose path names are the names of the elements of the array specified
# by the last argument.
#------------------------------------------------------------------------------
proc restoreExpandedStates {tbl nodeIdx expandedFoldersName} {
    upvar $expandedFoldersName expandedFolders

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[string compare $pathName ""] != 0 &&
	    [info exists expandedFolders($pathName)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedFolders
	}
    }
}

displayContents ""
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/dirViewer_tile.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#!/usr/bin/env wish

#==============================================================================
# Demonstrates how to use a tablelist widget for displaying the contents of a
# directory.
#
# Copyright (c) 2010-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option_tile.tcl]

#
# Create three images
#
image create photo clsdFolderImg -file [file join $dir clsdFolder.gif]
image create photo openFolderImg -file [file join $dir openFolder.gif]
image create photo fileImg       -file [file join $dir file.gif]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# displayContents
#
# Displays the contents of the directory dir in a tablelist widget.
#------------------------------------------------------------------------------
proc displayContents dir {
    #
    # Create a scrolled tablelist widget with 3 dynamic-
    # width columns and interactive sort capability
    #
    set tf .tf
    ttk::frame $tf -class ScrollArea
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Name"	    left
		  0 "Size"	    right
		  0 "Date Modified" left} \
	-expandcommand expandCmd -collapsecommand collapseCmd \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] \
	-movablecolumns no -setgrid no -showseparators yes -height 18 -width 80
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 0 -formatcommand formatString -sortmode dictionary
    $tbl columnconfigure 1 -formatcommand formatSize -sortmode integer
    $tbl columnconfigure 2 -formatcommand formatString
    ttk::scrollbar $vsb -orient vertical   -command [list $tbl yview]
    ttk::scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create a pop-up menu with one command entry; bind the script
    # associated with its entry to the <Double-1> event, too
    #
    set menu .menu
    menu $menu -tearoff no
    $menu add command -label "Display Contents" \
		      -command [list putContentsOfSelFolder $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list postPopupMenu %X %Y]
    bind $bodyTag <Double-1>   [list putContentsOfSelFolder $tbl]

    #
    # Create three buttons within a frame child of the main widget
    #
    set bf .bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -width 10 -text "Refresh"
    ttk::button $b2 -width 10 -text "Parent"
    ttk::button $b3 -width 10 -text "Close" -command exit

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the contents of the given directory
    #
    $tbl sortbycolumn 0
    putContents $dir $tbl root
}

#------------------------------------------------------------------------------
# putContents
#
# Outputs the contents of the directory dir into the tablelist widget tbl, as
# child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc putContents {dir tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {[string compare $dir ""] != 0 &&
	(![file isdirectory $dir] || ![file readable $dir])} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning -message \
			"Cannot read directory \"[file nativename $dir]\"\
			-- replacing it with nearest existent ancestor" \
			-type okcancel -default ok]
	    if {[string compare $choice "ok"] == 0} {
		while {![file isdirectory $dir] || ![file readable $dir]} {
		    set dir [file dirname $dir]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	if {[string compare $dir ""] == 0} {
	    if {[llength [file volumes]] == 1} {
		wm title . "Contents of the File System"
	    } else {
		wm title . "Contents of the File Systems"
	    }
	} else {
	    wm title . "Contents of the Directory \"[file nativename $dir]\""
	}

	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Build a list from the data of the subdirectories and
    # files of the directory dir.  Prepend a "D" or "F" to
    # each entry's name and modification date & time, for
    # sorting purposes (it will be removed by formatString).
    #
    set itemList {}
    if {[string compare $dir ""] == 0} {
	foreach volume [file volumes] {
	    lappend itemList [list D[file nativename $volume] -1 D $volume]
	}
    } else {
	foreach entry [glob -nocomplain -types {d f} -directory $dir *] {
	    if {[catch {file mtime $entry} modTime] != 0} {
		continue
	    }

	    if {[file isdirectory $entry]} {
		lappend itemList [list D[file tail $entry] -1 \
		    D[clock format $modTime -format "%Y-%m-%d %H:%M"] $entry]
	    } else {
		lappend itemList [list F[file tail $entry] [file size $entry] \
		    F[clock format $modTime -format "%Y-%m-%d %H:%M"] ""]
	    }
	}
    }

    #
    # Sort the above list and insert it into the tablelist widget
    # tbl as list of children of the row identified by nodeIdx
    #
    set itemList [$tbl applysorting $itemList]
    $tbl insertchildlist $nodeIdx end $itemList

    #
    # Insert an image into the first cell of each newly inserted row
    #
    foreach item $itemList {
	set name [lindex $item end]
	if {[string compare $name ""] == 0} {			;# file
	    $tbl cellconfigure $row,0 -image fileImg
	} else {						;# directory
	    $tbl cellconfigure $row,0 -image clsdFolderImg
	    $tbl rowattrib $row pathName $name

	    #
	    # Mark the row as collapsed if the directory is non-empty
	    #
	    if {[file readable $name] && [llength \
		[glob -nocomplain -types {d f} -directory $name *]] != 0} {
		$tbl collapse $row
	    }
	}

	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	.bf.b1 configure -command [list refreshView $dir $tbl]
	set b2 .bf.b2
	if {[string compare $dir ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal
	    set p [file dirname $dir]
	    if {[string compare $p $dir] == 0} {
		$b2 configure -command [list putContents "" $tbl root]
	    } else {
		$b2 configure -command [list putContents $p $tbl root]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# formatString
#
# Returns the substring obtained from the specified value by removing its first
# character.
#------------------------------------------------------------------------------
proc formatString val {
    return [string range $val 1 end]
}

#------------------------------------------------------------------------------
# formatSize
#
# Returns an empty string if the specified value is negative and the value
# itself in user-friendly format otherwise.
#------------------------------------------------------------------------------
proc formatSize val {
    if {$val < 0} {
	return ""
    } elseif {$val < 1024} {
	return "$val bytes"
    } elseif {$val < 1048576} {
	return [format "%.1f KB" [expr {$val / 1024.0}]]
    } elseif {$val < 1073741824} {
	return [format "%.1f MB" [expr {$val / 1048576.0}]]
    } else {
	return [format "%.1f GB" [expr {$val / 1073741824.0}]]
    }
}

#------------------------------------------------------------------------------
# expandCmd
#
# Outputs the contents of the directory whose leaf name is displayed in the
# first cell of the specified row of the tablelist widget tbl, as child items
# of the one identified by row, and updates the image displayed in that cell.
#------------------------------------------------------------------------------
proc expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set dir [$tbl rowattrib $row pathName]
	putContents $dir $tbl $row
    }

    if {[$tbl childcount $row] != 0} {
	$tbl cellconfigure $row,0 -image openFolderImg
    }
}

#------------------------------------------------------------------------------
# collapseCmd
#
# Updates the image displayed in the first cell of the specified row of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc collapseCmd {tbl row} {
    $tbl cellconfigure $row,0 -image clsdFolderImg
}

#------------------------------------------------------------------------------
# putContentsOfSelFolder
#
# Outputs the contents of the selected folder into the tablelist widget tbl.
#------------------------------------------------------------------------------
proc putContentsOfSelFolder tbl {
    set row [$tbl curselection]
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		bell
	    } else {
		putContents $dir $tbl root
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	bell
    }
}

#------------------------------------------------------------------------------
# postPopupMenu
#
# Posts the pop-up menu .menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its only entry, depending upon
# whether the selected item represents a readable directory or not.
#------------------------------------------------------------------------------
proc postPopupMenu {rootX rootY} {
    set tbl .tf.tbl
    set row [$tbl curselection]
    set menu .menu
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		$menu entryconfigure 0 -state disabled
	    } else {
		$menu entryconfigure 0 -state normal
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	$menu entryconfigure 0 -state disabled
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# refreshView
#
# Redisplays the contents of the directory dir in the tablelist widget tbl and
# restores the expanded states of the folders as well as the vertical view.
#------------------------------------------------------------------------------
proc refreshView {dir tbl} {
    #
    # Save the vertical view and get the path names
    # of the folders displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedFolders($pathName) 1
    }

    #
    # Redisplay the directory's (possibly changed) contents and restore
    # the expanded states of the folders, along with the vertical view
    #
    putContents $dir $tbl root
    restoreExpandedStates $tbl root expandedFolders
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# restoreExpandedStates
#
# Expands those children of the parent identified by nodeIdx that display
# folders whose path names are the names of the elements of the array specified
# by the last argument.
#------------------------------------------------------------------------------
proc restoreExpandedStates {tbl nodeIdx expandedFoldersName} {
    upvar $expandedFoldersName expandedFolders

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[string compare $pathName ""] != 0 &&
	    [info exists expandedFolders($pathName)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedFolders
	}
    }
}

displayContents ""
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/embeddedWindows.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the use of embedded windows in tablelist widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 5.16

wm title . "Tk Library Scripts"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create the font TkFixedFont if not yet present
#
catch {font create TkFixedFont -family Courier -size -12}

#
# Create an image to be displayed in buttons embedded in a tablelist widget
#
image create photo openImg -file [file join $dir open.gif]

#
# Create a vertically scrolled tablelist widget with 5
# dynamic-width columns and interactive sort capability
#
set tf .tf
frame $tf -class ScrollArea 
set tbl $tf.tbl
set vsb $tf.vsb
tablelist::tablelist $tbl \
    -columns {0 "File Name" left
	      0 "Bar Chart" center
	      0 "File Size" right
	      0 "View"      center
	      0 "Seen"      center} \
    -setgrid no -yscrollcommand [list $vsb set] -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -name fileName
$tbl columnconfigure 1 -formatcommand emptyStr -sortmode integer
$tbl columnconfigure 2 -name fileSize -sortmode integer
$tbl columnconfigure 4 -name seen
scrollbar $vsb -orient vertical -command [list $tbl yview]

proc emptyStr val { return "" }

eval font create BoldFont [font actual [$tbl cget -font]] -weight bold

#
# Populate the tablelist widget
#
cd $tk_library
set maxFileSize 0
foreach fileName [lsort [glob *.tcl]] {
    set fileSize [file size $fileName]
    $tbl insert end [list $fileName $fileSize $fileSize "" no]

    if {$fileSize > $maxFileSize} {
	set maxFileSize $fileSize
    }
}

#------------------------------------------------------------------------------
# createFrame
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget tbl, as well as a child frame representing the size of the
# file whose name is diplayed in the first column of the cell's row.
#------------------------------------------------------------------------------
proc createFrame {tbl row col w} {
    #
    # Create the frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w -width 102 -height 14 -background ivory -borderwidth 1 \
	     -relief solid
    bindtags $w [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Create the child frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w.f -height 12 -background red -borderwidth 1 -relief raised
    bindtags $w.f [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Manage the child frame
    #
    set fileSize [$tbl cellcget $row,fileSize -text]
    place $w.f -relwidth [expr {double($fileSize) / $::maxFileSize}]
}

#------------------------------------------------------------------------------
# createButton
#
# Creates a button widget w to be embedded into the specified cell of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc createButton {tbl row col w} {
    set key [$tbl getkeys $row]
    button $w -image openImg -highlightthickness 0 -takefocus 0 \
	      -command [list viewFile $tbl $key]
}

#------------------------------------------------------------------------------
# viewFile
#
# Displays the contents of the file whose name is contained in the row with the
# given key of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc viewFile {tbl key} {
    set top .top$key
    if {[winfo exists $top]} {
	raise $top
	return ""
    }

    toplevel $top
    set fileName [$tbl cellcget k$key,fileName -text]
    wm title $top "File \"$fileName\""

    #
    # Create a vertically scrolled text widget as a grandchild of the toplevel
    #
    set tf $top.tf
    frame $tf -class ScrollArea 
    set txt $tf.txt
    set vsb $tf.vsb
    text $txt -background white -font TkFixedFont -setgrid yes \
	      -yscrollcommand [list $vsb set]
    catch {$txt configure -tabstyle wordprocessor}	;# for Tk 8.5 and above
    scrollbar $vsb -orient vertical -command [list $txt yview]

    #
    # Insert the file's contents into the text widget
    #
    set chan [open $fileName]
    $txt insert end [read $chan]
    close $chan

    set btn [button $top.btn -text "Close" -command [list destroy $top]]

    #
    # Manage the widgets
    #
    grid $txt -row 0 -column 0 -sticky news
    grid $vsb -row 0 -column 1 -sticky ns
    grid rowconfigure    $tf 0 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $btn -side bottom -pady 10
    pack $tf  -side top -expand yes -fill both

    #
    # Mark the file as seen
    #
    $tbl rowconfigure k$key -font BoldFont
    $tbl cellconfigure k$key,seen -text yes
}

#------------------------------------------------------------------------------

#
# Create embedded windows in the columns no. 1 and 3
#
set rowCount [$tbl size]
for {set row 0} {$row < $rowCount} {incr row} {
    $tbl cellconfigure $row,1 -window createFrame -stretchwindow yes
    $tbl cellconfigure $row,3 -window createButton
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
if {[string compare $winSys "aqua"] == 0} {
    grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
    grid $vsb		   -row 1 -column 1 -sticky ns
} else {
    grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
}
grid rowconfigure    $tf 1 -weight 1
grid columnconfigure $tf 0 -weight 1
pack $btn -side bottom -pady 10
pack $tf  -side top -expand yes -fill both
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/embeddedWindows_tile.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the use of embedded windows in tablelist widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16

wm title . "Tile Library Scripts"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option_tile.tcl]

#
# Create the font TkFixedFont if not yet present
#
catch {font create TkFixedFont -family Courier -size -12}

#
# Create an image to be displayed in buttons embedded in a tablelist widget
#
image create photo openImg -file [file join $dir open.gif]

if {[tablelist::getCurrentTheme] eq "aqua"} {
    #
    # Work around the improper appearance of the tile scrollbars
    #
    interp alias {} ttk::scrollbar {} ::scrollbar
} else {
    #
    # Make the embedded buttons as small as possible.  Recall that in most
    # themes, the tile buttons consist of the following element hierarchy:
    #
    # Button.border
    #     Button.focus	      (one of its options is -focusthickness)
    #         Button.padding  (two of its options are -padding and -shiftrelief)
    #             Button.label
    #
    if {[info commands "::ttk::style"] ne ""} {
	interp alias {} styleConfig {} ttk::style configure
    } elseif {[string compare $tile::version "0.7"] >= 0} {
	interp alias {} styleConfig {} style configure
    } else {
	interp alias {} styleConfig {} style default
    }
    styleConfig Embedded.TButton -focusthickness 0 -padding 0 -shiftrelief 0
}

#
# Create a vertically scrolled tablelist widget with 5
# dynamic-width columns and interactive sort capability
#
set tf .tf
ttk::frame $tf -class ScrollArea
set tbl $tf.tbl
set vsb $tf.vsb
tablelist::tablelist $tbl \
    -columns {0 "File Name" left
	      0 "Bar Chart" center
	      0 "File Size" right
	      0 "View"      center
	      0 "Seen"      center} \
    -setgrid no -yscrollcommand [list $vsb set] -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -name fileName
$tbl columnconfigure 1 -formatcommand emptyStr -sortmode integer
$tbl columnconfigure 2 -name fileSize -sortmode integer
$tbl columnconfigure 4 -name seen
ttk::scrollbar $vsb -orient vertical -command [list $tbl yview]

proc emptyStr val { return "" }

eval font create BoldFont [font actual [$tbl cget -font]] -weight bold

#
# Populate the tablelist widget
#
if {[info exists ttk::library]} {
    cd $ttk::library
} else {
    cd $tile::library
}
set maxFileSize 0
foreach fileName [lsort [glob *.tcl]] {
    set fileSize [file size $fileName]
    $tbl insert end [list $fileName $fileSize $fileSize "" no]

    if {$fileSize > $maxFileSize} {
	set maxFileSize $fileSize
    }
}

#------------------------------------------------------------------------------
# createFrame
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget tbl, as well as a child frame representing the size of the
# file whose name is diplayed in the first column of the cell's row.
#------------------------------------------------------------------------------
proc createFrame {tbl row col w} {
    #
    # Create the frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w -width 102 -height 14 -background ivory -borderwidth 1 \
	     -relief solid
    bindtags $w [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Create the child frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w.f -height 12 -background red -borderwidth 1 -relief raised
    bindtags $w.f [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Manage the child frame
    #
    set fileSize [$tbl cellcget $row,fileSize -text]
    place $w.f -relwidth [expr {double($fileSize) / $::maxFileSize}]
}

#------------------------------------------------------------------------------
# createButton
#
# Creates a button widget w to be embedded into the specified cell of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc createButton {tbl row col w} {
    set key [$tbl getkeys $row]
    ttk::button $w -style Embedded.TButton -image openImg -takefocus 0 \
		   -command [list viewFile $tbl $key]
}

#------------------------------------------------------------------------------
# viewFile
#
# Displays the contents of the file whose name is contained in the row with the
# given key of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc viewFile {tbl key} {
    set top .top$key
    if {[winfo exists $top]} {
	raise $top
	return ""
    }

    toplevel $top
    set fileName [$tbl cellcget k$key,fileName -text]
    wm title $top "File \"$fileName\""

    #
    # Create a vertically scrolled text widget as a grandchild of the toplevel
    #
    set tf $top.tf
    ttk::frame $tf -class ScrollArea
    set txt $tf.txt
    set vsb $tf.vsb
    text $txt -background white -font TkFixedFont -highlightthickness 0 \
	      -setgrid yes -yscrollcommand [list $vsb set]
    catch {$txt configure -tabstyle wordprocessor}	;# for Tk 8.5 and above
    ttk::scrollbar $vsb -orient vertical -command [list $txt yview]

    #
    # Insert the file's contents into the text widget
    #
    set chan [open $fileName]
    $txt insert end [read $chan]
    close $chan

    set bf $top.bf
    ttk::frame $bf
    set btn [ttk::button $bf.btn -text "Close" -command [list destroy $top]]

    #
    # Manage the widgets
    #
    grid $txt -row 0 -column 0 -sticky news
    grid $vsb -row 0 -column 1 -sticky ns
    grid rowconfigure    $tf 0 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $btn -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Mark the file as seen
    #
    $tbl rowconfigure k$key -font BoldFont
    $tbl cellconfigure k$key,seen -text yes
}

#------------------------------------------------------------------------------

#
# Create embedded windows in the columns no. 1 and 3
#
set rowCount [$tbl size]
for {set row 0} {$row < $rowCount} {incr row} {
    $tbl cellconfigure $row,1 -window createFrame -stretchwindow yes
    $tbl cellconfigure $row,3 -window createButton
}

set bf .bf
ttk::frame $bf
set btn [ttk::button $bf.btn -text "Close" -command exit]

#
# Manage the widgets
#
grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
if {[tablelist::getCurrentTheme] eq "aqua"} {
    grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
    grid $vsb		   -row 1 -column 1 -sticky ns
} else {
    grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
}
grid rowconfigure    $tf 1 -weight 1
grid columnconfigure $tf 0 -weight 1
pack $btn -pady 10
pack $bf -side bottom -fill x
pack $tf -side top -expand yes -fill both
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/file.gif.

cannot compute difference between binary files

Deleted libs/tablelist5.16/demos/images.tcl.

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
#==============================================================================
# Creates some images.
#
# Copyright (c) 2011-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Create two images, to be displayed in tablelist cells with boolean values
#
image create photo checkedImg   -file [file join $dir checked.gif]
image create photo uncheckedImg -file [file join $dir unchecked.gif]

#
# Create 16 images representing different colors
#
set colorNames {
    "red" "green" "blue" "magenta"
    "yellow" "cyan" "white" "light gray"
    "dark red" "dark green" "dark blue" "dark magenta"
    "dark yellow" "dark cyan" "dark gray" "black"
}
set colorValues {
    #FF0000 #00FF00 #0000FF #FF00FF
    #FFFF00 #00FFFF #FFFFFF #C0C0C0
    #800000 #008000 #000080 #800080
    #808000 #008080 #808080 #000000
}
foreach name $colorNames value $colorValues {
    set colors($name) $value
}
foreach value $colorValues {
    image create photo img$value -height 13 -width 13
    img$value put gray50 -to 0 0 13 1				;# top edge
    img$value put gray50 -to 0 1 1 12				;# left edge
    img$value put gray75 -to 0 12 13 13				;# bottom edge
    img$value put gray75 -to 12 1 13 12				;# right edge
    img$value put $value -to 1 1 12 12
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































Deleted libs/tablelist5.16/demos/iwidgets.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the Iwidgets package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.4				;# because of "-compound"
package require tablelist 5.16
package require Iwidgets

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*Checkbutton.background		white
option add *Tablelist*Checkbutton.activeBackground	white
option add *Tablelist*textBackground			white
option add *Tablelist*Entry.disabledBackground		white
option add *Tablelist*Entry.disabledForeground		black
option add *Tablelist*Dateentry*Label.background	white
option add *Tablelist*Timeentry*Label.background	white

#
# Register some widgets from the Iwidgets package for interactive cell editing
#
tablelist::addIncrEntryfield
tablelist::addIncrSpinint
tablelist::addIncrCombobox
tablelist::addIncrDateTimeWidget dateentry -seconds
tablelist::addIncrDateTimeWidget timeentry -seconds

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entryfield \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinint
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -pasting no -fixed 20
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w insert list end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    $w configure -pasting no -fixed 6 -validate numeric
	}

	dataBits {
	    #
	    # Configure the spinint widget
	    #
	    $w configure -range {5 8} -wrap no -pasting no -fixed 1 \
			 -validate {regexp {^[5-8]$} %c}
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end None Even Odd Mark Space
	    $w configure -editable no -listheight 120
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end 1 1.5 2
	    $w configure -editable no -listheight 90
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end XON/XOFF RTS/CTS None
	    $w configure -editable no -listheight 90
	}

	actDate {
	    #
	    # Set the date format "%Y-%m-%d"
	    #
	    $w configure -int yes
	}

	actTime {
	    #
	    # Set the time format "%H:%M:%S"
	    #
	    $w configure -format military
	}

	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 contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
	available {
	    #
	    # Update the image contained in the cell
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
	    }
	}

	dataBits {
	    #
	    # Check whether the # of data bits is an integer in the range 5..8
	    #
	    if {![regexp {^[5-8]$} $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message \
		    "The # of data bits must be an integer in the range 5..8"
		$tbl rejectinput
	    }
	}

	actDate {
	    #
	    # 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 $text]
	    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 {
	    #
	    # 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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/iwidgets_tile.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the Iwidgets package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16
package require Iwidgets

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*Checkbutton.background		white
option add *Tablelist*Checkbutton.activeBackground	white
option add *Tablelist*textBackground			white
option add *Tablelist*Entry.disabledBackground		white
option add *Tablelist*Entry.disabledForeground		black
option add *Tablelist*Dateentry*Label.background	white
option add *Tablelist*Timeentry*Label.background	white

#
# Register some widgets from the Iwidgets package for interactive cell editing
#
tablelist::addIncrEntryfield
tablelist::addIncrSpinint
tablelist::addIncrCombobox
tablelist::addIncrDateTimeWidget dateentry -seconds
tablelist::addIncrDateTimeWidget timeentry -seconds

#
# 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
#
set f [ttk::frame .f]

#
# 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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entryfield \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinint
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -pasting no -fixed 20
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w insert list end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    $w configure -pasting no -fixed 6 -validate numeric
	}

	dataBits {
	    #
	    # Configure the spinint widget
	    #
	    $w configure -range {5 8} -wrap no -pasting no -fixed 1 \
			 -validate {regexp {^[5-8]$} %c}
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end None Even Odd Mark Space
	    $w configure -editable no -listheight 120
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end 1 1.5 2
	    $w configure -editable no -listheight 90
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end XON/XOFF RTS/CTS None
	    $w configure -editable no -listheight 90
	}

	actDate {
	    #
	    # Set the date format "%Y-%m-%d"
	    #
	    $w configure -int yes
	}

	actTime {
	    #
	    # Set the time format "%H:%M:%S"
	    #
	    $w configure -format military
	}

	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 contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
	available {
	    #
	    # Update the image contained in the cell
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
	    }
	}

	dataBits {
	    #
	    # Check whether the # of data bits is an integer in the range 5..8
	    #
	    if {![regexp {^[5-8]$} $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message \
		    "The # of data bits must be an integer in the range 5..8"
		$tbl rejectinput
	    }
	}

	actDate {
	    #
	    # 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 $text]
	    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 {
	    #
	    # 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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/leaf.xbm.

1
2
3
4
5
#define leaf_width 14
#define leaf_height 12
static unsigned char leaf_bits[] = {
   0xff, 0x3f, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
   0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0xff, 0x3f};
<
<
<
<
<










Deleted libs/tablelist5.16/demos/miscWidgets.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of Bryan
# Oakley's combobox, the mentry widgets of type "Date" and "Time", and of the
# Tk core entry, spinbox, checkbutton, and menubutton widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.4		;# because of "-compound" and the spinbox widget
package require tablelist 5.16
package require combobox
package require mentry

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*Checkbutton.background		white
option add *Tablelist*Checkbutton.activeBackground	white
option add *Tablelist*Entry.background			white
option add *Tablelist*Spinbox.background		white
option add *Tablelist*Spinbox.readonlyBackground	white
option add *Tablelist*Combobox.background		white
option add *Tablelist*Combobox.elementBorderWidth	2
option add *Tablelist*Mentry.background			white

#
# Register Bryan Oakley's combobox widget as well as the mentry
# widgets of type "Date" and "Time" for interactive cell editing
#
tablelist::addOakleyCombobox
tablelist::addDateMentry Ymd -
tablelist::addTimeMentry HMS :

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinbox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateMentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeMentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both

#------------------------------------------------------------------------------
# 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
	    #
	    wcb::callback $w before insert {wcb::checkEntryLen 20}
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w list insert end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    wcb::callback [$tbl entrypath] before insert \
		{wcb::checkEntryLen 6} {wcb::checkStrForRegExp {^[0-9]*$}}
	}

	dataBits {
	    #
	    # Configure the spinbox
	    #
	    $w configure -from 5 -to 8 -state readonly
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end None Even Odd Mark Space
	    $w configure -editable no
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end 1 1.5 2
	    $w configure -editable no
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end XON/XOFF RTS/CTS None
	    $w configure -editable no
	}

	actDate -
	actTime {
	    #
	    # Configure the mentry widget
	    #
	    $w configure -justify center
	}

	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
}

#
# Message strings corresponding to the values
# returned by mentry::getClockVal on failure
#
array set msgs {
    EMPTY	"Field value missing"
    BAD		"Invalid field value"
    BAD_DATE	"Invalid date"
    BAD_YEAR	"Unsupported year"
}

#------------------------------------------------------------------------------
# editEndCmd
#
# Performs a final validation of the text contained in the edit window and gets
# the cell's internal contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
	available {
	    #
	    # Update the image contained in the cell
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 $text]
	    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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/miscWidgets_tile.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of Bryan
# Oakley's combobox, the mentry widgets of type "Date" and "Time", and of the
# Tk core entry, spinbox, checkbutton, and menubutton widgets.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16
package require combobox
package require mentry

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*Checkbutton.background		white
option add *Tablelist*Checkbutton.activeBackground	white
option add *Tablelist*Entry.background			white
option add *Tablelist*Spinbox.background		white
option add *Tablelist*Spinbox.readonlyBackground	white
option add *Tablelist*Combobox.background		white
option add *Tablelist*Combobox.elementBorderWidth	2
option add *Tablelist*Mentry.background			white

#
# Register Bryan Oakley's combobox widget as well as the mentry
# widgets of type "Date" and "Time" for interactive cell editing
#
tablelist::addOakleyCombobox
tablelist::addDateMentry Ymd -
tablelist::addTimeMentry HMS :

#
# 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
#
set f [ttk::frame .f]

#
# 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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinbox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateMentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeMentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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
	    #
	    wcb::callback $w before insert {wcb::checkEntryLen 20}
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w list insert end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    wcb::callback [$tbl entrypath] before insert \
		{wcb::checkEntryLen 6} {wcb::checkStrForRegExp {^[0-9]*$}}
	}

	dataBits {
	    #
	    # Configure the spinbox
	    #
	    $w configure -from 5 -to 8 -state readonly
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end None Even Odd Mark Space
	    $w configure -editable no
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end 1 1.5 2
	    $w configure -editable no
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end XON/XOFF RTS/CTS None
	    $w configure -editable no
	}

	actDate -
	actTime {
	    #
	    # Configure the mentry widget
	    #
	    $w configure -justify center
	}

	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
}

#
# Message strings corresponding to the values
# returned by mentry::getClockVal on failure
#
array set msgs {
    EMPTY	"Field value missing"
    BAD		"Invalid field value"
    BAD_DATE	"Invalid date"
    BAD_YEAR	"Unsupported year"
}

#------------------------------------------------------------------------------
# editEndCmd
#
# Performs a final validation of the text contained in the edit window and gets
# the cell's internal contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
	available {
	    #
	    # Update the image contained in the cell
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 $text]
	    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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/open.gif.

cannot compute difference between binary files

Deleted libs/tablelist5.16/demos/openFolder.gif.

cannot compute difference between binary files

Deleted libs/tablelist5.16/demos/option.tcl.

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
#==============================================================================
# Contains some Tk option database settings.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Get the current windowing system ("x11", "win32", "classic", or "aqua")
#
if {[catch {tk windowingsystem} winSys] != 0} {
    switch $::tcl_platform(platform) {
	unix      { set winSys x11 }
	windows   { set winSys win32 }
	macintosh { set winSys classic }
    }
}

#
# Add some entries to the Tk option database
#
if {[string compare $winSys "x11"] == 0} {
    #
    # Create the font TkDefaultFont if not yet present
    #
    catch {font create TkDefaultFont -family Helvetica -size -12}

    option add *Font			TkDefaultFont
    option add *selectBackground	#678db2
    option add *selectForeground	white
} else {
    option add *ScrollArea.borderWidth			1
    option add *ScrollArea.relief			sunken
    option add *ScrollArea.Tablelist.borderWidth	0
    option add *ScrollArea.Tablelist.highlightThickness	0
    option add *ScrollArea.Text.borderWidth		0
    option add *ScrollArea.Text.highlightThickness	0
}
option add *Tablelist.background	white
option add *Tablelist.stripeBackground	#f0f0f0
option add *Tablelist.setGrid		yes
option add *Tablelist.movableColumns	yes
option add *Tablelist.labelCommand	tablelist::sortByColumn
option add *Tablelist.labelCommand2	tablelist::addToSortColumns
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































Deleted libs/tablelist5.16/demos/option_tile.tcl.

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
#==============================================================================
# Contains some Tk option database settings.
#
# Copyright (c) 2004-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Get the current windowing system ("x11", "win32", or
# "aqua") and add some entries to the Tk option database
#
if {[tk windowingsystem] eq "x11"} {
    option add *Font			TkDefaultFont
} else {
    option add *ScrollArea.borderWidth			1
    option add *ScrollArea.relief			sunken
    option add *ScrollArea.Tablelist.borderWidth	0
    option add *ScrollArea.Text.borderWidth		0
    option add *ScrollArea.Text.highlightThickness	0
}
tablelist::setThemeDefaults
if {[tablelist::getCurrentTheme] eq "aqua"} {
    option add *Listbox.selectBackground \
	       $tablelist::themeDefaults(-selectbackground)
    option add *Listbox.selectForeground \
	       $tablelist::themeDefaults(-selectforeground)
} else {
    option add *selectBackground  $tablelist::themeDefaults(-selectbackground)
    option add *selectForeground  $tablelist::themeDefaults(-selectforeground)
}
option add *selectBorderWidth     $tablelist::themeDefaults(-selectborderwidth)
option add *Tablelist.background	white
option add *Tablelist.stripeBackground	#f0f0f0
option add *Tablelist.setGrid		yes
option add *Tablelist.movableColumns	yes
option add *Tablelist.labelCommand	tablelist::sortByColumn
option add *Tablelist.labelCommand2	tablelist::addToSortColumns
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































Deleted libs/tablelist5.16/demos/styles.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates some ways of improving the look & feel of a tablelist widget.
#
# Copyright (c) 2002-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 5.16

wm title . "Tablelist Styles"

#
# Get the current windowing system ("x11", "win32", "classic",
# or "aqua") and add some entries to the Tk option database
#
if {[catch {tk windowingsystem} winSys] != 0} {
    switch $::tcl_platform(platform) {
	unix      { set winSys x11 }
	windows   { set winSys win32 }
	macintosh { set winSys classic }
    }
}
if {[string compare $winSys "x11"] == 0} {
    #
    # Create the font TkDefaultFont if not yet present
    #
    catch {font create TkDefaultFont -family Helvetica -size -12}

    option add *Font			TkDefaultFont
    option add *selectBackground	#678db2
    option add *selectForeground	white
}

#
# Create, configure, and populate 8 tablelist widgets
#
frame .f
for {set n 0} { $n < 8} {incr n} {
    set tbl .f.tbl$n
    tablelist::tablelist $tbl \
	-columntitles {"Label 0" "Label 1" "Label 2" "Label 3"} \
	-background white -height 4 -width 40 -stretch all
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }

    switch $n {
	1 {
	    $tbl configure -showseparators yes
	}
	2 {
	    $tbl configure -stripebackground #f0f0f0
	}
	3 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	}
	4 {
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	5 {
	    $tbl configure -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	6 {
	    $tbl configure -stripebackground #f0f0f0
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
	7 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
    }

    foreach row {0 1 2 3} {
	$tbl insert end \
	     [list "Cell $row,0" "Cell $row,1" "Cell $row,2" "Cell $row,3"]
    }
}

button .close -text "Close" -command exit
frame .bottom -height 10

#
# Manage the widgets
#
grid .f.tbl0 .f.tbl1 -sticky news -padx 5 -pady 5
grid .f.tbl2 .f.tbl3 -sticky news -padx 5 -pady 5
grid .f.tbl4 .f.tbl5 -sticky news -padx 5 -pady 5
grid .f.tbl6 .f.tbl7 -sticky news -padx 5 -pady 5
grid rowconfigure    .f {0 1 2 3} -weight 1
grid columnconfigure .f {0 1}     -weight 1
pack .bottom .close -side bottom
pack .f -side top -expand yes -fill both -padx 5 -pady 5
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































Deleted libs/tablelist5.16/demos/styles_tile.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates some ways of improving the look & feel of a tablelist widget.
#
# Copyright (c) 2002-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16

wm title . "Tablelist Styles"

#
# Improve the window's appearance by using a tile
# frame as a container for the other widgets
#
set f [ttk::frame .f]

#
# Create, configure, and populate 8 tablelist widgets
#
ttk::frame $f.f
for {set n 0} { $n < 8} {incr n} {
    set tbl $f.f.tbl$n
    tablelist::tablelist $tbl \
	-columntitles {"Label 0" "Label 1" "Label 2" "Label 3"} \
	-background white -stripebackground "" -height 4 -width 40 -stretch all
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }

    switch $n {
	1 {
	    $tbl configure -showseparators yes
	}
	2 {
	    $tbl configure -stripebackground #f0f0f0
	}
	3 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	}
	4 {
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	5 {
	    $tbl configure -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	6 {
	    $tbl configure -stripebackground #f0f0f0
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
	7 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
    }

    foreach row {0 1 2 3} {
	$tbl insert end \
	     [list "Cell $row,0" "Cell $row,1" "Cell $row,2" "Cell $row,3"]
    }
}

ttk::button $f.close -text "Close" -command exit
ttk::frame $f.bottom -height 10

#
# Manage the widgets
#
grid $f.f.tbl0 $f.f.tbl1 -sticky news -padx 5 -pady 5
grid $f.f.tbl2 $f.f.tbl3 -sticky news -padx 5 -pady 5
grid $f.f.tbl4 $f.f.tbl5 -sticky news -padx 5 -pady 5
grid $f.f.tbl6 $f.f.tbl7 -sticky news -padx 5 -pady 5
grid rowconfigure    $f.f {0 1 2 3} -weight 1
grid columnconfigure $f.f {0 1}     -weight 1
pack $f.bottom $f.close -side bottom
pack $f.f -side top -expand yes -fill both -padx 5 -pady 5
pack $f -expand yes -fill both
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































Deleted libs/tablelist5.16/demos/tileWidgets.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the tile package and of the Tk core spinbox widget.
#
# Copyright (c) 2005-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 5.16

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
#
set f [ttk::frame .f]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#
# 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 \
    -height 0 -width 0
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
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow ttk::entry \
    -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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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 contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
	available {
	    #
	    # Update the image contained in the cell
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/demos/unchecked.gif.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/adwaita.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/ambiance.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/aqua.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/arrowStyles.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/arrowStyles_vista.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/baghira.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/bicolor1.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/bicolor2.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/bicolor3.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/bicolor4.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/browse.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/browseTree.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/bwidget.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/classic1.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/classic2.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/classic3.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/classic4.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/config.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/dirViewer.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/dust.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/dustSand.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/embeddedWindows.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/embeddedWindows_tile.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/gtk.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/index.html.

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
<html>
<head>
  <title>The Multi-Column Listbox and Tree Widget Package Tablelist
  5.16</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content=
  "tablelist, multi-column, listbox, tree, widget, tile">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>The Multi-Column Listbox and Tree Widget Package Tablelist 5.16</h1>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>

  <hr>

  <h2>Contents</h2>

  <p><a href="tablelist.html">Tablelist Programmer's Guide</a></p>

  <p><a href="tablelistWidget.html">The <code>tablelist::tablelist</code>
  Command</a></p>

  <p><a href="tablelistColSort.html">Commands for Interactive Sorting by One or
  More Columns</a></p>

  <p><a href="tablelistBinding.html">Helper Commands Used in Tablelist Binding
  Scripts</a></p>

  <p><a href="tablelistTkCore.html">Interactive Tablelist Cell Editing Using Tk
  Core Widgets</a></p>

  <p><a href="tablelistTile.html">Interactive Tablelist Cell Editing Using Tile
  Widgets</a></p>

  <p><a href="tablelistBWidget.html">Interactive Tablelist Cell Editing Using
  the BWidget Package</a></p>

  <p><a href="tablelistIwidgets.html">Interactive Tablelist Cell Editing Using
  the Iwidgets Package</a></p>

  <p><a href="tablelistCombobox.html">Interactive Tablelist Cell Editing Using
  the combobox Package</a></p>

  <p><a href="tablelistCtext.html">Interactive Tablelist Cell Editing Using
  the ctext Package</a></p>

  <p><a href="tablelistMentry.html">Interactive Tablelist Cell Editing Using
  the Mentry Package</a></p>

  <p><a href="tablelistThemes.html">Commands Related to Tile Themes</a></p>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































Deleted libs/tablelist5.16/doc/klearlooks.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/mate.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/mint.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/mint2.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/newWave.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/oxygen1.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/oxygen2.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/phase.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/plain1.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/plain2.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/plain3.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/plain4.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/plastik.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/plastique.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/radiance.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/styles.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/stylesheet.css.

1
2
3
4
5
6
7
8
/* generic class defining a top margin whose height equals the font size */
.tm {margin-top: 1em}

/* background and border for the <pre> tag */
pre {background: #F7F7F7; border: silver solid 1px}

/* color for the <span> tag */
span {color: #E00000}
<
<
<
<
<
<
<
<
















Deleted libs/tablelist5.16/doc/tablelist.html.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
<html>
<head>
  <title>Tablelist Programmer's Guide</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content=
  "tablelist, multi-column, listbox, tree, widget, tile">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Tablelist Programmer's Guide</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <h4><a href="#overview">Overview</a></h4>

  <ul>
    <li><a href="#ov_what">What is Tablelist?</a></li>

    <li><a href="#ov_get">How to Get It?</a></li>

    <li><a href="#ov_install">How to Install It?</a></li>

    <li><a href="#ov_use">How to Use It?</a></li>

    <li><a href="#ov_tile">More on Tablelist_tile</a></li>
  </ul>

  <h4><a href="#examples">Examples</a></h4>

  <ul>
    <li><a href="#ex_config">A tablelist Widget for Displaying and Editing
    Configuration Options</a></li>

    <li><a href="#ex_browse">Two Widget Browsers Based on a tablelist</a></li>

    <li><a href="#ex_dirViewer">A Directory Viewer Based on a
    tablelist</a></li>

    <li><a href="#ex_styles">Improving the Look &amp; Feel of a tablelist
    Widget</a></li>

    <li><a href="#ex_editing">Advanced Interactive tablelist Cell
    Editing</a></li>

    <li><a href="#ex_windows">A tablelist Widget Containing Embedded
    Windows</a></li>

    <li><a href="#ex_tile">Tile-Based Demo Scripts</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <h3 id="ov_what">What is Tablelist?</h3>

  <p>Tablelist is a library package for Tcl/Tk versions 8.0 or higher, written
  in pure Tcl/Tk code.&nbsp; It contains:</p>

  <ul>
    <li>the implementation of the <a href=
    "tablelistWidget.html"><b>tablelist</b> mega-widget</a>, including a
    general utility module for mega-widgets;</li>

    <li>a demo script containing a useful procedure that displays the
    configuration options of an arbitrary widget in a tablelist and enables you
    to edit their values interactively;</li>

    <li>a demo script implementing a widget browser based on a tablelist used
    as multi-column listbox;</li>

    <li>a demo script implementing a widget browser based on a tablelist used
    as multi-column tree widget;</li>

    <li>a demo script implementing a directory viewer based on a tablelist used
    as multi-column tree widget;</li>

    <li>a demo script showing several ways to improve the appearance of a
    tablelist widget;</li>

    <li>four further demo scripts, illustrating the interactive cell editing
    with the aid of various widgets from the Tk core and from the packages
    tile, BWidget, Iwidgets, combobox (by Bryan Oakley), and Mentry;</li>

    <li>one further demo script, with a tablelist widget containing embedded
    windows;</li>

    <li>tile-based counterparts of the above-mentioned demo scripts;</li>

    <li>this tutorial;</li>

    <li>reference pages in HTML format.</li>
  </ul>

  <p>A tablelist is a multi-column listbox and tree widget.&nbsp; The width of
  each column can be dynamic (i.e., just large enough to hold all its elements,
  including the header) or static (specified in characters or pixels).&nbsp;
  The columns are, per default, resizable.&nbsp; The alignment of each column
  can be specified as <code>left</code>, <code>right</code>, or
  <code>center</code>.</p>

  <p>The columns, rows, and cells can be configured individually.&nbsp; Several
  of the global and column-specific options refer to the headers, implemented
  as label widgets.&nbsp; For instance, the <code>-labelcommand</code> option
  specifies a Tcl command to be invoked when mouse button 1 is released over a
  label.&nbsp; The most common value of this option sorts the items based on
  the respective column.</p>

  <p>The Tablelist package provides a great variety of tree styles controlling
  the look &amp; feel of the column that displays the tree hierarchy with the
  aid of indentations and expand/collapse controls.</p>

  <p>Interactive editing of the elements of a tablelist widget can be enabled
  for individual cells and for entire columns.&nbsp; A great variety of widgets
  from the Tk core and from the packages tile, BWidget, Iwidgets, combobox,
  ctext, and Mentry (or Mentry_tile) is supported for being used as embedded
  edit window.&nbsp; In addition, a rich set of keyboard bindings is provided
  for a comfortable navigation between the editable cells.</p>

  <p>The Tcl command corresponding to a tablelist widget is very similar to the
  one associated with a normal listbox.&nbsp; There are column-, row-, and
  cell-specific counterparts of the <code>configure</code> and
  <code>cget</code> subcommands (<code>columnconfigure</code>,
  <code>rowconfigure</code>, <code>cellconfigure</code>, ...).&nbsp; They can
  be used, among others, to insert images into the cells and the header labels,
  or to insert embedded windows into the cells.&nbsp; The <code>index</code>,
  <code>nearest</code>, and <code>see</code> command options refer to the rows,
  but similar subcommands are provided for the columns and cells
  (<code>columnindex</code>, <code>cellindex</code>, ...).&nbsp; The items can
  be sorted with the <code>sort</code>, <code>sortbycolumn</code>, and
  <code>sortbycolumnlist</code> command options.</p>

  <p>The bindings defined for the body of a tablelist widget make it behave
  just like a normal listbox.&nbsp; This includes the support for the virtual
  event <code>&lt;&lt;ListboxSelect&gt;&gt;</code> (which is equivalent to
  <code>&lt;&lt;TablelistSelect&gt;&gt;</code>).&nbsp; In addition, versions
  2.3 or higher of the widget callback package Wcb (written in pure Tcl/Tk code
  as well) can be used to define callbacks for the <code>activate</code>,&nbsp;
  <code>selection set</code>,&nbsp; and&nbsp; <code>selection
  clear</code>&nbsp; commands, and Wcb versions 3.0 or higher also support
  callbacks for the <code>activatecell</code>,&nbsp; <code>cellselection
  set</code>,&nbsp; and&nbsp; <code>cellselection clear</code>&nbsp;
  commands.&nbsp; The download location of Wcb is</p>

  <blockquote>
    <address>
      <a href="http://www.nemethi.de">http://www.nemethi.de</a>
    </address>
  </blockquote>

  <h3 id="ov_get">How to Get It?</h3>

  <p>Tablelist is available for free download from the same URL as Wcb.&nbsp;
  The distribution file is <code>tablelist5.16.tar.gz</code> for UNIX and
  <code>tablelist5_16.zip</code> for Windows.&nbsp; These files contain the
  same information, except for the additional carriage return character
  preceding the linefeed at the end of each line in the text files for
  Windows.</p>

  <p>Tablelist is also included in tklib, which has the address</p>

  <blockquote>
    <address>
      <a href="http://core.tcl.tk/tklib">http://core.tcl.tk/tklib</a>
    </address>
  </blockquote>

  <h3 id="ov_install">How to Install It?</h3>

  <p>Install the package as a subdirectory of one of the directories given by
  the <code>auto_path</code> variable.&nbsp; For example, you can install it as
  a directory at the same level as the Tcl and Tk script libraries.&nbsp; The
  locations of these library directories are given by the
  <code>tcl_library</code> and <code>tk_library</code> variables,
  respectively.</p>

  <p>To install Tablelist <i>on UNIX</i>, <code>cd</code> to the desired
  directory and unpack the distribution file
  <code>tablelist5.16.tar.gz</code>:</p>

  <blockquote>
    <pre>
gunzip -c tablelist5.16.tar.gz | tar -xf -
</pre>
  </blockquote>

  <p>This command will create a directory named <code>tablelist5.16</code>,
  with the subdirectories <code>demos</code>, <code>doc</code>, and
  <code>scripts</code>.</p>

  <p><i>On Windows</i>, use WinZip or some other program capable of unpacking
  the distribution file <code>tablelist5_16.zip</code> into the directory
  <code>tablelist5.16</code>, with the subdirectories <code>demos</code>,
  <code>doc</code>, and <code>scripts</code>.</p>

  <p>The file <code>tablelistEdit.tcl</code> in the <code>scripts</code>
  directory is only needed for applications making use of interactive cell
  editing.&nbsp; Similarly, the file <code>tablelistMove.tcl</code> in the same
  directory is only required for scripts invoking the <code>move</code> or
  <code>movecolumn</code> command.&nbsp; Finally, the file
  <code>tablelistThemes.tcl</code> is only needed for applications using the
  package Tablelist_tile (see next section).</p>

  <p>Next, you should check the exact version number of your Tcl/Tk
  distribution, given by the <code>tcl_patchLevel</code> and
  <code>tk_patchLevel</code> variables.&nbsp; If you are using Tcl/Tk version
  8.2.X, 8.3.0 - 8.3.2, or 8.4a1, then you should upgrade your Tcl/Tk
  distribution to a higher release.&nbsp; This is because a bug in these Tcl
  versions (fixed in Tcl 8.3.3 and 8.4a2) causes excessive memory use when
  calling&nbsp; <code>info exists</code>&nbsp; on non-existent array elements,
  and Tablelist makes a lot of invocations of this command.</p>

  <p>If for some reason you cannot upgrade your Tcl/Tk version, then you should
  execute the Tcl script <code>repair.tcl</code> in the directory
  <code>scripts</code>.&nbsp; This script makes backup copies of several files
  contained in this directory, and then creates new versions of them by
  replacing all invocations of&nbsp; <code>info exists</code>&nbsp; for array
  elements with a call to the helper procedure
  <code>arrElemExists</code>.&nbsp; The patched files work with all Tcl/Tk
  releases starting with 8.0, but the original ones have a much better
  performance.</p>

  <p>Notice that in tklib the Tablelist <code>demos</code> directory is
  replaced with the subdirectory <code>tablelist</code> of the
  <code>examples</code> directory.&nbsp; Please take this into account when
  reading the <a href="#examples">examples</a> below.</p>

  <h3 id="ov_use">How to Use It?</h3>

  <p>The Tablelist distribution provides two packages, called <b>Tablelist</b>
  and <b>Tablelist_tile</b>.&nbsp; The main difference between the two is that
  Tablelist_tile enables the tile-based, theme-specific appearance of tablelist
  widgets; this package requires Tcl/Tk 8.4 or higher and tile 0.6 or
  higher.&nbsp; It is not possible to use both packages in one and the same
  application, because both are implemented in the same <code>tablelist</code>
  namespace and provide identical commands.</p>

  <p>To be able to access the commands and variables defined in the package
  Tablelist, your scripts must contain one of the lines</p>

  <blockquote>
    <pre>
package require tablelist ?<i>version</i>?
package require Tablelist ?<i>version</i>?
</pre>
  </blockquote>

  <p>You can use either one of the two statements above because the file
  <code>tablelist.tcl</code> contains both lines</p>

  <blockquote>
    <pre>
package provide tablelist ...
package provide Tablelist ...
</pre>
  </blockquote>

  <p>Likewise, to be able to access the commands and variables defined in the
  package Tablelist_tile, your scripts must contain one of the lines</p>

  <blockquote>
    <pre>
package require tablelist_tile ?<i>version</i>?
package require Tablelist_tile ?<i>version</i>?
</pre>
  </blockquote>

  <p>Again, you can use either one of the two statements above because the file
  <code>tablelist_tile.tcl</code> contains both lines</p>

  <blockquote>
    <pre>
package provide tablelist_tile ...
package provide Tablelist_tile ...
</pre>
  </blockquote>

  <p>You are free to remove one of the above lines from
  <code>tablelist.tcl</code> and <code>tablelist_tile.tcl</code>, respectively,
  if you want to prevent the corresponding packages from making themselves
  known under two different names each.&nbsp; Of course, by doing so you
  restrict the argument of&nbsp; <code>package require</code>&nbsp; to a single
  name per package.</p>

  <p>Please note that <b>ActiveTcl versions 8.5 and later use a modified
  package mechanism, which only exports the all-lowercase names
  <code>tablelist</code> and <code>tablelist_tile</code></b>.</p>

  <p><b>REMARK:</b>&nbsp; If you have an earlier Tablelist version as part of
  ActiveTcl 8.5 or above and the new Tablelist release 5.16, then it is highly
  recommended to specify the version number <code>5.16</code> in the&nbsp;
  <code>package require</code>&nbsp; command, because otherwise the interpreter
  will load the old Tablelist version included in ActiveTcl as Tcl
  Module.&nbsp; The <a href="#examples">examples</a> below use the
  statement&nbsp; <code>package require tablelist 5.16</code>,&nbsp; and their
  tile-based counterparts invoke the command&nbsp; <code>package require
  tablelist_tile 5.16</code>.</p>

  <p>Since the packages Tablelist and Tablelist_tile are implemented in the
  <code>tablelist</code> namespace, you must either invoke the</p>

  <blockquote>
    <pre>
namespace import tablelist::<i>pattern</i> ?tablelist::<i>pattern ...</i>?
</pre>
  </blockquote>

  <p>command to import the <i>procedures</i> you need, or use qualified names
  like <code>tablelist::tablelist</code>.&nbsp; In the examples below we have
  chosen the latter approach.</p>

  <p>To access Tablelist <i>variables</i>, you <i>must</i> use qualified
  names.&nbsp; There are only 4 Tablelist variables (and one more when using
  Tablelist_tile) that are designed to be accessed outside the namespace
  <code>tablelist</code>:</p>

  <ul>
    <li>The variable <code>tablelist::version</code> holds the current version
    number of the Tablelist and Tablelist_tile packages.</li>

    <li>The variable <code>tablelist::library</code> holds the location of the
    Tablelist installation directory.</li>

    <li>The variable <code>tablelist::scalingpct</code> holds the scaling
    percentage used by Tablelist when adapting the sizes of the tree styles
    <code>vistaAero</code>, <code> vistaClassic</code>, <code>win7Aero</code>,
    <code>win7Classic</code>, and <code>win10</code> to the display's DPI
    scaling level.&nbsp; The currently supported values are <code>100</code>,
    <code>125</code>, <code>150</code>, and <code>200</code>.&nbsp; You can use
    the value of this variable, e.g., if you want to create images of different
    sizes, depending on the DPI scaling factor.&nbsp; For example, if your
    application uses images of size 16 x 16 on an unscaled display and
    <code>tablelist::scalingpct</code> has the value <code>150</code>, then the
    image size for this display should be 24 x 24.</li>

    <li>The read-only variable <code>tablelist::usingTile</code> has the value
    <code>0</code> in the package Tablelist and the value <code>1</code> in
    Tablelist_tile.</li>

    <li>In Tablelist_tile the array <code>tablelist::themeDefaults</code> holds
    the theme-specific default values of a series of Tablelist configuration
    options.</li>
  </ul>

  <h3 id="ov_tile">More on Tablelist_tile</h3>

  <p>A tablelist widget consists of a body (containing the items) and a header
  (displaying the column titles).&nbsp; Both components are contained in a
  hull, implemented as a frame.&nbsp; The header has a rather complex
  structure, consisting mainly of frame and label widgets.&nbsp; While in the
  Tablelist package all of these components are Tk widgets, the Tablelist_tile
  package uses both Tk and tile frame and label widgets.&nbsp; Due to several
  incompatibilities between Tk and tile, it is currently not possible to
  replace all Tk widgets making up a tablelist with their tile
  counterparts.</p>

  <p>From the above it follows that <b>the package Tablelist_tile will only
  work as expected if the Tk <code>frame</code> and <code>label</code> commands
  haven't been overridden by using&nbsp; <code>namespace import -force
  ttk::*</code>&nbsp; at global scope</b>.&nbsp; While earlier tile releases
  suggested using this command at global scope for the really adventurous, in
  newer tile versions this is considered a Really Bad Idea, causing many things
  to break.&nbsp; Instead, <b>you should explicitly invoke
  <code>ttk::frame</code>, <code>ttk::label</code>, etc. whenever you want to
  use a tile widget</b>.</p>

  <p><b>Overriding some other Tk widgets at global scope may be equally
  dangerous when using various widgets from the Tk core and from the packages
  BWidget, Iwidgets, combobox (by Bryan Oakley), ctext, and Mentry for
  interactive cell editing</b>, because these packages expect Tk widgets, which
  may not always be replaced by their tile counterparts.</p>

  <p>Another restriction to be taken into account is due to the fact that in
  earlier tile versions the&nbsp; <code>(ttk::)style theme use</code>&nbsp;
  command could only be used to set the current theme, but not to retrieve
  it.&nbsp; For this reason, the package Tablelist_tile makes use of the
  variable <code>ttk::currentTheme</code> or <code>tile::currentTheme</code>
  (depending on the tile version), which is set by the
  <code>ttk::setTheme</code> or <code>tile::setTheme</code> procedure.&nbsp;
  From this it follows that <b>the tile-based tablelist widgets will only have
  the expected appearance if the platform-specific default theme is either left
  unchanged or replaced with another theme by invoking the procedure
  <code>ttk::setTheme</code> or <code>tile::setTheme</code>, depending on the
  current tile version</b>.&nbsp; (See also the <code><a href=
  "tablelistThemes.html#setTheme">tablelist::setTheme</a></code> command.)</p>

  <p>After these cautions concerning the use of tile, the rest of this section
  describes the differences between the packages Tablelist and
  Tablelist_tile.</p>

  <p>The Tablelist_tile package checks whether the required Tcl, Tk, and tile
  versions are present, by executing the commands</p>

  <blockquote>
    <pre>
package require Tcl 8.4
package require Tk  8.4
if {$::tk_version &lt; 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
    package require tile 0.6
}
</pre>
  </blockquote>

  <p>The last command above reflects the fact that, beginning with Tk 8.5a6,
  tile is integrated into the Tk core and therefore it should only be loaded
  explicitly when using an earlier Tk version.</p>

  <p>Apart from this and the <code>_tile</code> suffix in the&nbsp;
  <code>package require</code>&nbsp; command, the only difference (from the
  programmer's point of view) between the packages Tablelist and Tablelist_tile
  is related to the supported configuration options:&nbsp; The
  <code>-highlightbackground</code>, <code>-highlightcolor</code>,
  <code>-highlightthickness</code>, <code>-labelbackground</code>,
  <code>-labelactivebackground</code>, <code>-labelactiveforeground</code>,
  <code>-labeldisabledforeground</code>, and <code>-labelheight</code> options
  (the latter at both widget and column levels), present in the Tablelist
  package, are not supported by Tablelist_tile.&nbsp; The first three are
  standard Tk widget options that are not available for tile widgets.&nbsp; The
  <code>-labelbackground</code> option stands for the <code>-background</code>
  option of the column labels, and current versions of the tile engine don't
  support setting the background color for these widgets with a special header
  layout.&nbsp; The remaining options stand for the
  <code>-activebackground</code>, <code>-activeforeground</code>,
  <code>-disabledforeground</code>, and <code>-height</code> options of the
  column labels, and these configuration options are not supported for tile
  label widgets.</p>

  <p>Also, take into account that in some themes, setting the
  <code>-labelborderwidth</code> option (at widget or column level) to a value
  other than the default might be ignored by tile and thus could cause
  alignment problems.&nbsp; This is because the border of tile widgets is drawn
  with theme-specific methods, which will not always produce the results known
  from Tk widgets.</p>

  <p>Finally, notice that, when using the <code>tileqt</code> theme, the
  version number of the <code>tile::theme::tileqt</code> package must be 0.4 or
  higher, and <code>tileqt</code> itself won't work with tile versions earlier
  than 0.7.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="examples">Examples</h2>

  <h3 id="ex_config">A tablelist Widget for Displaying and Editing
  Configuration Options</h3>

  <p>The file <code>config.tcl</code> in the <code>demos</code> directory
  contains a procedure <code>demo::displayConfig</code> that displays the
  configuration options of an arbitrary widget in a tablelist contained in a
  newly created top-level widget and allows you to edit these options.&nbsp;
  This procedure can prove to be quite useful during interactive GUI
  development.&nbsp; To test it, start <code>wish</code> and evaluate the file
  by using the <code>source</code> command as follows:</p>

  <ul>
    <li>If <code>wish</code> was started in the <code>demos</code> directory
    then it is sufficient to enter

      <blockquote>
        <pre>
source config.tcl
</pre>
      </blockquote>
    </li>

    <li>If <code>wish</code> was started in some other directory then you can
    use the <code>tablelist::library</code> variable to find the location of
    the file.&nbsp; For example, assuming that your Tablelist installation has
    the directory structure described in the <a href="#ov_install">How to
    install it?</a> section, the required commands are:

      <blockquote>
        <pre>
package require tablelist 5.16
source [file join $tablelist::library demos config.tcl]
</pre>
      </blockquote>
    </li>
  </ul>

  <p>In both cases, the script will print the following message to
  <code>stdout</code>:</p>

  <blockquote>
    <pre>
To display the configuration options of an arbitrary widget, enter

        demo::displayConfig &lt;widgetName&gt;
</pre>
  </blockquote>

  <p>The result looks like in the following figure:</p>

  <blockquote>
    <img src="config.png" alt="Configuration Options" width="839" height=
    "387">
  </blockquote>

  <p>It is assumed that the Tcl command associated with the widget specified by
  <code>&lt;widgetName&gt;</code> has a <code>configure</code> subcommand
  which, when invoked without any argument, returns a list describing all of
  the available configuration options for the widget, in the common format
  known from the standard Tk widgets.&nbsp; The
  <code>demo::displayConfig</code> procedure inserts the items of this list
  into a scrolled tablelist with 5 dynamic-width columns and interactive sort
  capability, and returns the name of the newly created tablelist widget:</p>

  <blockquote>
    <pre>
package require tablelist 5.16

namespace eval demo {
    #
    # Get the current windowing system ("x11", "win32", "classic", or "aqua")
    # and add some entries to the Tk option database for the following
    # widget hierarchy within a top-level widget of the class DemoTop:
    #
    # Name              Class
    # -----------------------------
    # tf                Frame
    #   tbl               Tabellist
    #   vsb, hsb          Scrollbar
    # bf                Frame
    #   b1, b2, b3        Button
    #
    variable winSys
    if {[catch {tk windowingsystem} winSys] != 0} {
        switch $::tcl_platform(platform) {
            unix        { set winSys x11 }
            windows     { set winSys win32 }
            macintosh   { set winSys classic }
        }
    }
    if {[string compare $winSys "x11"] == 0} {
        #
        # Create the font TkDefaultFont if not yet present
        #
        catch {font create TkDefaultFont -family Helvetica -size -12}

        option add *DemoTop*Font                        TkDefaultFont
        option add *DemoTop*selectBackground            #678db2
        option add *DemoTop*selectForeground            white
    } else {
        option add *DemoTop.tf.borderWidth              1
        option add *DemoTop.tf.relief                   sunken
        option add *DemoTop.tf.tbl.borderWidth          0
        option add *DemoTop.tf.tbl.highlightThickness   0
    }
    option add *DemoTop.tf.tbl.background               white
    option add *DemoTop.tf.tbl.stripeBackground         #f0f0f0
    option add *DemoTop.tf.tbl.setGrid                  yes
    option add *DemoTop.tf.tbl*Entry.background         white
    option add *DemoTop.bf.Button.width                 10
}

#------------------------------------------------------------------------------
# demo::displayConfig
#
# Displays the configuration options of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayConfig w {
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\""
        return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .configTop
    for {set n 2} {[winfo exists $top]} {incr n} {
        set top .configTop$n
    }
    toplevel $top -class DemoTop
    wm title $top "Configuration Options of the [winfo class $w] Widget \"$w\""

    #
    # Create a scrolled tablelist widget with 5 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
        -columns {0 "Command-Line Name"
                  0 "Database/Alias Name"
                  0 "Database Class"
                  0 "Default Value"
                  0 "Current Value"} \
        -labelcommand tablelist::sortByColumn -sortcommand demo::compareAsSet \
        -editendcommand demo::applyValue -height 15 -width 100 -stretch all \
        -xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set]
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }
    $tbl columnconfigure 3 -maxwidth 30
    $tbl columnconfigure 4 -maxwidth 30 -editable yes
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"     -command [list demo::putConfig $w $tbl]
    button $b2 -text "Sort as Set" -command [list $tbl sort]
    button $b3 -text "Close"       -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
        grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
        grid $vsb              -row 1 -column 1 -sticky ns
    } else {
        grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the configuration options of the given widget
    #
    putConfig $w $tbl
    return $tbl
}
</pre>
  </blockquote>

  <p>The procedure invokes the <code><a href=
  "tablelistWidget.html">tablelist::tablelist</a></code> command to create a
  tablelist widget.&nbsp; The value of the <code><a href=
  "tablelistWidget.html#columns">-columns</a></code> option passed to this
  command specifies the widths, titles, and alignments of the 5 columns.&nbsp;
  The width of each column is given as <code>0</code>, specifying that the
  column's width is to be made just large enough to hold all the elements in
  the column, including its title, which is the string following the
  width.&nbsp; We have omitted the alignment specifications (which can
  optionally follow the titles), because the columns shall all be
  left-justified.</p>

  <p>Since all columns are of dynamic width and left-aligned, instead of
  <code>-columns</code> we could have used the <code><a href=
  "tablelistWidget.html#columntitles">-columntitles</a></code> option as
  follows:</p>

  <blockquote>
    <pre>
    tablelist::tablelist $tbl \
        -columntitles {"Command-Line Name"
                       "Database/Alias Name"
                       "Database Class"
                       "Default Value"
                       "Current Value"} \
        . . .
</pre>
  </blockquote>

  <p>The command <code><a href=
  "tablelistColSort.html#sortByColumn">tablelist::sortByColumn</a></code>,
  specified as the value of the <code><a href=
  "tablelistWidget.html#labelcommand">-labelcommand</a></code> option, will be
  invoked whenever mouse button 1 is released over one of the labels.&nbsp;
  This command sorts the items based on the column corresponding to that label,
  in the right order, by invoking the <code><a href=
  "tablelistWidget.html#sortbycolumn">sortbycolumn</a></code> subcommand of the
  Tcl command associated with the tablelist widget.</p>

  <p>As seen from the creation of the button displaying the text&nbsp;
  <code>"Sort as Set"</code>,&nbsp; the items will also be sorted by invoking
  the <code><a href="tablelistWidget.html#sort">sort</a></code>
  subcommand.&nbsp; This makes it necessary to specify a command to be used for
  the comparison of the items, as the value of the <code><a href=
  "tablelistWidget.html#sortcommand">-sortcommand</a></code> option.&nbsp; In
  our example this is the <code>demo::compareAsSet</code> procedure shown
  below.</p>

  <p>The <code><a href=
  "tablelistWidget.html#editendcommand">-editendcommand</a></code> option
  specifies the command to be invoked automatically whenever the interactive
  editing of a cell's contents is finished and the final contents of the
  temporary embedded entry widget used for the editing are different from its
  original one.&nbsp; Per default, the elements of a tablelist widget can only
  be edited programmatically, but we enable the interactive editing for the
  cells of the last column with the aid of the <code><a href=
  "tablelistWidget.html#col_editable">-editable</a></code> column configuration
  option.</p>

  <p>By specifying the value <code>all</code> for the <code><a href=
  "tablelistWidget.html#stretch">-stretch</a></code> configuration option we
  make sure that all of the columns will be stretched to eliminate the blank
  space that might appear at the right of the table.</p>

  <p>If the default value of the <code>-selectborderwidth</code> option is
  <code>0</code> (this is the case on the Windows and Macintosh platforms, and
  also in an X11 envronment with Tk 8.5 or above) then we use the
  <code><a href="tablelistWidget.html#spacing">-spacing</a></code> option to
  provide some additional space above and below the rows.</p>

  <p>For the last two columns of the tablelist we use the <code><a href=
  "tablelistWidget.html#col_maxwidth">-maxwidth</a></code> column configuration
  option, to make sure that the dynamic widths of these columns won't exceed 30
  average-width characters.</p>

  <p>Besides the options given on the command line, our tablelist widget will
  automatically inherit the ones contained in the Tk option database entries
  specified in the namespace initialization preceding the
  <code>demo::displayConfig</code> procedure.&nbsp; The database name
  <code>stripeBackground</code> corresponds to the <code><a href=
  "tablelistWidget.html#stripebackground">-stripebackground</a></code>
  configuration option.&nbsp; According to this entry, every other row of the
  tablelist widget will be displayed in the background color
  <code>#f0f0f0</code>, which improves the readability of the items and gives
  the widget a nice appearance.</p>

  <p>The option database entries given for the windowing systems other than
  <code>x11</code> are implicitly used when managing the tablelist widget and
  the two scrollbars with the aid of <code>grid</code>.&nbsp; Notice how the
  <code><a href="tablelistWidget.html#cornerpath">cornerpath</a></code>
  subcommand enables us to achieve a native look &amp; feel with respect to the
  vertical scrollbar on the windowing system <code>aqua</code>.</p>

  <p>We populate the tablelist by invoking the <code>demo::putConfig</code>
  procedure discussed below.&nbsp; The same script is associated with the
  <b>Refresh</b> button, as the value of its <code>-command</code>
  configuration option.&nbsp; This procedure is implemented as follows:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::putConfig
#
# Outputs the configuration options of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putConfig {w tbl} {
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
        return ""
    }

    #
    # Display the configuration options of w in the tablelist widget tbl
    #
    $tbl delete 0 end
    foreach configSet [$w configure] {
        #
        # Insert the list configSet into the tablelist widget
        #
        $tbl insert end $configSet

        if {[llength $configSet] == 2} {
            $tbl rowconfigure end -foreground gray50 -selectforeground gray75
            $tbl cellconfigure end -editable no
        } else {
            #
            # Change the colors of the first and last cell of the row
            # if the current value is different from the default one
            #
            set default [lindex $configSet 3]
            set current [lindex $configSet 4]
            if {[string compare $default $current] != 0} {
                foreach col {0 4} {
                    $tbl cellconfigure end,$col \
                         -foreground red -selectforeground yellow
                }
            }
        }
    }

    $tbl sortbycolumn 0
    $tbl activate 0
    $tbl attrib widget $w
}
</pre>
  </blockquote>

  <p>After deleting the current items of the tablelist widget <code>tbl</code>,
  the procedure inserts the items of the list returned by the
  <code>configure</code> subcommand of the Tcl command associated with the
  widget <code>w</code>.&nbsp; For each option that is merely an abbreviated
  form of some other one, we use the <code><a href=
  "tablelistWidget.html#rowconfigure">rowconfigure</a></code> tablelist
  subcommand to change the normal and selection foreground colors of the item
  just appended, and we disable the interactive editing in the last inserted
  cell by using the <code><a href=
  "tablelistWidget.html#cell_editable">-editable</a></code> cell configuration
  option.&nbsp; The <code><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></code> tablelist
  operation is also invoked for each real option whose current value is
  different from the default one, to change the values of the
  <code>-foreground</code> and <code>-selectforeground</code> options of the
  cells no. 0 and 4, containing the command-line name of the option and its
  current value.</p>

  <p>Each tablelist widget may have any number of private <b>attributes</b>,
  which can be set and retrieved with the aid of the <code><a href=
  "tablelistWidget.html#attrib">attrib</a></code> subcommand of the Tcl command
  corresponding to the widget.&nbsp; The <code>demo::putConfig</code> procedure
  sets the <code>widget</code> attribute to the name of the widget whose
  options are displayed in the tablelist.</p>

  <p>The implementation of the comparison command
  <code>demo::compareAsSet</code> mentioned above is quite simple:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::compareAsSet
#
# Compares two items of a tablelist widget used to display the configuration
# options of an arbitrary widget.  The item in which the current value is
# different from the default one is considered to be less than the other; if
# both items fulfil this condition or its negation then string comparison is
# applied to the two option names.
#------------------------------------------------------------------------------
proc demo::compareAsSet {item1 item2} {
    foreach {opt1 dbName1 dbClass1 default1 current1} $item1 \
            {opt2 dbName2 dbClass2 default2 current2} $item2 {
        set changed1 [expr {[string compare $default1 $current1] != 0}]
        set changed2 [expr {[string compare $default2 $current2] != 0}]
        if {$changed1 == $changed2} {
            return [string compare $opt1 $opt2]
        } elseif {$changed1} {
            return -1
        } else {
            return 1
        }
    }
}
</pre>
  </blockquote>

  <p>Finally, here is the implementation of the <code>demo::applyValue</code>
  procedure, specified as the value of the <code>-editendcommand</code>
  option:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::applyValue
#
# Applies the new value of the configuraton option contained in the given row
# of the tablelist widget tbl to the widget whose options are displayed in it,
# and updates the colors of the first and last cell of the row.
#------------------------------------------------------------------------------
proc demo::applyValue {tbl row col text} {
    #
    # Try to apply the new value of the option contained in
    # the given row to the widget whose options are displayed
    # in the tablelist; reject the value if the attempt fails
    #
    set w [$tbl attrib widget]
    set opt [$tbl cellcget $row,0 -text]
    if {[catch {$w configure $opt $text} result] != 0} {
        bell
        tk_messageBox -title "Error" -icon error -message $result \
            -parent [winfo toplevel $tbl]
        $tbl rejectinput
        return ""
    }

    #
    # Replace the new option value with its canonical form and
    # update the colors of the first and last cell of the row
    #
    set text [$w cget $opt]
    set default [$tbl cellcget $row,3 -text]
    if {[string compare $default $text] == 0} {
        foreach col {0 4} {
            $tbl cellconfigure $row,$col \
                 -foreground "" -selectforeground ""
        }
    } else {
        foreach col {0 4} {
            $tbl cellconfigure $row,$col \
                 -foreground red -selectforeground yellow
        }
    }

    return $text
}
</pre>
  </blockquote>

  <p>The procedure retrieves the name of the widget whose options are displayed
  in the tablelist, as the value of its <code>widget</code> attribute, and
  invokes the <code><a href="tablelistWidget.html#cellcget">cellcget</a></code>
  tablelist subcommand to get the name of the option specified in the first
  cell of the row whose last element was just edited.&nbsp; Next, it tries to
  apply the new value of the option to the widget, and invokes the
  <code><a href="tablelistWidget.html#rejectinput">rejectinput</a></code>
  subcommand if the attempt fails.&nbsp; Otherwise it replaces the new option
  value with its canonical form and updates the normal and selection foreground
  colors of the cells no. 0 and 4.&nbsp; The canonical form of the option value
  is given by the <code>cget</code> subcommand of the Tcl command associated
  with that widget.&nbsp; For example, a boolean value will always be replaced
  with <code>1</code> or <code>0</code>, even if the entry contains the string
  <code>yes</code> or <code>no</code>.&nbsp; The procedure returns this
  canonical option value, thus making sure that the latter will become the new
  contents of the cell that was just edited.</p>

  <h3 id="ex_browse">Two Widget Browsers Based on a tablelist</h3>

  <p>The files <code>browse.tcl</code> and <code>browseTree.tcl</code> in the
  <code>demos</code> directory contain a procedure
  <code>demo::displayChildren</code> that displays information about the
  children of an arbitrary widget in a tablelist contained in a newly created
  top-level widget.&nbsp; To test it, start <code>wish</code> and evaluate the
  chosen file by using the <code>source</code> command, in a similar way as in
  the case of the <a href="#ex_config">previous example</a>.</p>

  <p>Both scripts will print the following message to <code>stdout</code>:</p>

  <blockquote>
    <pre>
To display information about the children of an arbitrary widget, enter

        demo::displayChildren &lt;widgetName&gt;
</pre>
  </blockquote>

  <p>The tablelist created by the procedure <code>demo::displayChildren</code>
  in the file <code>browse.tcl</code> is a multi-column listbox:</p>

  <blockquote>
    <img src="browse.png" alt="Widget Browser" width="609" height="289">
  </blockquote>

  <p>The tablelist created by the procedure of the same name in the file
  <code>browseTree.tcl</code> is a multi-column tree widget:</p>

  <blockquote>
    <img src="browseTree.png" alt="Widget Browser" width="627" height="289">
  </blockquote>

  <p>The <code>demo::displayChildren</code> command inserts some data of the
  children of the widget specified by <code>&lt;widgetName&gt;</code> into a
  vertically scrolled tablelist with 9 dynamic-width columns and interactive
  sort capability, and returns the name of the newly created tablelist
  widget.&nbsp; By double-clicking an item or invoking the first entry of a
  pop-up menu within the body of the tablelist, you can display the data of the
  children of the widget corresponding to the selected item, and with the
  second menu entry you can display its configuration options (see the <a href=
  "#ex_config">previous example</a> for details).&nbsp; To go one level up,
  click on the <b>Parent</b> button.</p>

  <p>There is a lot of code common to the scripts <code>browse.tcl</code> and
  <code>browseTree.tcl</code>.&nbsp; We will restrict the description below to
  the second one, which requires Tk 8.3 or later, due to the use of several
  tree-related tablelist options and subcommands.</p>

  <blockquote>
    <pre>
package require Tk 8.3
package require tablelist 5.16

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
                      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
                      -background yellow -foreground gray50]
}

source [file join $demo::dir config.tcl]

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\""
        return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
        set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
        -columns {0 "Path Name" left
                  0 "Class"     left
                  0 "X"         right
                  0 "Y"         right
                  0 "Width"     right
                  0 "Height"    right
                  0 "Mapped"    center
                  0 "Viewable"  center
                  0 "Manager"   left} \
        -expandcommand demo::expandCmd -labelcommand demo::labelCmd \
        -yscrollcommand [list $vsb set] -setgrid no -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
        $tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
        $tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
        bind $l &lt;Configure&gt; [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl &lt;Configure&gt; [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the &lt;Double-1&gt; event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
                      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
                      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag &lt;Double-1&gt;   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag &lt;&lt;Button3&gt;&gt;  [bind TablelistBody &lt;Button-1&gt;]
    bind $bodyTag &lt;&lt;Button3&gt;&gt; +[bind TablelistBody &lt;ButtonRelease-1&gt;]
    bind $bodyTag &lt;&lt;Button3&gt;&gt; +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"
    button $b2 -text "Parent"
    button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    . . .

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl root
    return $tbl
}
</pre>
  </blockquote>

  <p>The procedure invokes the <code><a href=
  "tablelistWidget.html">tablelist::tablelist</a></code> command to create a
  tablelist widget.&nbsp; The value of the <code><a href=
  "tablelistWidget.html#columns">-columns</a></code> option passed to this
  command specifies the widths, titles, and alignments of the 9 columns.&nbsp;
  The width of each column is given as <code>0</code>, specifying that the
  column's width is to be made just large enough to hold all the elements in
  the column, including its title, which is the string following the
  width.&nbsp; Each of the titles is followed by an alignment, which indicates
  how to justify both the elements and the title of the respective column.</p>

  <p>We want to display not only the data of the given widget's children, but
  also those of its further descendants.&nbsp; To this end, we need a command
  to be invoked whenever an item corresponding to a widget with children gets
  expanded.&nbsp; This command is specified as the value of the <code><a href=
  "tablelistWidget.html#expandcommand">-expandcommand</a></code> option.&nbsp;
  As discussed later, the <code>demo::expandCmd</code> procedure will insert
  the children of the row that is about to be expanded, if it has no children
  yet.</p>

  <p>The command <code>demo::labelCmd</code>, specified as the value of the
  <code><a href="tablelistWidget.html#labelcommand">-labelcommand</a></code>
  option, will be invoked whenever mouse button 1 is released over one of the
  labels.&nbsp; We will discuss this procedure later.</p>

  <p>We specify the value <code>0</code> for the widget's <code><a href=
  "tablelistWidget.html#width">-width</a></code> option, meaning that the
  tablelist's width shall be made just large enough to hold all its
  columns.</p>

  <p>After creating the tablelist widget, we make sure that the elements of its
  columns 2, 3, 4, and 5 (displaying the x and y coordinates as well as the
  widths and heights of the children) will be compared as integers when sorting
  the items based on one of these columns.&nbsp; We do this with the aid of the
  <code><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></code> tablelist
  operation.</p>

  <p>The same <code>columnconfigure</code> subcommand enables us to specify
  that, when displaying the elements of columns 6 and 7 (having the titles
  <code>"Mapped"</code> and <code>"Viewable"</code>, respectively), the boolean
  values <code>1</code> and <code>0</code> will be replaced with the strings
  <code>"yes"</code> and <code>"no"</code>, returned by the
  <code>demo::formatBoolean</code> command shown below.</p>

  <p>After creating the vertical scrollbar, we iterate over the elements of the
  list containing the path names of all header labels of the tablelist widget,
  returned by the <code><a href="tablelistWidget.html#labels">labels</a></code>
  subcommand of the Tcl command corresponding to the widget.&nbsp; For each
  element of the list, we bind the procedure
  <code>demo::updateItemsDelayed</code> to the <code>&lt;Configure&gt;</code>
  event.&nbsp; In this way we make sure the procedure will be invoked whenever
  the header label indicated by that list element changes size.</p>

  <p>The four invocations of the <code>bind</code> command following the
  creation of the pop-up menu make use of a binding tag whose name depends on
  the path name of the tablelist widget and is returned by the <code><a href=
  "tablelistWidget.html#bodytag">bodytag</a></code> subcommand of the Tcl
  command associated with the tablelist widget.&nbsp; The advantage of using
  this tag instead of the path name of the tablelist's body is that this
  binding tag is associated not only with the body but also with the separator
  frames and with the labels displaying embedded images.&nbsp; This is
  important in our example because we want to make sure the
  <code>&lt;&lt;Button3&gt;&gt;</code> and <code>&lt;Double-1&gt;</code> events
  will be handled in the same way within a label containing an embedded image
  as in the rest of the tablelist's body.&nbsp; Both the <code><a href=
  "tablelistWidget.html#button3">&lt;&lt;Button3&gt;&gt;</a></code> virtual
  event (used in the first three <code>bind</code> commands) and the
  <code><a href="tablelistWidget.html#body_bindings">TablelistBody</a></code>
  binding tag (used in the first binding script) are created by the Tablelist
  package.&nbsp; The first three <code>bind</code> commands make sure that a
  <code>&lt;&lt;Button3&gt;&gt;</code> virtual event will select and activate
  the nearest item and will post a pop-up menu with two command entries that
  refer to the widget described by that item.</p>

  <p>We populate the tablelist by invoking the <code>demo::putChildren</code>
  procedure, implemented as follows:</p>

  <blockquote id="putChildren">
    <pre>
#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl, as child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl nodeIdx} {
    . . .

    if {[string compare $nodeIdx "root"] == 0} {
        set top [winfo toplevel $tbl]
        wm title $top "Children of the [winfo class $w] Widget \"$w\""

        $tbl resetsortinfo
        $tbl delete 0 end
        set row 0
    } else {
        set row [expr {$nodeIdx + 1}]
    }

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
        #
        # Insert the data of the current child into the tablelist widget
        #
        set item {}
        lappend item \
                [winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
                [winfo width $c] [winfo height $c] [winfo ismapped $c] \
                [winfo viewable $c] [winfo manager $c]
        $tbl insertchild $nodeIdx end $item

        #
        # Insert an image into the first cell of the row; mark the
        # row as collapsed if the child widget has children itself
        #
        if {[llength [winfo children $c]] == 0} {
            $tbl cellconfigure end,0 -image $leafImg
        } else {
            $tbl cellconfigure end,0 -image $compImg
            $tbl collapse $row
        }

        $tbl rowattrib $row pathName $c
        incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
        #
        # Configure the "Refresh" and "Parent" buttons
        #
        $top.bf.b1 configure -command [list demo::refreshView $w $tbl]
        set b2 $top.bf.b2
        set p [winfo parent $w]
        if {[string compare $p ""] == 0} {
            $b2 configure -state disabled
        } else {
            $b2 configure -state normal -command \
                [list demo::putChildren $p $tbl root]
        }
    }
}
</pre>
  </blockquote>

  <p>The last argument of this procedure indicates the tree node to become the
  parent of the items displaying the data of the children of the widget passed
  as first argument.&nbsp; If this parent is the invisible <code>root</code>
  node then we first reset the sorting information by invoking the
  <code><a href="tablelistWidget.html#resetsortinfo">resetsortinfo</a></code>
  tablelist subcommand and delete the current items of the tablelist widget
  <code>tbl</code>.&nbsp; The procedure then iterates over the children of the
  specified widget and inserts the items built from some data retrieved by
  using the <code>winfo</code> command.&nbsp; Each new item is added to the end
  of the parent node's list of children with the aid of the <code><a href=
  "tablelistWidget.html#insertchildren">insertchild(ren)</a></code>
  subcommand.</p>

  <p>For each child widget, we invoke the <code><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></code> tablelist
  operation to set the value of the <code>-image</code> option of the
  corresponding row's first cell, containing the leaf name of the child.&nbsp;
  In this way, the procedure inserts the image <code>$leafImg</code> or
  <code>$compImg</code> into the first cell, depending on whether the child in
  question is a leaf or a composite widget.&nbsp; (Remember that both images
  were created outside this procedure, within the initialization of the
  <code>demo</code> namespace.)</p>

  <p>We mark every newly created row corresponding to a child widget that has
  children itself as collapsed by invoking the <code><a href=
  "tablelistWidget.html#collapse">collapse</a></code> subcommand.&nbsp; This
  will prepend an expand/collapse control to the contents of the first column,
  whose column index <code>0</code> is the default value of the <code><a href=
  "tablelistWidget.html#treecolumn">-treecolumn</a></code> configuration
  option.</p>

  <p>We use the <code><a href=
  "tablelistWidget.html#rowattrib">rowattrib</a></code> tablelist subcommand to
  remember the full path name of every child widget as a private attribute
  associated with the corresponding tablelist row, because it will be needed at
  several places later on.</p>

  <p>As mentioned above, the <code>demo::expandCmd</code> procedure will be
  invoked automatically when expanding a row that contains an expand/collapse
  control:</p>

  <blockquote>
    <pre>
------------------------------------------------------------------------------
# demo::expandCmd
#
# Outputs the data of the children of the widget whose leaf name is displayed
# in the first cell of the specified row of the tablelist widget tbl, as child
# items of the one identified by row.
#------------------------------------------------------------------------------
proc demo::expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
        set w [$tbl rowattrib $row pathName]
        putChildren $w $tbl $row

        #
        # Apply the last sorting (if any) to the new items
        #
        $tbl refreshsorting $row
    }
}
</pre>
  </blockquote>

  <p>The procedure invokes the <code><a href=
  "tablelistWidget.html#childcount">childcount</a></code> subcommand to check
  whether the children of the row that is about to be expanded have already
  been inserted into the tablelist widget, and inserts them if this is not the
  case.&nbsp; It also makes sure that the child items will be displayed in the
  order corresponding to the last sorting (if any), with the aid of the
  <code><a href="tablelistWidget.html#refreshsorting">refreshsorting</a></code>
  tablelist subcommand.&nbsp; Any sorting (if needed) will only be performed on
  the child items just inserted into the tablelist widget.</p>

  <p>The <code>demo::formatBoolean</code> and <code>demo::labelCmd</code>
  procedures mentioned above are trivial:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the contents of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sorting order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}
</pre>
  </blockquote>

  <p>The command <code><a href=
  "tablelistColSort.html#sortByColumn">tablelist::sortByColumn</a></code> sorts
  the items of the tablelist widget by the specified column in the right order,
  by invoking the <code><a href=
  "tablelistWidget.html#sortbycolumn">sortbycolumn</a></code> subcommand of the
  Tcl command associated with the tablelist widget.</p>

  <p>The implementation of the <code>demo::updateItemsDelayed</code> command,
  invoked in this procedure and already encountered in the
  <code>demo::displayChildren</code> procedure above, is quite simple:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
        $tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row &lt; $rowCount} {incr row} {
        set c [$tbl cellcget $row,0 -text]
        if {![winfo exists $c]} {
            continue
        }

        set item {}
        lappend item \
                [winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
                [winfo width $c] [winfo height $c] [winfo ismapped $c] \
                [winfo viewable $c] [winfo manager $c]
        $tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}
</pre>
  </blockquote>

  <p>As already mentioned in the <a href="#ex_config">previous example</a>,
  each tablelist widget may have any number of private attributes, which can be
  set and retrieved with the aid of the <code><a href=
  "tablelistWidget.html#attrib">attrib</a></code> subcommand of the Tcl command
  corresponding to the widget.&nbsp; The <code>afterId</code> attribute is set
  by the <code>demo::updateItemsDelayed</code> procedure when sheduling the
  <code>demo::updateItems</code> command for execution 500 ms later, but only
  if its value is an empty string.&nbsp; For this reason, the
  <code>demo::updateItems</code> procedure resets this attribute.&nbsp; It also
  makes use of the <code><a href=
  "tablelistWidget.html#cellcget">cellcget</a></code> tablelist subcommand to
  get the path names contained in the first cell of each row, and updates the
  data of the children with the aid of the <code><a href=
  "tablelistWidget.html#rowconfigure">rowconfigure</a></code> subcommand.&nbsp;
  After updating the items, the procedure repeats the most recent sorting based
  on a column (if there was one), with the aid of the <code><a href=
  "tablelistWidget.html#refreshsorting">refreshsorting</a></code>
  subcommand.</p>

  <p>The procedures <code>demo::putChildrenOfSelWidget</code>,
  <code>demo::dispConfigOfSelWidget</code>, and
  <code>demo::postPopupMenu</code> (see <code>demo::displayChildren</code>) are
  also straight-forward.&nbsp; For example, the
  <code>demo::putChildrenOfSelWidget</code> command shown below makes use of
  the <code><a href="tablelistWidget.html#curselection">curselection</a></code>
  subcommand to get the index of the selected row.&nbsp; More precisely,
  <code>curselection</code> returns a list, but in our case this list will have
  exactly one element, hence it can be used directly as the first component of
  a cell index.</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
        return ""
    }

    if {[llength [winfo children $w]] == 0} {
        bell
    } else {
        putChildren $w $tbl
    }
}
</pre>
  </blockquote>

  <p>The procedure <code>demo::refreshView</code>, associated with the
  <b>Refresh</b> button, is implemented as follows:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::refreshView
#
# Redisplays the data of the children of the widget w in the tablelist widget
# tbl and restores the expanded states of the items as well as the vertical
# view.
#------------------------------------------------------------------------------
proc demo::refreshView {w tbl} {
    #
    # Save the vertical view and get the path names of
    # the child widgets displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
        set pathName [$tbl rowattrib $key pathName]
        set expandedWidgets($pathName) 1
    }

    #
    # Redisplay the data of the widget's (possibly changed) children and
    # restore the expanded states of the children, along with the vertical view
    #
    putChildren $w $tbl root
    restoreExpandedStates $tbl root expandedWidgets
    $tbl yview moveto [lindex $yView 0]
}
</pre>
  </blockquote>

  <p>Before redisplaying the tablelist's contents via
  <code>demo::putChildren</code>, we get the full keys of the currently
  expanded items with the aid of the <code><a href=
  "tablelistWidget.html#expandedkeys">expandedkeys</a></code> tablelist
  subcommand and insert the correspondig widget paths into the array
  <code>expandedWidgets</code>.&nbsp; After redisplaying the data of the
  (possibly changed) children of the widget given as first argument, we pass
  this array to the <code>demo::restoreExpandedStates</code> procedure shown
  below:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# restoreExpandedStates
#
# Expands those children of the parent identified by nodeIdx that display the
# data of child widgets whose path names are the names of the elements of the
# array specified by the last argument.
#------------------------------------------------------------------------------
proc demo::restoreExpandedStates {tbl nodeIdx expandedWidgetsName} {
    upvar $expandedWidgetsName expandedWidgets

    foreach key [$tbl childkeys $nodeIdx] {
        set pathName [$tbl rowattrib $key pathName]
        if {[info exists expandedWidgets($pathName)]} {
            $tbl expand $key -partly
            restoreExpandedStates $tbl $key expandedWidgets
        }
    }
}
</pre>
  </blockquote>

  <p>The procedure retrieves the list of full keys of the children of the
  parent node indicated by <code>nodeIdx</code>, by means of the <code><a href=
  "tablelistWidget.html#childkeys">childkeys</a></code> tablelist
  subcommand.&nbsp; It then loops over this list, and for each key for which
  the corresponding row was previously expanded, it invokes the <code><a href=
  "tablelistWidget.html#expand">expand</a></code> tablelist subcommand and then
  calls itself recursively to restore the expanded states of that row's
  children.</p>

  <h3 id="ex_dirViewer">A Directory Viewer Based on a tablelist</h3>

  <p>The script <code>dirViewer.tcl</code> in the <code>demos</code> directory
  displays the contents of the volumes mounted on the system (e.g., the root
  <code>/</code> on UNIX and the local drives on Windows) in a tablelist used
  as multi-column tree widget:</p>

  <blockquote>
    <img src="dirViewer.png" alt="Directory Viewer" width="679" height="438">
  </blockquote>

  <p>By double-clicking an item or invoking the single entry of a pop-up menu
  within the body of the tablelist, you can display the contents of the folder
  corresponding to the selected item.&nbsp; To go one level up, click on the
  <b>Parent</b> button.</p>

  <p>There are a lot of similarities between this script and the one discussed
  in the <a href="#ex_browse">previous section</a>.&nbsp; In the following we
  will only present a few procedures that invoke tablelist commands not
  encountered in the examples above:</p>

  <blockquote>
    <pre>
package require Tk 8.3
package require tablelist 5.16

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create three images
#
image create photo clsdFolderImg -file [file join $dir clsdFolder.gif]
image create photo openFolderImg -file [file join $dir openFolder.gif]
image create photo fileImg       -file [file join $dir file.gif]

#------------------------------------------------------------------------------
# displayContents
#
# Displays the contents of the directory dir in a tablelist widget.
#------------------------------------------------------------------------------
proc displayContents dir {
    #
    # Create a scrolled tablelist widget with 3 dynamic-
    # width columns and interactive sort capability
    #
    set tf .tf
    frame $tf -class ScrollArea
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
        -columns {0 "Name"          left
                  0 "Size"          right
                  0 "Date Modified" left} \
        -expandcommand expandCmd -collapsecommand collapseCmd \
        -xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] \
        -movablecolumns no -setgrid no -showseparators yes -height 20 -width 80
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }
    $tbl columnconfigure 0 -formatcommand formatString -sortmode dictionary
    $tbl columnconfigure 1 -formatcommand formatSize -sortmode integer
    $tbl columnconfigure 2 -formatcommand formatString
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    . . .

    #
    # Populate the tablelist with the contents of the given directory
    #
    $tbl sortbycolumn 0
    putContents $dir $tbl root
}
</pre>
  </blockquote>

  <p>The procedure <code>displayContents</code> creates the tablelist widget
  and the two scrollbars as children of a frame of class
  <code>ScrollArea</code>.&nbsp; For this class, the file
  <code>option.tcl</code>, <code>source</code>d into the main script, contains
  some look &amp; feel related settings similar to the ones encountered in our
  <a href="#ex_config">first example</a>:</p>

  <blockquote>
    <pre>
if {[string compare $winSys "x11"] == 0} {
    . . .
} else {
    option add *ScrollArea.borderWidth                  1
    option add *ScrollArea.relief                       sunken
    option add *ScrollArea.Tablelist.borderWidth        0
    option add *ScrollArea.Tablelist.highlightThickness 0
    . . .
}
</pre>
  </blockquote>

  <p>The procedure specifies a value not only for the <code><a href=
  "tablelistWidget.html#expandcommand">-expandcommand</a></code> option of the
  tablelist it creates, but also for its <code><a href=
  "tablelistWidget.html#collapsecommand">-collapsecommand</a></code>
  option.&nbsp; The latter will merely restore the image shown in the first
  column to the one displaying a closed folder (see below).</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# putContents
#
# Outputs the contents of the directory dir into the tablelist widget tbl, as
# child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc putContents {dir tbl nodeIdx} {
    . . .

    if {[string compare $nodeIdx "root"] == 0} {
        if {[string compare $dir ""] == 0} {
            if {[llength [file volumes]] == 1} {
                wm title . "Contents of the File System"
            } else {
                wm title . "Contents of the File Systems"
            }
        } else {
            wm title . "Contents of the Directory \"[file nativename $dir]\""
        }

        $tbl delete 0 end
        set row 0
    } else {
        set row [expr {$nodeIdx + 1}]
    }

    #
    # Build a list from the data of the subdirectories and
    # files of the directory dir.  Prepend a "D" or "F" to
    # each entry's name and modification date &amp; time, for
    # sorting purposes (it will be removed by formatString).
    #
    set itemList {}
    if {[string compare $dir ""] == 0} {
        foreach volume [file volumes] {
            lappend itemList [list D[file nativename $volume] -1 D $volume]
        }
    } else {
        foreach entry [glob -nocomplain -types {d f} -directory $dir *] {
            if {[catch {file mtime $entry} modTime] != 0} {
                continue
            }

            if {[file isdirectory $entry]} {
                lappend itemList [list D[file tail $entry] -1 \
                    D[clock format $modTime -format "%Y-%m-%d %H:%M"] $entry]
            } else {
                lappend itemList [list F[file tail $entry] [file size $entry] \
                    F[clock format $modTime -format "%Y-%m-%d %H:%M"] ""]
            }
        }
    }

    #
    # Sort the above list and insert it into the tablelist widget
    # tbl as list of children of the row identified by nodeIdx
    #
    set itemList [$tbl applysorting $itemList]
    $tbl insertchildlist $nodeIdx end $itemList

    #
    # Insert an image into the first cell of each newly inserted row
    #
    foreach item $itemList {
        set name [lindex $item end]
        if {[string compare $name ""] == 0} {                   ;# file
            $tbl cellconfigure $row,0 -image fileImg
        } else {                                                ;# directory
            $tbl cellconfigure $row,0 -image clsdFolderImg
            $tbl rowattrib $row pathName $name

            #
            # Mark the row as collapsed if the directory is non-empty
            #
            if {[file readable $name] &amp;&amp; [llength \
                [glob -nocomplain -types {d f} -directory $name *]] != 0} {
                $tbl collapse $row
            }
        }

        incr row
    }

    . . .
}
</pre>
  </blockquote>

  <p>The main difference between the procedure <code>putContents</code> above
  and the procedure <code><a href="#putChildren">demo::putChildren</a></code>
  described in the <a href="#ex_browse">previous section</a> is related to the
  way child items are inserted into the tablelist widget.&nbsp; Instead of
  inserting them individually with the aid of the <code><a href=
  "tablelistWidget.html#insertchildren">insertchild(ren)</a></code> tablelist
  subcommand, here we add the relevant data to a list of items and then invoke
  the much more performant <code><a href=
  "tablelistWidget.html#insertchildlist">insertchildlist</a></code>
  subcommand.&nbsp; Also, instead of first inserting the items and then sorting
  them via <code><a href=
  "tablelistWidget.html#refreshsorting">refreshsorting</a></code>, we first
  perform the necessary sortings on the above-mentioned list of items by
  invoking the <code><a href=
  "tablelistWidget.html#applysorting">applysorting</a></code> subcommand.&nbsp;
  Again, this is much faster than sorting the already inserted child items.</p>

  <p>This procedure also illustrates an effective technique based on the
  <code><a href=
  "tablelistWidget.html#col_formatcommand">-formatcommand</a></code> column
  configuration option:&nbsp; In the tablelist widget's internal list, the
  names and modification times of the directories and files are preceded by a
  <code>D</code> and <code>F</code>, respectively.&nbsp; This makes sure that
  the directories will sort before the files (when sorting in ascending
  order).&nbsp; When displaying the items, the Tablelist code will
  automatically invoke the <code>formatString</code> procedure, which removes
  the first character.&nbsp; Similarly, in the widget's internal list, the size
  of a directory is set to <code>-1</code>, which sorts before the sizes of the
  files.&nbsp; The <code>formatSize</code> procedure, invoked automatically
  when displaying the items, replaces this value with an empty string:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# formatString
#
# Returns the substring obtained from the specified value by removing its first
# character.
#------------------------------------------------------------------------------
proc formatString val {
    return [string range $val 1 end]
}

#------------------------------------------------------------------------------
# formatSize
#
# Returns an empty string if the specified value is negative and the value
# itself in user-friendly format otherwise.
#------------------------------------------------------------------------------
proc formatSize val {
    if {$val &lt; 0} {
        return ""
    } elseif {$val &lt; 1024} {
        return "$val bytes"
    } elseif {$val &lt; 1048576} {
        return [format "%.1f KB" [expr {$val / 1024.0}]]
    } elseif {$val &lt; 1073741824} {
        return [format "%.1f MB" [expr {$val / 1048576.0}]]
    } else {
        return [format "%.1f GB" [expr {$val / 1073741824.0}]]
    }
}
</pre>
  </blockquote>

  <p>Besides its common task of inserting the children of the row to be
  expanded, the <code>expandCmd</code> procedure shown below also changes the
  image contained in the first column to the one displaying an open
  folder.&nbsp; The <code>collapseCmd</code> procedure restores the image to
  the one displaying a closed folder:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# expandCmd
#
# Outputs the contents of the directory whose leaf name is displayed in the
# first cell of the specified row of the tablelist widget tbl, as child items
# of the one identified by row, and updates the image displayed in that cell.
#------------------------------------------------------------------------------
proc expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
        set dir [$tbl rowattrib $row pathName]
        putContents $dir $tbl $row
    }

    if {[$tbl childcount $row] != 0} {
        $tbl cellconfigure $row,0 -image openFolderImg
    }
}

#------------------------------------------------------------------------------
# collapseCmd
#
# Updates the image displayed in the first cell of the specified row of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc collapseCmd {tbl row} {
    $tbl cellconfigure $row,0 -image clsdFolderImg
}

. . .

displayContents ""
</pre>
  </blockquote>

  <p>The last line of the script invokes the procedure
  <code>displayContents</code> with an empty string as argument, i.e., displays
  the volumes mounted on the system.</p>

  <h3 id="ex_styles">Improving the Look &amp; Feel of a tablelist Widget</h3>

  <p>The script <code>styles.tcl</code> in the <code>demos</code> directory
  demonstrates some ways of making tablelist widgets smarter and improving the
  readability of their items.&nbsp; It creates 8 tablelist widgets, shown in
  the following figure:</p>

  <blockquote>
    <img src="styles.png" alt="Styles" width="700" height="497">
  </blockquote>

  <p>Here is the relevant code segment:</p>

  <blockquote>
    <pre>
#
# Create, configure, and populate 8 tablelist widgets
#
frame .f
for {set n 0} { $n &lt; 8} {incr n} {
    set tbl .f.tbl$n
    tablelist::tablelist $tbl \
        -columntitles {"Label 0" "Label 1" "Label 2" "Label 3"} \
        -background white -height 4 -width 40 -stretch all
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }

    switch $n {
        1 {
            $tbl configure -showseparators yes
        }
        2 {
            $tbl configure -stripebackground #f0f0f0
        }
        3 {
            $tbl configure -stripebackground #f0f0f0 -showseparators yes
        }
        4 {
            $tbl columnconfigure 1 -background LightYellow
            $tbl columnconfigure 3 -background LightCyan
        }
        5 {
            $tbl configure -showseparators yes
            $tbl columnconfigure 1 -background LightYellow
            $tbl columnconfigure 3 -background LightCyan
        }
        6 {
            $tbl configure -stripebackground #f0f0f0
            $tbl columnconfigure 1 -background LightYellow \
                -stripebackground #f0f0d2
            $tbl columnconfigure 3 -background LightCyan \
                -stripebackground #d2f0f0
        }
        7 {
            $tbl configure -stripebackground #f0f0f0 -showseparators yes
            $tbl columnconfigure 1 -background LightYellow \
                -stripebackground #f0f0d2
            $tbl columnconfigure 3 -background LightCyan \
                -stripebackground #d2f0f0
        }
    }

    foreach row {0 1 2 3} {
        $tbl insert end \
             [list "Cell $row,0" "Cell $row,1" "Cell $row,2" "Cell $row,3"]
    }
}
</pre>
  </blockquote>

  <p>The only configuration option used here but not discussed in the first
  three examples (although already encountered in the <a href=
  "#ex_dirViewer">previous one</a>) is <code><a href=
  "tablelistWidget.html#showseparators">-showseparators</a></code>.&nbsp; The
  visual effect it produces looks nice both by itself and combined with
  horizontal or vertical stripes, created by using the <code><a href=
  "tablelistWidget.html#stripebackground">-stripebackground</a></code> option
  and the <code><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></code> subcommand,
  respectively.</p>

  <h3 id="ex_editing">Advanced Interactive tablelist Cell Editing</h3>

  <p>The scripts <code>tileWidgets.tcl</code>, <code>bwidget.tcl</code>,
  <code>iwidgets.tcl</code>, and <code>miscWidgets.tcl</code> in the
  <code>demos</code> directory create a tablelist widget displaying some
  parameters of 16 serial lines, and demonstrate how to use various widgets
  from the Tk core and from the packages tile, BWidget, Iwidgets, combobox (by
  Bryan Oakley), ctext, and Mentry (or Mentry_tile) for interactive cell
  editing.&nbsp; The following figure shows the tablelist widget, together with
  a BWidget ComboBox used to edit the contents of one of its cells:</p>

  <blockquote>
    <img src="bwidget.png" alt="Serial Line Configuration" width="843" height=
    "391">
  </blockquote>

  <p>Here is the relevant code segment from the script <code>bwidget.tcl</code>
  (the scripts <code>tileWidgets.tcl</code>, <code>iwidgets.tcl</code>, and
  <code>miscWidgets.tcl</code> are similar):</p>

  <blockquote>
    <pre>
package require Tk 8.4                          ;# because of "-compound"
package require tablelist 5.16
package require BWidget

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*Checkbutton.background            white
option add *Tablelist*Checkbutton.activeBackground      white
option add *Tablelist*Entry.background                  white

#
# Register some widgets from the BWidget package for interactive cell editing
#
tablelist::addBWidgetEntry
tablelist::addBWidgetSpinBox
tablelist::addBWidgetComboBox

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow Entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow ComboBox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow SpinBox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow ComboBox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow ComboBox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow ComboBox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow Entry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow Entry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date &amp; time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i &lt; 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i &lt; 8}] "Line $n" 9600 8 None 1 XON/XOFF \
        $clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i &lt; 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
</pre>
  </blockquote>

  <p>We invoke the <code><a href=
  "tablelistBWidget.html#Entry">tablelist::addBWidgetEntry</a></code>,
  <code><a href=
  "tablelistBWidget.html#SpinBox">tablelist::addBWidgetSpinBox</a></code>, and
  <code><a href=
  "tablelistBWidget.html#ComboBox">tablelist::addBWidgetComboBox</a></code>
  commands to register the Entry, SpinBox, and ComboBox widgets from the
  BWidget package for interactive cell editing.&nbsp; These commands return the
  values <code>"Entry"</code>, <code>"SpinBox"</code>, and
  <code>"ComboBox"</code>, respectively, which we then use in the
  <code><a href="tablelistWidget.html#col_editwindow">-editwindow</a></code>
  column configuration option to set the edit window for the columns no. 2,
  ..., 10.&nbsp; In columns no. 1 and 10 we use the Tk core checkbutton and
  menubutton widgets, which are automatically registered for interactive cell
  editing.</p>

  <p>Notice the use of the <code><a href=
  "tablelistWidget.html#col_name">-name</a></code> column configuration option,
  which allows us to access the columns by their names instead of by numerical
  column indices.&nbsp; This is important, because the file
  <code>option.tcl</code>, which is <code>source</code>d into the main script,
  contains the line</p>

  <blockquote>
    <pre>
option add *Tablelist.movableColumns    yes
</pre>
  </blockquote>

  <p>The <code>editStartCmd</code> and <code>editEndCmd</code> procedures shown
  below use the <code><a href=
  "tablelistWidget.html#columncget">columncget</a></code> subcommand to
  retrieve the name of the column from the numerical column index.</p>

  <p>By the way, two further option database settings contained in the file
  <code>option.tcl</code> are:</p>

  <blockquote>
    <pre>
option add *Tablelist.labelCommand      tablelist::sortByColumn
option add *Tablelist.labelCommand2     tablelist::addToSortColumns
</pre>
  </blockquote>

  <p>The <code><a href=
  "tablelistColSort.html#sortByColumn">tablelist::sortByColumn</a></code> and
  <code><a href=
  "tablelistColSort.html#addToSortColumns">tablelist::addToSortColumns</a></code>
  commands specified in these settings enable the user to sort the items by one
  or more columns, with the aid of the left mouse button and of the
  <code>Shift</code> key.</p>

  <p>The <code>editStartCmd</code> procedure, specified as the value of the
  <code><a href=
  "tablelistWidget.html#editstartcommand">-editstartcommand</a></code>
  configuration option, needs the path name of the edit window, in order to be
  able to configure the widget in various ways.&nbsp; This is a common
  situation, and Tablelist provides the <code><a href=
  "tablelistWidget.html#editwinpath">editwinpath</a></code> subcommand for this
  purpose:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# 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] &lt;= 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] &lt;= 6 &amp;&amp; [regexp {^[0-9]*$} %S]}}
        }

        dataBits {
            #
            # Configure the SpinBox
            #
            $w configure -range {5 8 1} -editable no
        }

        parity {
            #
            # Populate the ComboBox and make it non-editable
            #
            $w configure -values {None Even Odd Mark Space} -editable no
        }

        . . .

        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
}
</pre>
  </blockquote>

  <p>The <code>editEndCmd</code> procedure, specified as the value of the
  <code><a href=
  "tablelistWidget.html#editendcommand">-editendcommand</a></code>
  configuration option, is responsible for a final validation of the edit
  window's text.&nbsp; Another purpose of this command is to convert the text
  contained in the edit window to the cell's new <i>internal</i> contents,
  which is necessary because the internal value of the activation date and time
  is a clock value in seconds:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# editEndCmd
#
# Performs a final validation of the text contained in the edit window and gets
# the cell's internal contents.
#------------------------------------------------------------------------------
proc editEndCmd {tbl row col text} {
    switch [$tbl columncget $col -name] {
        available {
            #
            # Update the image contained in the cell
            #
            set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
            $tbl cellconfigure $row,$col -image $img
        }

        baudRate {
            #
            # Check whether the baud rate is an integer in the range 50..921600
            #
            if {![regexp {^[0-9]+$} $text] || $text &lt; 50 || $text &gt; 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 &lt;= [clock seconds]} {
                bell
                tk_messageBox -title "Error" -icon error -message \
                    "The activation date &amp; time must be in the future"
                $tbl rejectinput
            } else {
                $tbl cellconfigure $row,actTime -text $actClock
                return $actClock
            }
        }

        . . .

        color {
            #
            # Update the image contained in the cell
            #
            $tbl cellconfigure $row,$col -image img$::colors($text)
        }
    }

    return $text
}
</pre>
  </blockquote>

  <p>As mentioned above, the scripts <code>tileWidgets.tcl</code>,
  <code>iwidgets.tcl</code>, and <code>miscWidgets.tcl</code> are similar to
  <code>bwidget.tcl</code>.&nbsp; The first one makes use of the tile entry,
  spinbox, combobox, checkbutton, and menubutton widgets.&nbsp; The second one
  uses (besides the Tk core checkbutton and menubutton) the entryfield,
  spinint, combobox, dateentry, and timeentry widgets from the Iwidgets package
  and the validation facilities specific to that library.&nbsp; The third
  script makes use of the entry, spinbox, checkbutton, and menubutton widgets
  from the Tk core, Bryan Oakley's combobox, and of the mentry widgets of type
  <code>"Date"</code> and <code>"Time"</code>, and it performs the entry
  validation with the aid of the Wcb package (which is required anyway for the
  Mentry library).</p>

  <h3 id="ex_windows">A tablelist Widget Containing Embedded Windows</h3>

  <p>The script <code>embeddedWindows.tcl</code> in the <code>demos</code>
  directory creates a tablelist widget whose items correspond to the Tk library
  scripts.&nbsp; The size of each file (in bytes) is not only displayed as a
  number, but is also illustrated with the aid of a frame with red background,
  created as a child of an embedded frame with ivory background.&nbsp; The
  files can be viewed by clicking on the corresponding embedded button
  widgets.</p>

  <p>The following screenshot shows the tablelist widget with the mouse cursor
  over the first header label, causing this label to appear in
  <code>active</code> state:</p>

  <blockquote>
    <img src="embeddedWindows.png" alt="Embedded Windows" width="436" height=
    "290">
  </blockquote>

  <p>First, we create and populate the tablelist widget:</p>

  <blockquote>
    <pre>
package require tablelist 5.16

wm title . "Tk Library Scripts"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create the font TkFixedFont if not yet present
#
catch {font create TkFixedFont -family Courier -size -12}

#
# Create an image to be displayed in buttons embedded in a tablelist widget
#
image create photo openImg -file [file join $dir open.gif]

#
# Create a vertically scrolled tablelist widget with 5
# dynamic-width columns and interactive sort capability
#
set tf .tf
frame $tf -class ScrollArea
set tbl $tf.tbl
set vsb $tf.vsb
tablelist::tablelist $tbl \
    -columns {0 "File Name" left
              0 "Bar Chart" center
              0 "File Size" right
              0 "View"      center
              0 "Seen"      center} \
    -setgrid no -yscrollcommand [list $vsb set] -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -name fileName
$tbl columnconfigure 1 -formatcommand emptyStr -sortmode integer
$tbl columnconfigure 2 -name fileSize -sortmode integer
$tbl columnconfigure 4 -name seen
scrollbar $vsb -orient vertical -command [list $tbl yview]

proc emptyStr val { return "" }

eval font create BoldFont [font actual [$tbl cget -font]] -weight bold

#
# Populate the tablelist widget
#
cd $tk_library
set maxFileSize 0
foreach fileName [lsort [glob *.tcl]] {
    set fileSize [file size $fileName]
    $tbl insert end [list $fileName $fileSize $fileSize "" no]

    if {$fileSize &gt; $maxFileSize} {
        set maxFileSize $fileSize
    }
}
</pre>
  </blockquote>

  <p>We insert the size of each file not only into the column with the
  title&nbsp; <code>"File Size"</code>&nbsp;, but also into the column&nbsp;
  <code>"Bar Chart"</code>.&nbsp; Since we configured this column with&nbsp;
  <code>-formatcommand emptyStr</code>,&nbsp; the text will remain hidden in
  it.&nbsp; It will, however, be needed when sorting the items by that
  column.</p>

  <p>To be able to create the embedded windows, we have first to implement the
  creation scripts for them, as specified in the description of the
  <code><a href="tablelistWidget.html#cell_window">-window</a></code> cell
  configuration option.&nbsp; Here is the script that creates a frame to be
  embedded into the column displaying the bar chart:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# createFrame
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget tbl, as well as a child frame representing the size of the
# file whose name is diplayed in the first column of the cell's row.
#------------------------------------------------------------------------------
proc createFrame {tbl row col w} {
    #
    # Create the frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w -width 102 -height 14 -background ivory -borderwidth 1 \
             -relief solid
    bindtags $w [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Create the child frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w.f -height 12 -background red -borderwidth 1 -relief raised
    bindtags $w.f [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Manage the child frame
    #
    set fileSize [$tbl cellcget $row,fileSize -text]
    place $w.f -relwidth [expr {double($fileSize) / $::maxFileSize}]
}
</pre>
  </blockquote>

  <p>Since the frame will be embedded into the tablelist's body, we want to
  have the same handling of the mouse events in the frame and in its child
  frame as in the rest of the tablelist's body.&nbsp; To this end we replace
  the binding tag <code>Frame</code> (which has no own bindings anyway) with
  <code><a href="tablelistWidget.html#body_bindings">TablelistBody</a></code>,
  thus making sure that the default binding scripts associated with that tag
  will be valid for the parent frame and its child, too.</p>

  <p>We <code>place</code> the red child frame within its parent using the
  <code>-relwidth</code> option, to make sure that its width will remain
  proportional to the size of the corresponding file when resizing the parent
  frame (which will happen when resizing its column, as seen below).</p>

  <p>The creation script for the buttons used for viewing the Tk library files
  is quite simple:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# createButton
#
# Creates a button widget w to be embedded into the specified cell of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc createButton {tbl row col w} {
    set key [$tbl getkeys $row]
    button $w -image openImg -highlightthickness 0 -takefocus 0 \
              -command [list viewFile $tbl $key]
}

#------------------------------------------------------------------------------
# viewFile
#
# Displays the contents of the file whose name is contained in the row with the
# given key of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc viewFile {tbl key} {
    set top .top$key
    if {[winfo exists $top]} {
        raise $top
        return ""
    }

    toplevel $top
    set fileName [$tbl cellcget k$key,fileName -text]
    wm title $top "File \"$fileName\""

    #
    # Create a vertically scrolled text widget as a grandchild of the toplevel
    #
    set tf $top.tf
    frame $tf -class ScrollArea
    set txt $tf.txt
    set vsb $tf.vsb
    text $txt -background white -font TkFixedFont -setgrid yes \
              -yscrollcommand [list $vsb set]
    catch {$txt configure -tabstyle wordprocessor}      ;# for Tk 8.5 and above
    scrollbar $vsb -orient vertical -command [list $txt yview]

    #
    # Insert the file's contents into the text widget
    #
    set chan [open $fileName]
    $txt insert end [read $chan]
    close $chan

    . . .

    #
    # Mark the file as seen
    #
    $tbl rowconfigure k$key -font BoldFont
    $tbl cellconfigure k$key,seen -text yes
}
</pre>
  </blockquote>

  <p>Each file will be displayed in a text widget contained in a top-level
  whose name is <code>.top$key</code>, where <code>$key</code> is obtained with
  the aid of the <code><a href=
  "tablelistWidget.html#getkeys">getkeys</a></code> subcommand.&nbsp; By using
  the key instead of the row number, we will have a unique name for the
  top-level, even if the order of the items changes due to interactive sorting
  by a column.&nbsp; (Remember that the embedded windows will be destroyed and
  automatically recreated when sorting the items or moving the columns.)</p>

  <p>Having implemented the creation scripts for the frames and buttons, we can
  now use the <code><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></code> subcommand to
  effectively create these widgets as embedded windows.&nbsp; Notice the
  <code><a href=
  "tablelistWidget.html#cell_stretchwindow">-stretchwindow</a></code> option
  used for the embedded frames, to make sure that their width will be adapted
  to that of the containing column when the latter is being resized
  interactively.</p>

  <blockquote>
    <pre>
#
# Create embedded windows in the columns no. 1 and 3
#
set rowCount [$tbl size]
for {set row 0} {$row &lt; $rowCount} {incr row} {
    $tbl cellconfigure $row,1 -window createFrame -stretchwindow yes
    $tbl cellconfigure $row,3 -window createButton
}
</pre>
  </blockquote>

  <h3 id="ex_tile">Tile-Based Demo Scripts</h3>

  <p>The Tablelist distribution contains also tile-based counterparts of the
  demo scripts discussed above.&nbsp; As described in the <a href=
  "#ov_tile">More on Tablelist_tile</a> section of this tutorial, it is quite
  easy to port an application using the Tablelist package to one based on
  Tablelist_tile.&nbsp; For example, let's see how to transform the demo script
  <code><a href="#ex_editing">bwidget.tcl</a></code> into a tile-based one,
  called <code>bwidget_tile.tcl</code>.&nbsp; The changes are shown below in
  <span>red</span> color:</p>

  <p>First, we replace the starting lines</p>

  <blockquote>
    <pre>
package require Tk 8.3                          ;# because of entry validation
package require tablelist 5.16
</pre>
  </blockquote>

  <p>with</p>

  <blockquote>
    <pre>
package require tablelist<span>_tile</span> 5.16
</pre>
  </blockquote>

  <p>and the command</p>

  <blockquote>
    <pre>
source [file join $dir option.tcl]
</pre>
  </blockquote>

  <p>with</p>

  <blockquote>
    <pre>
source [file join $dir option<span>_tile</span>.tcl]
</pre>
  </blockquote>

  <p>To ensure that the overall appearance of the GUI will conform to the
  currently used theme, we create a theme-specific container for our
  widgets:</p>

  <blockquote>
    <pre>
<span>#
# Improve the window's appearance by using a tile
# frame as a container for the other widgets
#
set f [ttk::frame .f]</span>
</pre>
  </blockquote>

  <p>This implies that we have to replace the statement</p>

  <blockquote>
    <pre>
set tbl .tbl
</pre>
  </blockquote>

  <p>defining the path name of our tablelist widget with</p>

  <blockquote>
    <pre>
set tbl <span>$f</span>.tbl
</pre>
  </blockquote>

  <p>Similarly, instead of a Tk button created by the command</p>

  <blockquote>
    <pre>
set btn [button .btn -text "Close" -command exit]
</pre>
  </blockquote>

  <p>we use a tile button that is a child of the above tile frame:</p>

  <blockquote>
    <pre>
set btn [<span>ttk::</span>button <span>$f</span>.btn -text "Close" -command exit]
</pre>
  </blockquote>

  <p>We manage this frame in the usual manner:</p>

  <blockquote>
    <pre>
<span>pack $f -expand yes -fill both</span>
</pre>
  </blockquote>

  <p>The script <code>option_tile.tcl</code> is nearly identical to
  <code>option.tcl</code>.&nbsp; Its tile-specific part uses the values written
  by the command <code><a href=
  "tablelistThemes.html#setThemeDefaults">tablelist::setThemeDefaults</a></code>
  into the array <code>tablelist::themeDefaults</code>, to make sure that the
  selection will have the same theme-specific look in all the widgets created
  by the application:</p>

  <blockquote>
    <pre>
<span>tablelist::setThemeDefaults
if {[tablelist::getCurrentTheme] eq "aqua"} {
    option add *Listbox.selectBackground \
               $tablelist::themeDefaults(-selectbackground)
    option add *Listbox.selectForeground \
               $tablelist::themeDefaults(-selectforeground)
} else {
    option add *selectBackground  $tablelist::themeDefaults(-selectbackground)
    option add *selectForeground  $tablelist::themeDefaults(-selectforeground)
}
option add *selectBorderWidth     $tablelist::themeDefaults(-selectborderwidth)</span>
</pre>
  </blockquote>

  <p>The demo script <code>tileWidgets.tcl</code> uses not only the
  Tablelist_tile package for creating a tablelist widget with a modern
  theme-specific look &amp; feel, but also the tile entry, spinbox, combobox,
  checkbutton, and menubutoon widgets for interactive cell editing.&nbsp; The
  resulting window has a nice theme-specific appearance:</p>

  <blockquote>
    <img src="tileWidgets.png" alt="Serial Line Configuration" width="841"
    height="386">
  </blockquote>

  <p>The tile-based version of the demo script <code><a href=
  "#ex_windows">embeddedWindows.tcl</a></code> contains a bit more changes, but
  most of them are not Tablelist-specific.&nbsp; Please take a look at the file
  <code>embeddedWindows_tile.tcl</code> in the <code>demos</code> directory for
  the details.&nbsp; Here is a screenshot of the resulting window:</p>

  <blockquote>
    <img src="embeddedWindows_tile.png" alt="Embedded Windows" width="434"
    height="284">
  </blockquote>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistBWidget.html.

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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the BWidget Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, BWidget">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the BWidget Package</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#Entry">The <code><b>tablelist::addBWidgetEntry</b></code>
    Command</a></li>

    <li><a href="#SpinBox">The <code><b>tablelist::addBWidgetSpinBox</b></code>
    Command</a></li>

    <li><a href="#ComboBox">The
    <code><b>tablelist::addBWidgetComboBox</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The BWidget package is a library extension for Tcl/Tk versions 8.1.1 or
  higher, written in pure Tcl/Tk code.&nbsp; Its download location is</p>

  <blockquote>
    <address>
      <a href=
      "http://sourceforge.net/projects/tcllib/files">http://sourceforge.net/projects/tcllib/files</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the Entry,
  SpinBox, and ComboBox widgets from the BWidget package.&nbsp; The steps
  needed for using one of these widgets for editing the cells of a given column
  are as follows:</p>

  <ol>
    <li>Register the desired widget for interactive cell editing by invoking
    one of the commands described in this reference page.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="Entry">The <code><b>tablelist::addBWidgetEntry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addBWidgetEntry</code> &ndash; Register the Entry
    widget from the BWidget package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addBWidgetEntry</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the Entry widget from the BWidget package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the Entry widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>Entry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, BWidget, Entry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="SpinBox">The <code><b>tablelist::addBWidgetSpinBox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addBWidgetSpinBox</code> &ndash; Register the SpinBox
    widget from the BWidget package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addBWidgetSpinBox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the SpinBox widget from the BWidget package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the SpinBox widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>SpinBox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded SpinBox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the SpinBox non-editable or define
    validations for it, as well as for setting its (range of) values and its
    <code><b>-wrap</b></code> option.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, BWidget, SpinBox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="ComboBox">The <code><b>tablelist::addBWidgetComboBox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addBWidgetComboBox</code> &ndash; Register the
    ComboBox widget from the BWidget package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addBWidgetComboBox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the ComboBox widget from the BWidget package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the ComboBox widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ComboBox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded ComboBox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the ComboBox non-editable or define
    validations for it, as well as for populating its listbox component (with
    the aid of the ComboBox widget's <code><b>-values</b></code> option).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, BWidget, ComboBox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistBinding.html.

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
<html>
<head>
  <title>Helper Commands Used in Tablelist Binding Scripts</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, binding script">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Helper Commands Used in Tablelist Binding Scripts</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#convEventFields">The
    <code><b>tablelist::convEventFields</b></code> Command</a></li>

    <li><a href="#getTablelistPath">The
    <code><b>tablelist::getTablelistPath</b></code> Command</a></li>

    <li><a href="#getTablelistColumn">The
    <code><b>tablelist::getTablelistColumn</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The commands described in this reference page are designed to be used in
  binding scripts associated with the binding tags whose names are returned by
  the <code><b><a href="tablelistWidget.html#bodytag">bodytag</a></b></code>
  and <code><b><a href="tablelistWidget.html#labeltag">labeltag</a></b></code>
  subcommands of the Tcl command associated with a tablelist widget.&nbsp; The
  first two of these commands are also used in the default binding scripts
  associated with the binding tag <code><b>TablelistBody</b></code>.&nbsp; For
  details and examples see the sections <a href=
  "tablelistWidget.html#body_bindings">DEFAULT AND INDIVIDUAL BINDINGS FOR THE
  TABLELIST BODY</a> and <a href="tablelistWidget.html#label_bindings">DEFAULT
  AND INDIVIDUAL BINDINGS FOR THE HEADER LABELS</a>.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="convEventFields">The <code><b>tablelist::convEventFields</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::convEventFields</code> &ndash; Convert event fields
    relative to a descendant of a tablelist widget</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::convEventFields</b> <i>descendantPathName</i> <i>x</i> <i>y</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command gets the path name of a tablelist widget and the x and y
    coordinates relative to the latter from the path name
    <code><i>descendantPathName</i></code> of one of its descendants and from
    the x and y coordinates <code><i>x</i></code>, <code><i>y</i></code>
    relative to this descendant.&nbsp; The command returns these values as the
    components of a list consisting of three elements.</dd>

    <dd class="tm">
      In a binding script, the descendant widget corresponds to the event field
      <code><b>%W</b></code>, which can be the tablelist's body, one of the
      separator frames, a label widget displaying an embedded image, or (a
      descendant of) an embedded window.&nbsp; It can also be a header label or
      an additional widget placed by Tablelist into a header label for
      displaying a header image or a sort arrow.&nbsp; Likewise, the arguments
      <code><i>x</i></code> and <code><i>y</i></code> correspond to the event
      fields <code><b>%x</b></code> and <code><b>%y</b></code>.&nbsp; The three
      elements of the list returned by the command are usually assigned to the
      help variables <code><b>tablelist::W</b></code>,
      <code><b>tablelist::x</b></code>, and <code><b>tablelist::y</b></code>,
      by using the statement

      <blockquote>
        <pre>
foreach {tablelist::W tablelist::x tablelist::y} \
    [tablelist::convEventFields %W %x %y] {}
</pre>
      </blockquote>
    </dd>

    <dt><b>KEYWORDS</b></dt>

    <dd>tablelist, event fields, binding script</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getTablelistPath">The <code><b>tablelist::getTablelistPath</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getTablelistPath</code> &ndash; Get the path name of a
    tablelist widget from the path name of one of its descendants</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getTablelistPath</b> <i>descendantPathName</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command gets the path name of a tablelist widget from the path
    name <code><i>descendantPathName</i></code> of one of its descendants.</dd>

    <dd class="tm">In a binding script, the descendant widget corresponds to
    the event field <code><b>%W</b></code>, which can be the tablelist's body,
    one of the separator frames, a label widget displaying an embedded image,
    or (a descendant of) an embedded window.&nbsp; It can also be a header
    label or an additional widget placed by Tablelist into a header label for
    displaying a header image or a sort arrow.&nbsp; The return value is often
    assigned to the help variable <code><b>tablelist::W</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, path name, binding script</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getTablelistColumn">The
  <code><b>tablelist::getTablelistColumn</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getTablelistColumn</code> &ndash; Get the column
    number from the path name of a tablelist header label</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getTablelistColumn</b> <i>headerLabelPathName</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command gets the column number from the path name
    <code><i>headerLabelPathName</i></code> of a tablelist header label or of
    an additional widget placed by Tablelist into a header label for displaying
    a header image or a sort arrow.</dd>

    <dd class="tm">In a binding script, the command argument corresponds to the
    event field <code><b>%W</b></code>.&nbsp; The return value is often
    assigned to the help variable <code><b>tablelist::col</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, path name, binding script</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistColSort.html.

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
<html>
<head>
  <title>Commands for Interactive Sorting by One or More Columns</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, sort, column, widget">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Commands for Interactive Sorting by One or More Columns</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#sortByColumn">The <code><b>tablelist::sortByColumn</b></code>
    Command</a></li>

    <li><a href="#addToSortColumns">The
    <code><b>tablelist::addToSortColumns</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The commands described in this reference page enable the user to sort the
  items of a tablelist widget based on one or more of its columns, with the aid
  of the left mouse button.</p>

  <p>If the <code><b><a href=
  "#sortByColumn">tablelist::sortByColumn</a></b></code> command was specified
  as the value of the <code><b><a href=
  "tablelistWidget.html#labelcommand">-labelcommand</a></b></code>
  configuration option, then by pressing mouse button 1 over one of the header
  labels and later releasing it over the same label, the items will be sorted
  based on the elements of the corresponding column.</p>

  <p>If the <code><b><a href=
  "#addToSortColumns">tablelist::addToSortColumns</a></b></code> command was
  specified as the value of the <code><b><a href=
  "tablelistWidget.html#labelcommand2">-labelcommand2</a></b></code>
  configuration option, then by pressing mouse button 1 together with the
  <code>Shift</code> key over one of the header labels and later releasing it
  over the same label, the corresponding column will be appended to the list of
  sort columns, or (if it was already contained in that list) the corresponding
  sort order will be toggled; in both cases, the items will be sorted based on
  the updated lists of sort columns and sort orders.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="sortByColumn">The <code><b>tablelist::sortByColumn</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::sortByColumn</code> &ndash; Sort the items of a
    tablelist widget based on one of its columns</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::sortByColumn</b> <i>pathName</i> <i>columnIndex</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command sorts the items of the <a href=
    "tablelistWidget.html">tablelist</a> widget <code><i>pathName</i></code>
    based on the elements of the column specified by
    <code><i>columnIndex</i></code>.&nbsp; This is done by invoking the
    <code><b><a href=
    "tablelistWidget.html#sortbycolumn">sortbycolumn</a></b></code> subcommand
    of the Tcl command associated with the given tablelist widget.&nbsp; If the
    items were last sorted in increasing order, based on the same column given
    by <code><i>columnIndex</i></code>, and no subsequent invocation of the
    <code><b><a href=
    "tablelistWidget.html#resetsortinfo">resetsortinfo</a></b></code>
    subcommand was made, then the last argument passed to
    <code><b>sortbycolumn</b></code> will be <code><b>-decreasing</b></code>,
    otherwise <code><b>-increasing</b></code>.</dd>

    <dd class="tm">After sorting the items, the virtual event
    <code><b>&lt;&lt;TablelistColumnSorted&gt;&gt;</b></code> is
    generated.&nbsp; For Tk versions 8.5 or higher, this virtual event is
    generated with its <code><b>-data</b></code> option set to a list
    consisting of the numerical column index and the sort order
    (<code><b>decreasing</b></code> or <code><b>increasing</b></code>).&nbsp;
    The command returns the sort order, as <code><b>decreasing</b></code> or
    <code><b>increasing</b></code>.</dd>

    <dd class="tm">If the specified column's <code><b><a href=
    "tablelistWidget.html#col_showlinenumbers">-showlinenumbers</a></b></code>
    option has been set to true, then the actions described above are not
    performed and the return value is an empty string.</dd>

    <dd class="tm"><code><b>tablelist::sortByColumn</b></code> is usually
    specified as the value of the <code><b><a href=
    "tablelistWidget.html#labelcommand">-labelcommand</a></b></code>
    configuration option for a tablelist widget.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, sort, column, widget</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="addToSortColumns">The <code><b>tablelist::addToSortColumns</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addToSortColumns</code> &ndash; Add a column index to
    the list of sort columns and perform the multi-column sorting</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addToSortColumns</b> <i>pathName</i> <i>columnIndex</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command adds the column index specified by
    <code><i>columnIndex</i></code> to the list of sort columns of the <a href=
    "tablelistWidget.html">tablelist</a> widget <code><i>pathName</i></code>
    and sorts the items based on the elements of the columns indicated by the
    modified list.&nbsp; This is done by invoking the <code><b><a href=
    "tablelistWidget.html#sortbycolumnlist">sortbycolumnlist</a></b></code>
    subcommand of the Tcl command associated with the given tablelist
    widget.&nbsp; The two arguments passed to
    <code><b>sortbycolumnlist</b></code> are built as follows: (a) if the given
    column index is already contained in the widget's list of sort columns
    (returned by the <code><b><a href=
    "tablelistWidget.html#sortcolumnlist">sortcolumnlist</a></b></code>
    subcommand) then this list is left unchanged and the sort order list
    (returned by the <code><b><a href=
    "tablelistWidget.html#sortorderlist">sortorderlist</a></b></code>
    subcommand) is updated by toggling its corresponding element from
    <code><b>increasing</b></code> to <code><b>decreasing</b></code> and
    vice-versa; (b) otherwise the column index is appended to the list of sort
    columns and the value <code><b>increasing</b></code> is appended to the
    list of sort orders.</dd>

    <dd class="tm">After sorting the items by passing the two updated lists to
    the <code><b>sortbycolumnlist</b></code> subcommand, the virtual event
    <code><b>&lt;&lt;TablelistColumnsSorted&gt;&gt;</b></code> (note the plural
    form!) is generated.&nbsp; For Tk versions 8.5 or higher, this virtual
    event is generated with its <code><b>-data</b></code> option set to a list
    consisting of the two above-mentioned updated lists passed to
    <code><b>sortbycolumnlist</b></code> as arguments.&nbsp; The command
    returns the new sort order corresponding to the given column, as
    <code><b>decreasing</b></code> or <code><b>increasing</b></code>.</dd>

    <dd class="tm">If the specified column's <code><b><a href=
    "tablelistWidget.html#col_showlinenumbers">-showlinenumbers</a></b></code>
    option has been set to true, then the actions described above are not
    performed and the return value is an empty string.</dd>

    <dd class="tm"><code><b>tablelist::addToSortColumns</b></code> is usually
    specified as the value of the <code><b><a href=
    "tablelistWidget.html#labelcommand2">-labelcommand2</a></b></code>
    configuration option for a tablelist widget.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, sort, column list, widget</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistCombobox.html.

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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the combobox Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, combobox">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the combobox Package</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#combobox">The
    <code><b>tablelist::addOakleyCombobox</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>Bryan Oakley's combobox package is a library extension for Tcl/Tk versions
  8.0 or higher, written in pure Tcl/Tk code.&nbsp; Its download location
  is</p>

  <blockquote>
    <address>
      <a href=
      "http://www1.clearlight.com/~oakley/tcl/combobox">http://www1.clearlight.com/~oakley/tcl/combobox</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the combobox
  widget implemented in the package mentioned above.&nbsp; The steps needed for
  using this widget for editing the cells of a given column are as follows:</p>

  <ol>
    <li>Register the combobox widget for interactive cell editing by invoking
    the <code><b><a href=
    "#combobox">tablelist::addOakleyCombobox</a></b></code> command described
    below.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="combobox">The <code><b>tablelist::addOakleyCombobox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addOakleyCombobox</code> &ndash; Register Bryan
    Oakley's combobox widget for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addOakleyCombobox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers Bryan Oakley's combobox widget for interactive
    cell editing in tablelist widgets.&nbsp; The optional argument specifies
    the name to be used for the combobox widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>combobox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded combobox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the combobox non-editable or define
    validations for its entry child (whose path name can be obtained by
    invoking the tablelist widget's <code><b><a href=
    "tablelistWidget.html#entrypath">entrypath</a></b></code> subcommand, or by
    appending <code><b>.entry</b></code> to the path name of the combobox
    widget, or, if using combobox version 2.3 or later, with the aid of the
    combobox widget's&nbsp; <code><b>subwidget entry</b></code>&nbsp;
    subcommand), as well as for populating its listbox component (by using the
    combobox widget's&nbsp; <code><b>list insert</b></code>&nbsp;
    subcommand).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, combobox</dd>
  </dl>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistCtext.html.

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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the ctext Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, ctext">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the ctext Package</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#ctext">The <code><b>tablelist::addCtext</b></code>
    Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>George Peter Staplin's ctext package is a library extension for Tcl/Tk
  versions 8.0 or higher, written in pure Tcl/Tk code.&nbsp; It is part of
  tklib, which has the address</p>

  <blockquote>
    <address>
      <a href="http://core.tcl.tk/tklib">http://core.tcl.tk/tklib</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the ctext
  widget implemented in the package mentioned above.&nbsp; The steps needed for
  using this widget for editing the cells of a given column are as follows:</p>

  <ol>
    <li>Register the ctext widget for interactive cell editing by invoking the
    <code><b><a href="#ctext">tablelist::addCtext</a></b></code> command
    described below.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="ctext">The <code><b>tablelist::addCtext</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addCtext</code> &ndash; Register the ctext widget for
    interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addCtext</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the ctext widget for interactive cell editing in
    tablelist widgets.&nbsp; The optional argument specifies the name to be
    used for the ctext widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ctext</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded ctext widget used for interactive
    cell editing will be created with its <code><b>-padx</b></code> and
    <code><b>-pady</b></code> options set to <code>2</code>, its
    <code><b>-wrap</b></code> option set to <code><b>none</b></code>, and its
    initial height set to the number of lines contained in it.&nbsp; There is,
    however, an exception from this rule:&nbsp; If the <code><b><a href=
    "tablelistWidget.html#col_wrap">-wrap</a></b></code> option of the cell's
    column was set to true and Tk version 8.5 or higher is being used, then the
    ctext widget's <code><b>-wrap</b></code> option will be set to
    <code><b>word</b></code> and its initial height will equal the number of
    <i>display</i> lines (taking into account the line wraps) contained in
    it.&nbsp; You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to override the initial settings according
    to your needs.</dd>

    <dd class="tm">If the ctext widget's <code><b>-wrap</b></code> option was
    set to <code><b>word</b></code> or <code><b>char</b></code> (either by
    Tablelist or from within the above-mentioned script) and Tk version 8.5 or
    higher is being used, then, whenever its width changes (e.g., due to
    interactive column resizing), its height will be set automatically to the
    number of display lines contained in it.&nbsp; (The number of display lines
    is retrieved with the aid of the&nbsp; <code><b>count
    -displaylines</b></code>&nbsp; ctext widget subcommand, introduced in Tk
    8.5.)</dd>

    <dd class="tm">If the widget callback package Wcb was loaded into the
    interpreter (via&nbsp; <code><b>package require Wcb</b></code>&nbsp;
    or&nbsp; <code><b>package require wcb</b></code>)&nbsp; then the ctext
    widget's height will be updated automatically whenever text is inserted
    into or deleted from it, which makes the editing much more
    user-friendly.&nbsp; This is achieved by using an appropriately defined
    after-<code><b>insert</b></code> and after-<code><b>delete</b></code>
    callback for the edit window.&nbsp; You can use the script corresponding to
    the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define further callbacks for the ctext
    widget.&nbsp; (The above-mentioned callback is created via
    <code><b>wcb::cbappend</b></code>, <i>after</i> returning from that
    script.)</dd>

    <dd class="tm">The <code>Tab</code> key is reserved for navigation between
    the editable cells, but the user can insert a tabulator character into the
    ctext widget by pressing <code>Control-i</code>.</dd>

    <dd class="tm">Unlike in the case of the other widgets used for interactive
    cell editing (except the Tk core text widget), the <code>Return</code> and
    <code>KP_Enter</code> keys insert a newline character into the ctext
    widget.&nbsp; <code>Control-j</code> can also be used for inserting a
    newline.&nbsp; <code>Control-Return</code> and
    <code>Control-KP_Enter</code> terminate the editing and destroy the edit
    window.</dd>

    <dd class="tm"><code>Control-Home</code> and <code>Control-End</code> have
    their well-known text widget-specific bindings, just like
    <code>Meta-&lt;</code> and <code>Meta-&gt;</code> if
    <code><b>tk_strictMotif</b></code> is false.&nbsp; Again, this is different
    from the behavior of the other widgets used for interactive cell editing
    (except the Tk core text widget).&nbsp; For jumping into the first/last
    editable cell, the user can press
    <code>Alt-Home</code>/<code>Alt-End</code> or
    <code>Meta-Home</code>/<code>Meta-End</code>
    (<code>Command-Home</code>/<code>Command-End</code> on Mac OS Classic and
    Mac OS X Aqua).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, ctext</dd>
  </dl>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistIwidgets.html.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the Iwidgets Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, Iwidgets">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the Iwidgets Package</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#entryfield">The
    <code><b>tablelist::addIncrEntryfield</b></code> Command</a></li>

    <li><a href="#dateTime">The
    <code><b>tablelist::addIncrDateTimeWidget</b></code> Command</a></li>

    <li><a href="#spinner">The <code><b>tablelist::addIncrSpinner</b></code>
    Command</a></li>

    <li><a href="#spinint">The <code><b>tablelist::addIncrSpinint</b></code>
    Command</a></li>

    <li><a href="#combobox">The <code><b>tablelist::addIncrCombobox</b></code>
    Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The Iwidgets package (also known as [incr Widgets]) is a library extension
  for Tcl/Tk versions 8.0 or higher, written in pure Tcl/Tk code.&nbsp; It
  requires the compiled packages Itcl and Itk (also known as [incr Tcl] and
  [incr Tk], respectively).&nbsp; The download location of these three library
  packages is</p>

  <blockquote>
    <address>
      <a href=
      "http://sourceforge.net/projects/incrtcl/files">http://sourceforge.net/projects/incrtcl/files</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the
  entryfield, datefield, dateentry, timefield, timeentry, spinner, spinint, and
  combobox widgets from the Iwidgets package.&nbsp; The steps needed for using
  one of these widgets for editing the cells of a given column are as
  follows:</p>

  <ol>
    <li>Register the desired widget for interactive cell editing by invoking
    one of the commands described in this reference page.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="entryfield">The <code><b>tablelist::addIncrEntryfield</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrEntryfield</code> &ndash; Register the
    entryfield widget from the Iwidgets package for interactive cell
    editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrEntryfield</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the entryfield widget from the Iwidgets package
    for interactive cell editing in tablelist widgets.&nbsp; The optional
    argument specifies the name to be used for the entryfield widget as the
    value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>entryfield</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, entryfield</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="dateTime">The <code><b>tablelist::addIncrDateTimeWidget</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrDateTimeWidget</code> &ndash; Register the
    datefield, dateentry, timefield, or timeentry widget from the Iwidgets
    package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrDateTimeWidget</b> <b>datefield</b>|<b>dateentry</b>|<b>timefield</b>|<b>timeentry</b> ?<b>-seconds</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the datefield, dateentry, timefield, or
    timeentry widget from the Iwidgets package for interactive cell editing in
    tablelist widgets.&nbsp; If the <code><b>-seconds</b></code> argument is
    present then the <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the contents of the embedded window used for interactive cell
    editing as an integer clock value (in seconds), otherwise as a
    string.&nbsp; Use this option for tablelist widgets whose internal list
    contains date or time information in seconds (displayed with the aid of
    commands given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The second optional argument specifies
    the name to be used for the datefield, dateentry, timefield, or timeentry
    widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>datefield</b></code>, <code><b>dateentry</b></code>,
    <code><b>timefield</b></code>, or <code><b>timeentry</b></code>, as given
    by the first argument.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">When editing a cell with the aid of the temporary embedded
    datefield, dateentry, timefield, or timeentry widget associated with the
    above <code><i>name</i></code>, you can use the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any of the widget's options, like
    <code><b>-gmt</b></code>, <code><b>-iq</b></code>, <code><b>-int</b></code>
    ("international" date format, supported by datefield and dateentry
    widgets), or <code><b>-format</b></code> (for timefield and timeentry
    widgets, with the values <code><b>civilian</b></code> and
    <code><b>military</b></code>).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, datefield, dateentry, timefield,
    timeentry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinner">The <code><b>tablelist::addIncrSpinner</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrSpinner</code> &ndash; Register the spinner
    widget from the Iwidgets package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrSpinner</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the spinner widget from the Iwidgets package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the spinner widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>spinner</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">When editing a cell with the aid of the temporary embedded
    spinner widget associated with the above <code><i>name</i></code>, you can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define validations for the widget or set
    any of its other options, like <code><b>-decrement</b></code> and
    <code><b>-increment</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, spinner</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinint">The <code><b>tablelist::addIncrSpinint</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrSpinint</code> &ndash; Register the spinint
    widget from the Iwidgets package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrSpinint</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the spinint widget from the Iwidgets package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the spinint widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>spinint</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">When editing a cell with the aid of the temporary embedded
    spinint widget associated with the above <code><i>name</i></code>, you can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define validations for the widget or set
    any of its other options, like <code><b>-range</b></code>,
    <code><b>-step</b></code>, and <code><b>-wrap</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, spinint</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="combobox">The <code><b>tablelist::addIncrCombobox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrCombobox</code> &ndash; Register the combobox
    widget from the Iwidgets package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrCombobox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the dropdown-style combobox widget from the
    Iwidgets package for interactive cell editing in tablelist widgets.&nbsp;
    The optional argument specifies the name to be used for the combobox widget
    as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>combobox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded combobox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the combobox non-editable or define
    validations for it, as well as for populating its listbox component (by
    using the combobox widget's&nbsp; <code><b>insert list</b></code>&nbsp;
    subcommand).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, combobox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistMentry.html.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the Mentry Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, Mentry">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the Mentry Package</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#Date">The <code><b>tablelist::addDateMentry</b></code>
    Command</a></li>

    <li><a href="#Time">The <code><b>tablelist::addTimeMentry</b></code>
    Command</a></li>

    <li><a href="#DateTime">The
    <code><b>tablelist::addDateTimeMentry</b></code> Command</a></li>

    <li><a href="#FixedPoint">The
    <code><b>tablelist::addFixedPointMentry</b></code> Command</a></li>

    <li><a href="#IPAddr">The <code><b>tablelist::addIPAddrMentry</b></code>
    Command</a></li>

    <li><a href="#IPv6Addr">The
    <code><b>tablelist::addIPv6AddrMentry</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The multi-entry package Mentry is a library extension for Tcl/Tk versions
  8.0 or higher, written in pure Tcl/Tk code.&nbsp; Its download location
  is</p>

  <blockquote>
    <address>
      <a href="http://www.nemethi.de">http://www.nemethi.de</a>
    </address>
  </blockquote>

  <p>Starting with version 3.0, the Mentry distribution provides not only the
  package Mentry, but also its tile-based equivalent Mentry_tile, which enables
  the theme-specific appearance of mentry widgets; this package requires Tcl/Tk
  8.4 or higher and tile 0.6 or higher.</p>

  <p>Tablelist supports interactive cell editing with the aid of the mentry
  widgets of type <code>"Date"</code>, <code>"Time"</code>,
  <code>"DateTime</code>, <code>"FixedPoint"</code>, <code>"IPAddr"</code>, and
  <code>"IPv6Addr"</code>.&nbsp; The steps needed for using one of these
  widgets for editing the cells of a given column are as follows:</p>

  <ol>
    <li>Register the desired widget for interactive cell editing by invoking
    one of the commands described in this reference page.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="Date">The <code><b>tablelist::addDateMentry</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addDateMentry</code> &ndash; Register the mentry
    widget of type <code>"Date"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addDateMentry</b> <i>format separator</i> ?<b>-gmt</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::dateMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>format</i></code> and
    <code><i>separator</i></code> arguments have the same meanings as in the
    <code><b>mentry::dateMentry</b></code> command.&nbsp; If the
    <code><b>-gmt</b></code> argument is present then both the internal clock
    value and its external date representation in the mentry widget will be
    viewed as Greenwich Mean Time, otherwise as local time.&nbsp; The second
    optional argument specifies the name to be used for the mentry widget as
    the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>dateMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain as
    internal cell values date information in seconds (displayed with the aid of
    a command given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the contents of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getClockVal</b></code>
    command.&nbsp; The value returned by this command (a clock value in seconds
    or one of the error strings <code>"EMPTY"</code>, <code>"BAD"</code>,
    <code>"BAD_DATE"</code>, or <code>"BAD_YEAR"</code>) will be passed to the
    script corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is one of the above error strings then the script should reject
    the mentry's contents by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, date</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="Time">The <code><b>tablelist::addTimeMentry</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addTimeMentry</code> &ndash; Register the mentry
    widget of type <code>"Time"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addTimeMentry</b> <i>format separator</i> ?<b>-gmt</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::timeMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>format</i></code> and
    <code><i>separator</i></code> arguments have the same meanings as in the
    <code><b>mentry::timeMentry</b></code> command.&nbsp; If the
    <code><b>-gmt</b></code> argument is present then both the internal clock
    value and its external time representation in the mentry widget will be
    viewed as Greenwich Mean Time, otherwise as local time.&nbsp; The second
    optional argument specifies the name to be used for the mentry widget as
    the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>timeMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain as
    internal cell values time information in seconds (displayed with the aid of
    a command given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the contents of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getClockVal</b></code>
    command.&nbsp; The value returned by this command (a clock value in seconds
    or one of the error strings <code>"EMPTY"</code> or <code>"BAD"</code>)
    will be passed to the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is one of the above error strings then the script should reject
    the mentry's contents by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, time</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="DateTime">The <code><b>tablelist::addDateTimeMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addDateTimeMentry</code> &ndash; Register the mentry
    widget of type <code>"DateTime"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addDateTimeMentry</b> <i>format dateSeparator timeSeparator</i> ?<b>-gmt</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::dateTimeMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>format</i></code>,
    <code><i>dateSeparator</i></code>, and <code><i>timeSeparator</i></code>
    arguments have the same meanings as in the
    <code><b>mentry::dateTimeMentry</b></code> command.&nbsp; If the
    <code><b>-gmt</b></code> argument is present then both the internal clock
    value and its external date &amp; time representation in the mentry widget
    will be viewed as Greenwich Mean Time, otherwise as local time.&nbsp; The
    second optional argument specifies the name to be used for the mentry
    widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>dateTimeMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain as
    internal cell values date &amp; time information in seconds (displayed with
    the aid of a command given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the contents of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getClockVal</b></code>
    command.&nbsp; The value returned by this command (a clock value in seconds
    or one of the error strings <code>"EMPTY"</code>, <code>"BAD"</code>,
    <code>"BAD_DATE"</code>, or <code>"BAD_YEAR"</code>) will be passed to the
    script corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is one of the above error strings then the script should reject
    the mentry's contents by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, date, time</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="FixedPoint">The <code><b>tablelist::addFixedPointMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addFixedPointMentry</code> &ndash; Register the mentry
    widget of type <code>"FixedPoint"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addFixedPointMentry</b> <i>count1 count2</i> ?<b>-comma</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::fixedPointMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>count1</i></code>, <code><i>count2</i></code>,
    and <code><i>-comma</i></code> arguments have the same meanings as in the
    <code><b>mentry::fixedPointMentry</b></code> command.&nbsp; The second
    optional argument specifies the name to be used for the mentry widget as
    the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>fixedPointMentry_</b><i>count1</i><b>.</b><i>count2</i></code>
    (e.g., <code><b>fixedPointMentry_6.2</b></code>) or
    <code><b>fixedPointMentry_</b><i>count1</i><b>,</b><i>count2</i></code>
    (e.g., <code><b>fixedPointMentry_6,2</b></code>), depending on the presence
    of the optional <code><b>-comma</b></code> argument.&nbsp; The command
    returns its <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain
    real numbers as internal cell values.&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the contents of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getReal</b></code> command.&nbsp;
    The value returned by this command (a real number or the error string
    <code>"EMPTY"</code>) will be passed to the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is the above error string then the script should reject the
    mentry's contents by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, real number</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="IPAddr">The <code><b>tablelist::addIPAddrMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIPAddrMentry</code> &ndash; Register the mentry
    widget of type <code>"IPAddr"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIPAddrMentry</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::ipAddrMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The optional argument specifies the name to be used for the
    mentry widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ipAddrMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain IP
    addresses as internal cell values.&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the contents of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getIPAddr</b></code>
    command.&nbsp; The value returned by this command (an IP address or the
    error string <code>"EMPTY"</code>) will be passed to the script
    corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is the above error string then the script should reject the
    mentry's contents by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, IP address</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="IPv6Addr">The <code><b>tablelist::addIPv6AddrMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIPv6AddrMentry</code> &ndash; Register the mentry
    widget of type <code>"IPv6Addr"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIPv6AddrMentry</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::ipv6AddrMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The optional argument specifies the name to be used for the
    mentry widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ipv6AddrMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain
    IPv6 addresses as internal cell values.&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the contents of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getIPv6Addr</b></code>
    command.&nbsp; The value returned by this command (an IPv6 address or the
    error string <code>"EMPTY"</code>) will be passed to the script
    corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is the above error string then the script should reject the
    mentry's contents by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, IPv6 address</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistThemes.html.

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
<html>
<head>
  <title>Commands Related to Tile Themes</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, theme, tile">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Commands Related to Tile Themes</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#setTheme">The <code><b>tablelist::setTheme</b></code>
    Command</a></li>

    <li><a href="#getCurrentTheme">The
    <code><b>tablelist::getCurrentTheme</b></code> Command</a></li>

    <li><a href="#getThemes">The <code><b>tablelist::getThemes</b></code>
    Command</a></li>

    <li><a href="#setThemeDefaults">The
    <code><b>tablelist::setThemeDefaults</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The commands described in this reference page should only be invoked when
  using the package Tablelist_tile.&nbsp; They enable you to set and query the
  current theme, to retrieve a list of the available themes, and to make sure
  that your widgets will have a theme-specific appearance.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="setTheme">The <code><b>tablelist::setTheme</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::setTheme</code> &ndash; Set the current theme</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::setTheme</b> <i>theme</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command sets the current theme to <code><i>theme</i></code>,
    loading it if necessary.&nbsp; It is simply an alias for
    <code><b>ttk::setTheme</b></code> or <code><b>tile::setTheme</b></code>,
    depending on the tile version loaded into the interpreter.&nbsp; (The
    <code><b>tile::setTheme</b></code> command was renamed to
    <code><b>ttk::setTheme</b></code> in tile version 0.8.)</dd>

    <dd class="tm">Being just an alias for a tile library procedure, the
    <code><b>tablelist::setTheme</b></code> command does exactly the same as
    the original one: It loads the package implementing the given theme if
    needed, sets the theme to the specified one, and saves the latter in the
    variable <code><b>ttk::currentTheme</b></code> or
    <code><b>tile::currentTheme</b></code>, depending on the current tile
    version.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getCurrentTheme">The <code><b>tablelist::getCurrentTheme</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getCurrentTheme</code> &ndash; Get the current
    theme</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getCurrentTheme</b>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command returns the value of the variable
    <code><b>ttk::currentTheme</b></code> or
    <code><b>tile::currentTheme</b></code>, depending on the tile version
    loaded into the interpreter.&nbsp; (The namespace containing the variable
    <code><b>currentTheme</b></code> was changed in tile version 0.8 from
    <code><b>tile</b></code> to <code><b>ttk</b></code>.)</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getThemes">The <code><b>tablelist::getThemes</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getThemes</code> &ndash; Get the themes registered in
    the package database</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getThemes</b>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command returns a list of the themes registered in the package
    database.&nbsp; It is simply an alias for <code><b>ttk::themes</b></code>
    or <code><b>tile::availableThemes</b></code>, depending on the tile version
    loaded into the interpreter.&nbsp; (The
    <code><b>tile::availableThemes</b></code> command was renamed to
    <code><b>ttk::themes</b></code> in tile version 0.8.)</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="setThemeDefaults"><code><b>tablelist::setThemeDefaults</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::setThemeDefaults</code> &ndash; Set theme-specific
    default values of some tablelist configuration options</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::setThemeDefaults</b>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command populates the array
    <code><b>tablelist::themeDefaults</b></code> with theme-specific default
    values of a series of Tablelist configuration options.&nbsp; The array
    names are the command-line names of the options, and the corresponding
    array values are the default values of these configuration options for the
    currently set tile theme.</dd>

    <dd class="tm">The options whose names and values are written into the
    array <code><b>tablelist::themeDefaults</b></code> are:
    <code><b>-background</b></code>, <code><b>-foreground</b></code>,
    <code><b>-disabledforeground</b></code>,
    <code><b>-stripebackground</b></code>,
    <code><b>-selectbackground</b></code>,
    <code><b>-selectforeground</b></code>,
    <code><b>-selectborderwidth</b></code>, <code><b>-font</b></code>,
    <code><b>-labelforeground</b></code>, <code><b>-labelfont</b></code>,
    <code><b>-labelborderwidth</b></code>, <code><b>-labelpady</b></code>,
    <code><b>-arrowcolor</b></code>, <code><b>-arrowdisabledcolor</b></code>,
    <code><b>-arrowstyle</b></code>, and <code><b>-treestyle</b></code>.&nbsp;
    In addition, the command sets some other array elements to theme-specific
    default values of the background and foreground colors of the column labels
    in <code><b>normal</b></code>, <code><b>disabled</b></code>,
    <code><b>active</b></code>, and <code><b>pressed</b></code> states.&nbsp;
    (Tablelist needs the label colors for handling sort arrows and images with
    transparent background in the column labels.)</dd>

    <dd class="tm">The <code><b>tablelist::setThemeDefaults</b></code> command
    is invoked by Tablelist_tile automatically whenever a tablelist widget is
    createad or the <code><b>&lt;&lt;ThemeChanged&gt;&gt;</b></code> virtual
    event is received by a tablelist widget.&nbsp; In the latter case, the
    widget is reconfigured, using the new default values of those options that
    were not set explicitly to values different from the corresponding
    defaults.</dd>

    <dd class="tm">Besides being used by the Tablelist_tile code, this command
    can also be invoked in Tcl scripts, still before creating any tile-based
    tablelist widget.&nbsp; By calling it explicitly and using the values
    written by it into the array <code><b>tablelist::themeDefaults</b></code>,
    you can make sure that classical Tk widgets, e.g., listbox and text, will
    have a theme-specific appearance, just like the tile widgets.&nbsp; For
    example, you can add some common configuration options to the option
    database as follows:</dd>

    <dd>
      <blockquote>
        <pre>
tablelist::setThemeDefaults
if {$tile::currentTheme eq "aqua"} {
    option add *Listbox.selectBackground \
               $tablelist::themeDefaults(-selectbackground)
    option add *Listbox.selectForeground \
               $tablelist::themeDefaults(-selectforeground)
} else {
    option add *selectBackground  $tablelist::themeDefaults(-selectbackground)
    option add *selectForeground  $tablelist::themeDefaults(-selectforeground)
}
option add *selectBorderWidth     $tablelist::themeDefaults(-selectborderwidth)
</pre>
      </blockquote>
    </dd>

    <dt><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistTile.html.

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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using Tile Widgets</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, tile">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using Tile Widgets</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#entry">Interactive Cell Editing Using the tile entry
    Widget</a></li>

    <li><a href="#spinbox">Interactive Cell Editing Using the tile spinbox
    Widget</a></li>

    <li><a href="#combobox">Interactive Cell Editing Using the tile combobox
    Widget</a></li>

    <li><a href="#checkbutton">Interactive Cell Editing Using the tile
    checkbutton Widget</a></li>

    <li><a href="#menubutton">Interactive Cell Editing Using the tile
    menubutton Widget</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The tile theme engine is a compiled library extension for Tcl/Tk versions
  8.4 or higher.&nbsp; Beginning with Tk 8.5a6, tile is integrated into the Tk
  core.&nbsp; For earlier Tk versions it can be downloaded from the address</p>

  <blockquote>
    <address>
      <a href=
      "http://sourceforge.net/projects/tktable/files/tile/">http://sourceforge.net/projects/tktable//files/tile</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the tile
  entry, spinbox, combobox, checkbutton, and menubutton widgets, accessed as
  <code><b>ttk::entry</b></code>, <code><b>ttk::spinbox</b></code>,
  <code><b>ttk::combobox</b></code>, <code><b>ttk::checkbutton</b></code>, and
  <code><b>ttk::menubutton</b></code>, respectively.&nbsp; The fully-qualified
  names <code><b>::ttk::entry</b></code>, <code><b>::ttk::spinbox</b></code>,
  <code><b>::ttk::combobox</b></code>, <code><b>::ttk::checkbutton</b></code>,
  and <code><b>::ttk::menubutton</b></code> are also supported.&nbsp; The
  version of the tile package must be 0.6 or higher (the tile spinbox requires
  even tile 0.8.3 or later, or, alternatively, Tk 8.6 or later).&nbsp; These
  widgets are automatically registered for cell editing, hence the only action
  needed for using one of them for editing the cells of a given column is as
  follows:</p>

  <p>Use the tablelist widget's <code><b><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
  subcommand to set the given column's <code><b><a href=
  "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
  and its <code><b><a href=
  "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
  <code><b>ttk::entry</b></code>, <code><b>ttk::spinbox</b></code>,
  <code><b>ttk::combobox</b></code>, <code><b>ttk::checkbutton</b></code>, or
  <code><b>ttk::menubutton</b></code> (or to the corresponding fully-qualified
  name), respectively.&nbsp; (These options are supported at cell level, too,
  with the aid of the <code><b><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
  subcommand.)</p>

  <p>One known limitation of earlier tile versions was that the&nbsp;
  <code><b>(ttk::)style theme use</b></code>&nbsp; command could only be used
  to set the current theme, but not to retrieve it.&nbsp; For this reason,
  Tablelist makes use of the variable <code><b>ttk::currentTheme</b></code> or
  <code><b>tile::currentTheme</b></code> (depending on the tile version), which
  is set by the <code><b>ttk::setTheme</b></code> or
  <code><b>tile::setTheme</b></code> procedure.&nbsp; From this it follows that
  the tile widgets used for interactive cell editing will only be managed as
  expected if the platform-specific default theme is either left unchanged or
  replaced with another theme by invoking the procedure
  <code><b>ttk::setTheme</b></code> or <code><b>tile::setTheme</b></code>,
  depending on the current tile version.&nbsp; (See also the <code><b><a href=
  "tablelistThemes.html#setTheme">tablelist::setTheme</a></b></code>
  command.)</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="entry">Interactive Cell Editing Using the tile entry Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile entry widget used for interactive cell
    editing will be created with an explicitly set value for its
    <code><b>-style</b></code> option.&nbsp; Apart from its theme-specific
    appearance, it behaves just like its Tk core counterpart.</dd>

    <dd class="tm">If an application uses the tile entry widget for interactive
    cell editing and also the Wcb package (even if not for that widget), then
    the version of Wcb must be 3.1 or higher (because earlier Wcb releases
    didn't support any tile widgets).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, entry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinbox">Interactive Cell Editing Using the tile spinbox Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile spinbox widget used for interactive cell
    editing will be created with an explicitly set value for its
    <code><b>-style</b></code> option and with its <code><b>-state</b></code>
    option set to <code><b>normal</b></code>, which makes the widget
    editable.&nbsp; You can use the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set the state of the spinbox to
    <code><b>readonly</b></code> or define validations for it, as well as for
    setting its (range of) values and its <code><b>-wrap</b></code>
    option.&nbsp; Apart from its theme-specific appearance, it behaves just
    like its Tk core counterpart.</dd>

    <dd class="tm">If an application uses the tile spinbox widget for
    interactive cell editing and also the Wcb package (even if not for that
    widget), then the version of Wcb must be 3.2 or higher (because the support
    for the new tile spinbox widget was added to Wcb in its version 3.2).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, spinbox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="combobox">Interactive Cell Editing Using the tile combobox
  Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile combobox widget used for interactive cell
    editing will be created with an explicitly set value for its
    <code><b>-style</b></code> option and with its <code><b>-state</b></code>
    option set to <code><b>normal</b></code>, which makes the widget
    editable.&nbsp; You can use the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set the state of the combobox to
    <code><b>readonly</b></code> or define validations for it, as well as for
    populating its listbox component (with the aid of the combobox widget's
    <code><b>-values</b></code> option).</dd>

    <dd class="tm">If an application uses the tile combobox widget for
    interactive cell editing and also the Wcb package (even if not for that
    widget), then the version of Wcb must be 3.1 or higher (because earlier Wcb
    releases didn't support any tile widgets).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, combobox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="checkbutton">Interactive Cell Editing Using the tile checkbutton
  Widget.</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile checkbutton widget used for interactive
    cell editing will be created with explicitly set values for its
    <code><b>-style</b></code> and <code><b>-variable</b></code> options.&nbsp;
    You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other configuration options, like
    <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code>, according
    to the <i>internal</i> values of the cells.&nbsp; Since the default values
    of the <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code> tile
    checkbutton options are <code>0</code> and <code>1</code>, you don't need
    to change these options if the cells have the same internal values
    <code>0</code> and <code>1</code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, checkbutton</dd>
  </dl>
  <hr>

  <h2 id="menubutton">Interactive Cell Editing Using the tile menubutton
  Widget.</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile menubutton widget used for interactive cell
    editing will be created with explicitly set values for its
    <code><b>-style</b></code> and <code><b>-textvariable</b></code>
    options.&nbsp; In addition, a menu with its <code><b>-tearoff</b></code>
    option set to <code>0</code> and an appropriate script as the value of its
    <code><b>-postcommand</b></code> option is created and set as the value of
    the menubutton's <code><b>-menu</b></code> option.&nbsp; In an X11
    environment, the menu's appearance is adapted to that of the tablelist
    widget by setting its <code><b>-background</b></code>,
    <code><b>-foreground</b></code>, <code><b>-activebackground</b></code>,
    <code><b>-activeforeground</b></code>, and
    <code><b>-activeborderwidth</b></code> options to appropriate values.&nbsp;
    You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other options of the menubutton
    and/or its associated menu.&nbsp; You will, however, need this script in
    the first place for populating the menu, preferably with radiobutton
    entries.&nbsp; For every radiobutton entry added to the menu, the Tablelist
    implementation will make sure that its value (which can be specified by
    setting the entry's <code><b>-value</b></code> or
    <code><b>-label</b></code> option) will be displayed in the menubutton as
    its text when the entry is selected.&nbsp; (Tablelist achieves this by
    setting the menu entry's <code><b>-variable</b></code> option to the value
    of the menubutton's <code><b>-textvariable</b></code> option.)&nbsp; For
    menu entries of types other than radiobutton (e.g., for command entries) it
    is the responsibility of the application to make sure that the selected
    entry's text will be shown in the menubutton (for example, with the aid of
    the menu entry's <code><b>-command</b></code> option).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, menubutton</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistTkCore.html.

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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using Tk Core Widgets</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, Tk core">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using Tk Core Widgets</h1>

    <h2>For Tablelist Version 5.16</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#entry">Interactive Cell Editing Using the entry
    Widget</a></li>

    <li><a href="#text">Interactive Cell Editing Using the text Widget</a></li>

    <li><a href="#spinbox">Interactive Cell Editing Using the spinbox
    Widget</a></li>

    <li><a href="#checkbutton">Interactive Cell Editing Using the checkbutton
    Widget</a></li>

    <li><a href="#menubutton">Interactive Cell Editing Using the menubutton
    Widget</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>Tablelist supports interactive cell editing with the aid of the Tk core
  entry, text, spinbox, checkbutton, and menubutton widgets.&nbsp; These
  widgets are automatically registered for cell editing, hence the only action
  needed for using one of them for editing the cells of a given column is as
  follows:</p>

  <p>Use the tablelist widget's <code><b><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
  subcommand to set the given column's <code><b><a href=
  "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
  and its <code><b><a href=
  "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
  <code><b>entry</b></code>, <code><b>text</b></code>,
  <code><b>spinbox</b></code>, <code><b>checkbutton</b></code>, or
  <code><b>menubutton</b></code>, respectively.&nbsp; (These options are
  supported at cell level, too, with the aid of the <code><b><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
  subcommand.)&nbsp; Since the default value of the
  <code><b>-editwindow</b></code> column configuration option is
  <code><b>entry</b></code>, it is not necessary to set it explicitly if the
  editing should take place with the aid of an embedded entry widget.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="entry">Interactive Cell Editing Using the entry Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>As mentioned above, the interactive cell editing in a tablelist widget
    takes place per default with the aid of an embedded entry widget.&nbsp;
    Refer to the <a href="tablelistWidget.html#cell_editing">INTERACTIVE CELL
    EDITING</a> section of the reference page describing the
    <code><b>tablelist::tablelist</b></code> command for details on the editing
    process.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, entry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="text">Interactive Cell Editing Using the text Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded text widget used for interactive cell editing
    will be created with its <code><b>-padx</b></code> and
    <code><b>-pady</b></code> options set to <code>2</code>, its
    <code><b>-wrap</b></code> option set to <code><b>none</b></code>, and its
    initial height set to the number of lines contained in it.&nbsp; There is,
    however, an exception from this rule:&nbsp; If the <code><b><a href=
    "tablelistWidget.html#col_wrap">-wrap</a></b></code> option of the cell's
    column was set to true and Tk version 8.5 or higher is being used, then the
    text widget's <code><b>-wrap</b></code> option will be set to
    <code><b>word</b></code> and its initial height will equal the number of
    <i>display</i> lines (taking into account the line wraps) contained in
    it.&nbsp; You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to override the initial settings according
    to your needs.</dd>

    <dd class="tm">If the text widget's <code><b>-wrap</b></code> option was
    set to <code><b>word</b></code> or <code><b>char</b></code> (either by
    Tablelist or from within the above-mentioned script) and Tk version 8.5 or
    higher is being used, then, whenever its width changes (e.g., due to
    interactive column resizing), its height will be set automatically to the
    number of display lines contained in it.&nbsp; (The number of display lines
    is retrieved with the aid of the&nbsp; <code><b>count
    -displaylines</b></code>&nbsp; text widget subcommand, introduced in Tk
    8.5.)</dd>

    <dd class="tm">If the widget callback package Wcb was loaded into the
    interpreter (via&nbsp; <code><b>package require Wcb</b></code>&nbsp;
    or&nbsp; <code><b>package require wcb</b></code>)&nbsp; then the text
    widget's height will be updated automatically whenever text is inserted
    into or deleted from it, which makes the editing much more
    user-friendly.&nbsp; This is achieved by using an appropriately defined
    after-<code><b>insert</b></code> and after-<code><b>delete</b></code>
    callback for the edit window.&nbsp; You can use the script corresponding to
    the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define further callbacks for the text
    widget.&nbsp; (The above-mentioned callback is created via
    <code><b>wcb::cbappend</b></code>, <i>after</i> returning from that
    script.)</dd>

    <dd class="tm">The <code>Tab</code> key is reserved for navigation between
    the editable cells, but the user can insert a tabulator character into the
    text widget by pressing <code>Control-i</code>.</dd>

    <dd class="tm">Unlike in the case of the other widgets used for interactive
    cell editing, the <code>Return</code> and <code>KP_Enter</code> keys insert
    a newline character into the text widget.&nbsp; <code>Control-j</code> can
    also be used for inserting a newline.&nbsp; <code>Control-Return</code> and
    <code>Control-KP_Enter</code> terminate the editing and destroy the edit
    window.</dd>

    <dd class="tm"><code>Control-Home</code> and <code>Control-End</code> have
    their well-known text widget-specific bindings, just like
    <code>Meta-&lt;</code> and <code>Meta-&gt;</code> if
    <code><b>tk_strictMotif</b></code> is false.&nbsp; Again, this is different
    from the behavior of the other widgets used for interactive cell
    editing.&nbsp; For jumping into the first/last editable cell, the user can
    press <code>Alt-Home</code>/<code>Alt-End</code> or
    <code>Meta-Home</code>/<code>Meta-End</code>
    (<code>Command-Home</code>/<code>Command-End</code> on Mac OS Classic and
    Mac OS X Aqua).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, text</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinbox">Interactive Cell Editing Using the spinbox Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded spinbox widget used for interactive cell editing
    will be created with its <code><b>-state</b></code> option set to
    <code><b>normal</b></code>, which makes the widget editable.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set the state of the spinbox to
    <code><b>readonly</b></code> or define validations for it, as well as for
    setting its (range of) values and its <code><b>-wrap</b></code>
    option.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, spinbox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="checkbutton">Interactive Cell Editing Using the checkbutton
  Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>On Windows, Mac OS Classic, and Mac OS X Aqua the temporary embedded
    checkbutton widget used for interactive cell editing will be created with
    explicitly set values for its <code><b>-borderwidth</b></code>,
    <code><b>-font</b></code>, <code><b>-padx</b></code>,
    <code><b>-pady</b></code>, and <code><b>-variable</b></code> options.&nbsp;
    In an X11 environment it will be created with explicitly set values for its
    <code><b>-borderwidth</b></code>, <code><b>-indicatoron</b></code>,
    <code><b>-image</b></code>, <code><b>-selectimage</b></code>,
    <code><b>-selectcolor</b></code>, and <code><b>-variable</b></code>
    options.&nbsp; You can use the script corresponding to the
    <code><b><a href="tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other options, like
    <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code>, according
    to the <i>internal</i> values of the cells.&nbsp; Since the default values
    of the <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code>
    checkbutton options are <code>0</code> and <code>1</code>, you don't need
    to change these options if the cells have the same internal values
    <code>0</code> and <code>1</code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, checkbutton</dd>
  </dl>
  <hr>

  <h2 id="menubutton">Interactive Cell Editing Using the menubutton Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded menubutton widget used for interactive cell
    editing will be created with explicitly set values for its
    <code><b>-anchor</b></code>, <code><b>-indicatoron</b></code>,
    <code><b>-justify</b></code>, <code><b>-padx</b></code>,
    <code><b>-pady</b></code>, <code><b>-relief</b></code>, and
    <code><b>-textvariable</b></code> options.&nbsp; In addition, a menu with
    its <code><b>-tearoff</b></code> option set to <code>0</code> and an
    appropriate script as the value of its <code><b>-postcommand</b></code>
    option is created and set as the value of the menubutton's
    <code><b>-menu</b></code> option.&nbsp; In an X11 environment, the menu's
    appearance is adapted to that of the tablelist widget by setting its
    <code><b>-background</b></code>, <code><b>-foreground</b></code>,
    <code><b>-activebackground</b></code>,
    <code><b>-activeforeground</b></code>, and
    <code><b>-activeborderwidth</b></code> options to appropriate values.&nbsp;
    You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other options of the menubutton
    and/or its associated menu.&nbsp; You will, however, need this script in
    the first place for populating the menu, preferably with radiobutton
    entries.&nbsp; For every radiobutton entry added to the menu, the Tablelist
    implementation will make sure that its value (which can be specified by
    setting the entry's <code><b>-value</b></code> or
    <code><b>-label</b></code> option) will be displayed in the menubutton as
    its text when the entry is selected.&nbsp; (Tablelist achieves this by
    setting the menu entry's <code><b>-variable</b></code> option to the value
    of the menubutton's <code><b>-textvariable</b></code> option.)&nbsp; For
    menu entries of types other than radiobutton (e.g., for command entries) it
    is the responsibility of the application to make sure that the selected
    entry's text will be shown in the menubutton (for example, with the aid of
    the menu entry's <code><b>-command</b></code> option).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, menubutton</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/doc/tablelistWidget.html.

more than 10,000 changes

Deleted libs/tablelist5.16/doc/tileWidgets.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/ubuntu.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/ubuntu2.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/vistaAero.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/vistaClassic.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/win10.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/win7Aero.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/win7Classic.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/winnative.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/winxpBlue.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/winxpOlive.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/winxpSilver.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/doc/yuyo.png.

cannot compute difference between binary files

Deleted libs/tablelist5.16/pkgIndex.tcl.

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
#==============================================================================
# Tablelist and Tablelist_tile package index file.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Regular packages:
#
package ifneeded tablelist         5.16 \
	[list source [file join $dir tablelist.tcl]]
package ifneeded tablelist_tile    5.16 \
	[list source [file join $dir tablelist_tile.tcl]]

#
# Aliases:
#
package ifneeded Tablelist         5.16 \
	[list package require -exact tablelist	    5.16]
package ifneeded Tablelist_tile    5.16 \
	[list package require -exact tablelist_tile 5.16]

#
# Code common to all packages:
#
package ifneeded tablelist::common 5.16 \
        "namespace eval ::tablelist { proc DIR {} {return [list $dir]} } ;\
	 source [list [file join $dir tablelistPublic.tcl]]"
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































Deleted libs/tablelist5.16/scripts/mwutil.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
#==============================================================================
# Contains utility procedures for mega-widgets.
#
# Structure of the module:
#   - Namespace initialization
#   - Public utility procedures
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tcl 8
package require Tk  8

#
# Namespace initialization
# ========================
#

namespace eval mwutil {
    #
    # Public variables:
    #
    variable version	2.8
    variable library	[file dirname [info script]]

    #
    # Public procedures:
    #
    namespace export	wrongNumArgs getAncestorByClass convEventFields \
			defineKeyNav processTraversal focusNext focusPrev \
			configureWidget fullConfigOpt fullOpt enumOpts \
			configureSubCmd attribSubCmd hasattribSubCmd \
			unsetattribSubCmd getScrollInfo

    #
    # Make modified versions of the procedures tk_focusNext and
    # tk_focusPrev, to be invoked in the processTraversal command
    #
    proc makeFocusProcs {} {
	#
	# Enforce the evaluation of the Tk library file "focus.tcl"
	#
	tk_focusNext .

	#
	# Build the procedures focusNext and focusPrev
	#
	foreach direction {Next Prev} {
	    set procBody [info body tk_focus$direction]
	    regsub -all {winfo children} $procBody {getChildren $class} procBody
	    proc focus$direction {w class} $procBody
	}
    }
    makeFocusProcs 

    #
    # Invoked in the procedures focusNext and focusPrev defined above:
    #
    proc getChildren {class w} {
	if {[string compare [winfo class $w] $class] == 0} {
	    return {}
	} else {
	    return [winfo children $w]
	}
    }
}

#
# Public utility procedures
# =========================
#

#------------------------------------------------------------------------------
# mwutil::wrongNumArgs
#
# Generates a "wrong # args" error message.
#------------------------------------------------------------------------------
proc mwutil::wrongNumArgs args {
    set optList {}
    foreach arg $args {
	lappend optList \"$arg\"
    }
    return -code error "wrong # args: should be [enumOpts $optList]"
}

#------------------------------------------------------------------------------
# mwutil::getAncestorByClass
#
# Gets the path name of the widget of the specified class from the path name w
# of one of its descendants.  It is assumed that all of the ancestors of w
# exist (but w itself needn't exist).
#------------------------------------------------------------------------------
proc mwutil::getAncestorByClass {w class} {
    regexp {^(\..+)\..+$} $w dummy win
    while {[string compare [winfo class $win] $class] != 0} {
	set win [winfo parent $win]
    }

    return $win
}

#------------------------------------------------------------------------------
# mwutil::convEventFields
#
# Gets the path name of the widget of the specified class and the x and y
# coordinates relative to the latter from the path name w of one of its
# descendants and from the x and y coordinates relative to the latter.
#------------------------------------------------------------------------------
proc mwutil::convEventFields {w x y class} {
    set win [getAncestorByClass $w $class]
    set _x  [expr {$x + [winfo rootx $w] - [winfo rootx $win]}]
    set _y  [expr {$y + [winfo rooty $w] - [winfo rooty $win]}]

    return [list $win $_x $_y]
}

#------------------------------------------------------------------------------
# mwutil::defineKeyNav
#
# For a given mega-widget class, the procedure defines the binding tag
# ${class}KeyNav as a partial replacement for "all", by substituting the
# scripts bound to the events <Tab>, <Shift-Tab>, and <<PrevWindow>> with new
# ones which propagate these events to the mega-widget of the given class
# containing the widget to which the event was reported.  (The event
# <Shift-Tab> was replaced with <<PrevWindow>> in Tk 8.3.0.)  This tag is
# designed to be inserted before "all" in the list of binding tags of a
# descendant of a mega-widget of the specified class.
#------------------------------------------------------------------------------
proc mwutil::defineKeyNav class {
    foreach event {<Tab> <Shift-Tab> <<PrevWindow>>} {
	bind ${class}KeyNav $event \
	     [list mwutil::processTraversal %W $class $event]
    }

    bind Entry   <<TraverseIn>> { %W selection range 0 end; %W icursor end }
    bind Spinbox <<TraverseIn>> { %W selection range 0 end; %W icursor end }
}

#------------------------------------------------------------------------------
# mwutil::processTraversal
#
# Processes the given traversal event for the mega-widget of the specified
# class containing the widget w if that mega-widget is not the only widget
# receiving the focus during keyboard traversal within its top-level widget.
#------------------------------------------------------------------------------
proc mwutil::processTraversal {w class event} {
    set win [getAncestorByClass $w $class]

    if {[string compare $event "<Tab>"] == 0} {
	set target [focusNext $win $class]
    } else {
	set target [focusPrev $win $class]
    }

    if {[string compare $target $win] != 0} {
	set focus [focus]
	if {[string length $focus] != 0} {
	    event generate $focus <<TraverseOut>>
	}

	focus $target
	event generate $target <<TraverseIn>>
    }

    return -code break ""
}

#------------------------------------------------------------------------------
# mwutil::configureWidget
#
# Configures the widget win by processing the command-line arguments specified
# in optValPairs and, if the value of initialize is true, also those database
# options that don't match any command-line arguments.
#------------------------------------------------------------------------------
proc mwutil::configureWidget {win configSpecsName configCmd cgetCmd \
			      optValPairs initialize} {
    upvar $configSpecsName configSpecs

    #
    # Process the command-line arguments
    #
    set cmdLineOpts {}
    set savedVals {}
    set failed 0
    set count [llength $optValPairs]
    foreach {opt val} $optValPairs {
	if {[catch {fullConfigOpt $opt configSpecs} result] != 0} {
	    set failed 1
	    break
	}
	if {$count == 1} {
	    set result "value for \"$opt\" missing"
	    set failed 1
	    break
	}
	set opt $result
	lappend cmdLineOpts $opt
	lappend savedVals [eval $cgetCmd [list $win $opt]]
	if {[catch {eval $configCmd [list $win $opt $val]} result] != 0} {
	    set failed 1
	    break
	}
	incr count -2
    }

    if {$failed} {
	#
	# Restore the saved values
	#
	foreach opt $cmdLineOpts val $savedVals {
	    eval $configCmd [list $win $opt $val]
	}

	return -code error $result
    }

    if {$initialize} {
	#
	# Process those configuration options that were not
	# given as command-line arguments; use the corresponding
	# values from the option database if available
	#
	foreach opt [lsort [array names configSpecs]] {
	    if {[llength $configSpecs($opt)] == 1 ||
		[lsearch -exact $cmdLineOpts $opt] >= 0} {
		continue
	    }
	    set dbName [lindex $configSpecs($opt) 0]
	    set dbClass [lindex $configSpecs($opt) 1]
	    set dbValue [option get $win $dbName $dbClass]
	    if {[string length $dbValue] == 0} {
		set default [lindex $configSpecs($opt) 3]
		eval $configCmd [list $win $opt $default]
	    } else {
		if {[catch {
		    eval $configCmd [list $win $opt $dbValue]
		} result] != 0} {
		    return -code error $result
		}
	    }
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# mwutil::fullConfigOpt
#
# Returns the full configuration option corresponding to the possibly
# abbreviated option opt.
#------------------------------------------------------------------------------
proc mwutil::fullConfigOpt {opt configSpecsName} {
    upvar $configSpecsName configSpecs

    if {[info exists configSpecs($opt)]} {
	if {[llength $configSpecs($opt)] == 1} {
	    return $configSpecs($opt)
	} else {
	    return $opt
	}
    }

    set optList [lsort [array names configSpecs]]
    set count 0
    foreach elem $optList {
	if {[string first $opt $elem] == 0} {
	    incr count
	    if {$count == 1} {
		set option $elem
	    } else {
		break
	    }
	}
    }

    if {$count == 1} {
	if {[llength $configSpecs($option)] == 1} {
	    return $configSpecs($option)
	} else {
	    return $option
	}
    } elseif {$count == 0} {
	### return -code error "unknown option \"$opt\""
	return -code error \
	       "bad option \"$opt\": must be [enumOpts $optList]"
    } else {
	### return -code error "unknown option \"$opt\""
	return -code error \
	       "ambiguous option \"$opt\": must be [enumOpts $optList]"
    }
}

#------------------------------------------------------------------------------
# mwutil::fullOpt
#
# Returns the full option corresponding to the possibly abbreviated option opt.
#------------------------------------------------------------------------------
proc mwutil::fullOpt {kind opt optList} {
    if {[lsearch -exact $optList $opt] >= 0} {
	return $opt
    }

    set count 0
    foreach elem $optList {
	if {[string first $opt $elem] == 0} {
	    incr count
	    if {$count == 1} {
		set option $elem
	    } else {
		break
	    }
	}
    }

    if {$count == 1} {
	return $option
    } elseif {$count == 0} {
	return -code error \
	       "bad $kind \"$opt\": must be [enumOpts $optList]"
    } else {
	return -code error \
	       "ambiguous $kind \"$opt\": must be [enumOpts $optList]"
    }
}

#------------------------------------------------------------------------------
# mwutil::enumOpts
#
# Returns a string consisting of the elements of the given list, separated by
# commas and spaces.
#------------------------------------------------------------------------------
proc mwutil::enumOpts optList {
    set optCount [llength $optList]
    set n 1
    foreach opt $optList {
	if {$n == 1} {
	    set str $opt
	} elseif {$n < $optCount} {
	    append str ", $opt"
	} else {
	    if {$optCount > 2} {
		append str ","
	    }
	    append str " or $opt"
	}

	incr n
    }

    return $str
}

#------------------------------------------------------------------------------
# mwutil::configureSubCmd
#
# This procedure is invoked to process configuration subcommands.
#------------------------------------------------------------------------------
proc mwutil::configureSubCmd {win configSpecsName configCmd cgetCmd argList} {
    upvar $configSpecsName configSpecs

    set argCount [llength $argList]
    if {$argCount > 1} {
	#
	# Set the specified configuration options to the given values
	#
	return [configureWidget $win configSpecs $configCmd $cgetCmd $argList 0]
    } elseif {$argCount == 1} {
	#
	# Return the description of the specified configuration option
	#
	set opt [fullConfigOpt [lindex $argList 0] configSpecs]
	set dbName [lindex $configSpecs($opt) 0]
	set dbClass [lindex $configSpecs($opt) 1]
	set default [lindex $configSpecs($opt) 3]
	return [list $opt $dbName $dbClass $default \
		[eval $cgetCmd [list $win $opt]]]
    } else {
	#
	# Return a list describing all available configuration options
	#
	foreach opt [lsort [array names configSpecs]] {
	    if {[llength $configSpecs($opt)] == 1} {
		set alias $configSpecs($opt)
		if {$::tk_version >= 8.1} {
		    lappend result [list $opt $alias]
		} else {
		    set dbName [lindex $configSpecs($alias) 0]
		    lappend result [list $opt $dbName]
		}
	    } else {
		set dbName [lindex $configSpecs($opt) 0]
		set dbClass [lindex $configSpecs($opt) 1]
		set default [lindex $configSpecs($opt) 3]
		lappend result [list $opt $dbName $dbClass $default \
				[eval $cgetCmd [list $win $opt]]]
	    }
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# mwutil::attribSubCmd
#
# This procedure is invoked to process *attrib subcommands.
#------------------------------------------------------------------------------
proc mwutil::attribSubCmd {win prefix argList} {
    set classNs [string tolower [winfo class $win]]
    upvar ::${classNs}::ns${win}::attribs attribs

    set argCount [llength $argList]
    if {$argCount > 1} {
	#
	# Set the specified attributes to the given values
	#
	if {$argCount % 2 != 0} {
	    return -code error "value for \"[lindex $argList end]\" missing"
	}
	foreach {attr val} $argList {
	    set attribs($prefix-$attr) $val
	}
	return ""
    } elseif {$argCount == 1} {
	#
	# Return the value of the specified attribute
	#
	set attr [lindex $argList 0]
	set name $prefix-$attr
	if {[info exists attribs($name)]} {
	    return $attribs($name)
	} else {
	    return ""
	}
    } else {
	#
	# Return the current list of attribute names and values
	#
	set len [string length "$prefix-"]
	set result {}
	foreach name [lsort [array names attribs "$prefix-*"]] {
	    set attr [string range $name $len end]
	    lappend result [list $attr $attribs($name)]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# mwutil::hasattribSubCmd
#
# This procedure is invoked to process has*attrib subcommands.
#------------------------------------------------------------------------------
proc mwutil::hasattribSubCmd {win prefix attr} {
    set classNs [string tolower [winfo class $win]]
    upvar ::${classNs}::ns${win}::attribs attribs

    return [info exists attribs($prefix-$attr)]
}

#------------------------------------------------------------------------------
# mwutil::unsetattribSubCmd
#
# This procedure is invoked to process unset*attrib subcommands.
#------------------------------------------------------------------------------
proc mwutil::unsetattribSubCmd {win prefix attr} {
    set classNs [string tolower [winfo class $win]]
    upvar ::${classNs}::ns${win}::attribs attribs

    set name $prefix-$attr
    if {[info exists attribs($name)]} {
	unset attribs($name)
    }

    return ""
}

#------------------------------------------------------------------------------
# mwutil::getScrollInfo
#
# Parses a list of arguments of the form "moveto <fraction>" or "scroll
# <number> units|pages" and returns the corresponding list consisting of two or
# three properly formatted elements.
#------------------------------------------------------------------------------
proc mwutil::getScrollInfo argList {
    set argCount [llength $argList]
    set opt [lindex $argList 0]

    if {[string first $opt "moveto"] == 0} {
	if {$argCount != 2} {
	    wrongNumArgs "moveto fraction"
	}

	set fraction [format "%f" [lindex $argList 1]]
	return [list moveto $fraction]
    } elseif {[string first $opt "scroll"] == 0} {
	if {$argCount != 3} {
	    wrongNumArgs "scroll number units|pages"
	}

	set number [format "%d" [lindex $argList 1]]
	set what [lindex $argList 2]
	if {[string first $what "units"] == 0} {
	    return [list scroll $number units]
	} elseif {[string first $what "pages"] == 0} {
	    return [list scroll $number pages]
	} else {
	    return -code error "bad argument \"$what\": must be units or pages"
	}
    } else {
	return -code error "unknown option \"$opt\": must be moveto or scroll"
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/pencil.cur.

cannot compute difference between binary files

Deleted libs/tablelist5.16/scripts/repair.tcl.

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
#!/usr/bin/env wish

#==============================================================================
# Creates new versions of the files "tablelistWidget.tcl", "tablelistBind.tcl",
# "tablelistConfig.tcl", "tablelistEdit.tcl", "tablelistMove.tcl",
# "tablelistSort.tcl", and "tablelistUtil.tcl" by defining the procedure
# "arrElemExists" and replacing all invocations of "[info exists
# <array>(<name>)]" with "[arrElemExists <array> <name>]".  This works around a
# bug in Tcl versions 8.2, 8.3.0 - 8.3.2, and 8.4a1 (fixed in Tcl 8.3.3 and
# 8.4a2), which causes excessive memory use when calling "info exists" on
# non-existent array elements.
#
# Copyright (c) 2001-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

set procDef {
    #
    # The following procedure returns 1 if arrName($name) exists and
    # 0 otherwise.  It is a (partial) replacement for [info exists
    # arrName($name)], which -- due to a bug in Tcl versions 8.2,
    # 8.3.0 - 8.3.2, and 8.4a1 (fixed in Tcl 8.3.3 and 8.4a2) --
    # causes excessive memory use if arrName($name) doesn't exist.
    # The first version of the procedure assumes that the second
    # argument doesn't contain glob-style special characters.
    #
    if {[regexp {^8\.(2\.[0-3]|3\.[0-2]|4a1)$} $tk_patchLevel]} {
	proc arrElemExists {arrName name} {
	    upvar $arrName arr
	    return [llength [array names arr $name]]
	}
    } else {
	proc arrElemExists {arrName name} {
	    upvar $arrName arr
	    return [info exists arr($name)]		;# this is much faster
	}
    }
}

file copy tablelistWidget.tcl tablelistWidget.tcl.BAK

set fi [open tablelistWidget.tcl.BAK r]
set fo [open tablelistWidget.tcl     w]

for {set n 1} {[gets $fi line] >= 0} {incr n} {
    if {$n == 19} {
	puts -nonewline $fo $line
	puts $fo $procDef
    } else {
	regsub -all {\[info exists (tablelist::[^\(]+)\(([^\]]+)\)\]} $line \
		    {[tablelist::arrElemExists \1 \2]} line
	regsub -all {\[info exists ([^\(]+)\(([^\]]+)\)\]} $line \
		    {[arrElemExists \1 \2]} line
	puts $fo $line
    }
}

close $fi
close $fo

puts "\nMade backup copy \"tablelistWidget.tcl.BAK\"."
puts "Created new version of the file \"tablelistWidget.tcl\"."

foreach file {tablelistBind.tcl tablelistConfig.tcl tablelistEdit.tcl
	      tablelistMove.tcl tablelistSort.tcl tablelistThemes.tcl
	      tablelistUtil.tcl} {
    file copy $file $file.BAK

    set fi [open $file.BAK r]
    set fo [open $file     w]

    while {[gets $fi line] >= 0} {
	regsub -all {\[info exists (tablelist::[^\(]+)\(([^\]]+)\)\]} $line \
		    {[tablelist::arrElemExists \1 \2]} line
	regsub -all {\[info exists ([^\(]+)\(([^\]]+)\)\]} $line \
		    {[arrElemExists \1 \2]} line
	puts $fo $line
    }

    close $fi
    close $fo

    puts "\nMade backup copy \"$file.BAK\"."
    puts "Created new version of the file \"$file\"."
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































Deleted libs/tablelist5.16/scripts/tablelistBind.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
#==============================================================================
# Contains public and private procedures used in tablelist bindings.
#
# Structure of the module:
#   - Public helper procedures
#   - Binding tag Tablelist
#   - Binding tag TablelistWindow
#   - Binding tag TablelistBody
#   - Binding tags TablelistLabel, TablelistSubLabel, and TablelistArrow
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Public helper procedures
# ========================
#

#------------------------------------------------------------------------------
# tablelist::getTablelistColumn
#
# Gets the column number from the path name w of a (sub)label or sort arrow of
# a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::getTablelistColumn w {
    if {[regexp {^(\..+)\.hdr\.t\.f\.l([0-9]+)(-[it]l)?$} $w dummy win col] ||
	[regexp {^(\..+)\.hdr\.t\.f\.c([0-9]+)$} $w dummy win col]} {
	return $col
    } else {
	return -1
    }
}

#------------------------------------------------------------------------------
# tablelist::getTablelistPath
#
# Gets the path name of the tablelist widget from the path name w of one of its
# descendants.  It is assumed that all of the ancestors of w exist (but w
# itself needn't exist).
#------------------------------------------------------------------------------
proc tablelist::getTablelistPath w {
    return [mwutil::getAncestorByClass $w Tablelist]
}

#------------------------------------------------------------------------------
# tablelist::convEventFields
#
# Gets the path name of the tablelist widget and the x and y coordinates
# relative to the latter from the path name w of one of its descendants and
# from the x and y coordinates relative to the latter.
#------------------------------------------------------------------------------
proc tablelist::convEventFields {w x y} {
    return [mwutil::convEventFields $w $x $y Tablelist]
}

#
# Binding tag Tablelist
# =====================
#

#------------------------------------------------------------------------------
# tablelist::addActiveTag
#
# This procedure is invoked when the tablelist widget win gains the keyboard
# focus.  It moves the "active" tag to the line or cell that displays the
# active item or element of the widget in its body text child.
#------------------------------------------------------------------------------
proc tablelist::addActiveTag win {
    upvar ::tablelist::ns${win}::data data
    set data(ownsFocus) 1

    #
    # Conditionally move the "active" tag to the line
    # or cell that displays the active item or element
    #
    if {![info exists data(dispId)]} {
	moveActiveTag $win
    }
}

#------------------------------------------------------------------------------
# tablelist::removeActiveTag
#
# This procedure is invoked when the tablelist widget win loses the keyboard
# focus.  It removes the "active" tag from the body text child of the widget.
#------------------------------------------------------------------------------
proc tablelist::removeActiveTag win {
    upvar ::tablelist::ns${win}::data data
    set data(ownsFocus) 0

    $data(body) tag remove curRow 1.0 end
    $data(body) tag remove active 1.0 end
}

#------------------------------------------------------------------------------
# tablelist::cleanup
#
# This procedure is invoked when the tablelist widget win is destroyed.  It
# executes some cleanup operations.
#------------------------------------------------------------------------------
proc tablelist::cleanup win {
    #
    # Cancel the execution of all delayed handleMotion, updateKeyToRowMap,
    # adjustSeps, makeStripes, showLineNumbers, stretchColumns, updateColors,
    # updateScrlColOffset, updateHScrlbar, updateVScrlbar, updateView,
    # synchronize, displayItems, moveTo, autoScan, horizAutoScan, forceRedraw,
    # doCellConfig, redisplay, redisplayCol, and destroyWidgets commands
    #
    upvar ::tablelist::ns${win}::data data
    foreach id {motionId mapId sepsId stripesId lineNumsId stretchId colorsId
		offsetId hScrlbarId vScrlbarId viewId syncId dispId moveToId
		afterId redrawId reconfigId} {
	if {[info exists data($id)]} {
	    after cancel $data($id)
	}
    }
    foreach name [array names data *redispId] {
	after cancel $data($name)
    }
    foreach destroyId $data(destroyIdList) {
	after cancel $destroyId
    }

    #
    # If there is a list variable associated with the
    # widget then remove the trace set on this variable
    #
    upvar #0 $data(-listvariable) var
    if {$data(hasListVar) && [info exists var]} {
	trace vdelete var wu $data(listVarTraceCmd)
    }

    #
    # Destroy any existing bindings for data(bodyTag),
    # data(labelTag), and data(editwinTag)
    #
    foreach event [bind $data(bodyTag)] {
	bind $data(bodyTag) $event ""
    }
    foreach event [bind $data(labelTag)] {
	bind $data(labelTag) $event ""
    }
    foreach event [bind $data(editwinTag)] {
	bind $data(editwinTag) $event ""
    }

    #
    # Delete the bitmaps displaying the sort ranks
    # and the images used to display the sort arrows
    #
    for {set rank 1} {$rank < 10} {incr rank} {
	image delete sortRank$rank$win
    }
    set imgNames [image names]
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set w $data(hdrTxtFrCanv)$col
	foreach shape {triangleUp darkLineUp lightLineUp
		       triangleDn darkLineDn lightLineDn} {
	    if {[lsearch -exact $imgNames $shape$w] >= 0} {
		image delete $shape$w
	    }
	}
    }

    destroy $data(corner)

    namespace delete ::tablelist::ns$win
    catch {rename ::$win ""}
}

#------------------------------------------------------------------------------
# tablelist::updateCanvases
#
# This procedure handles the events <Activate> and <Deactivate> by configuring
# the canvases displaying sort arrows.
#------------------------------------------------------------------------------
proc tablelist::updateCanvases win {
    upvar ::tablelist::ns${win}::data data
    foreach col $data(arrowColList) {
	configCanvas $win $col
	raiseArrow $win $col
    }
}

#------------------------------------------------------------------------------
# tablelist::updateConfigSpecs
#
# This procedure handles the virtual event <<ThemeChanged>> by updating the
# theme-specific default values of some tablelist configuration options.
#------------------------------------------------------------------------------
proc tablelist::updateConfigSpecs win {
    #
    # This might be an "after idle" callback; check whether the window exists
    #
    if {![array exists ::tablelist::ns${win}::data]} {
	return ""
    }

    set currentTheme [getCurrentTheme]
    upvar ::tablelist::ns${win}::data data
    if {[string compare $currentTheme $data(currentTheme)] == 0} {
	if {[string compare $currentTheme "tileqt"] == 0} {
	    set widgetStyle [tileqt_currentThemeName]
	    if {[info exists ::env(KDE_SESSION_VERSION)] &&
		[string length $::env(KDE_SESSION_VERSION)] != 0} {
		set colorScheme [getKdeConfigVal "General" "ColorScheme"]
	    } else {
		set colorScheme [getKdeConfigVal "KDE" "colorScheme"]
	    }
	    if {[string compare $widgetStyle $data(widgetStyle)] == 0 &&
		[string compare $colorScheme $data(colorScheme)] == 0} {
		return ""
	    }
	} else {
	    return ""
	}
    }

    #
    # Populate the array tmp with values corresponding to the old theme
    # and the array themeDefaults with values corresponding to the new one
    #
    array set tmp $data(themeDefaults)
    setThemeDefaults

    #
    # Set those configuration options whose values equal the old
    # theme-specific defaults to the new theme-specific ones
    #
    variable themeDefaults
    foreach opt {-background -foreground -disabledforeground -stripebackground
		 -selectbackground -selectforeground -selectborderwidth -font
		 -labelforeground -labelfont -labelborderwidth -labelpady
		 -treestyle} {
	if {[string compare $data($opt) $tmp($opt)] == 0} {
	    doConfig $win $opt $themeDefaults($opt)
	}
    }
    if {[string compare $data(-arrowcolor) $tmp(-arrowcolor)] == 0 &&
	[string compare $data(-arrowstyle) $tmp(-arrowstyle)] == 0} {
	foreach opt {-arrowcolor -arrowdisabledcolor -arrowstyle} {
	    doConfig $win $opt $themeDefaults($opt)
	}
    }
    foreach opt {-background -foreground} {
	doConfig $win $opt $data($opt)	;# sets the bg color of the separators
    }
    updateCanvases $win

    #
    # Destroy and recreate the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editRow $data(editRow)
	saveEditData $win
	destroy $data(bodyFr)
	doEditCell $win $editRow $editCol 1
    }

    #
    # Destroy and recreate the embedded windows
    #
    if {$data(winCount) != 0} {
	for {set row 0} {$row < $data(itemCount)} {incr row} {
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set key [lindex $data(keyList) $row]
		if {[info exists data($key,$col-window)]} {
		    set val $data($key,$col-window)
		    doCellConfig $row $col $win -window ""
		    doCellConfig $row $col $win -window $val
		}
	    }
	}
    }

    set data(currentTheme) $currentTheme
    set data(themeDefaults) [array get themeDefaults]
    if {[string compare $currentTheme "tileqt"] == 0} {
	set data(widgetStyle) [tileqt_currentThemeName]
	if {[info exists ::env(KDE_SESSION_VERSION)] &&
	    [string length $::env(KDE_SESSION_VERSION)] != 0} {
	    set data(colorScheme) [getKdeConfigVal "General" "ColorScheme"]
	} else {
	    set data(colorScheme) [getKdeConfigVal "KDE" "colorScheme"]
	}
    } else {
	set data(widgetStyle) ""
	set data(colorScheme) ""
    }
}

#
# Binding tag TablelistWindow
# ===========================
#

#------------------------------------------------------------------------------
# tablelist::cleanupWindow
#
# This procedure is invoked when a window aux embedded into a tablelist widget
# is destroyed.  It invokes the cleanup script associated with the cell
# containing the window, if any.
#------------------------------------------------------------------------------
proc tablelist::cleanupWindow aux {
    regexp {^(.+)\.body\.frm_(k[0-9]+),([0-9]+)$} $aux dummy win key col
    upvar ::tablelist::ns${win}::data data
    if {[info exists data($key,$col-windowdestroy)]} {
	set row [keyToRow $win $key]
	uplevel #0 $data($key,$col-windowdestroy) [list $win $row $col $aux.w]
    }
}

#
# Binding tag TablelistBody
# =========================
#

#------------------------------------------------------------------------------
# tablelist::defineTablelistBody
#
# Defines the bindings for the binding tag TablelistBody.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistBody {} {
    variable priv
    array set priv {
	x			""
	y			""
	afterId			""
	prevRow			""
	prevCol			""
	prevActExpCollCtrlCell	""
	selection		{}
	selClearPending		0
	selChangePending	0
	justClicked		0
	justReleased		0
	clickedInEditWin	0
	clickedExpCollCtrl	0
    }

    foreach event {<Enter> <Motion> <Leave>} {
	bind TablelistBody $event [format {
	    tablelist::handleMotionDelayed %%W %%x %%y %%X %%Y %%m %s
	} $event]
    }
    bind TablelistBody <Button-1> {
	if {[winfo exists %W]} {
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}

	    set tablelist::priv(x) $tablelist::x
	    set tablelist::priv(y) $tablelist::y
	    set tablelist::priv(row) [$tablelist::W nearest       $tablelist::y]
	    set tablelist::priv(col) [$tablelist::W nearestcolumn $tablelist::x]
	    set tablelist::priv(justClicked) 1
	    after 300 [list set tablelist::priv(justClicked) 0]
	    set tablelist::priv(clickedInEditWin) 0
	    if {[$tablelist::W cget -setfocus] &&
		[string compare [$tablelist::W cget -state] "normal"] == 0} {
		focus [$tablelist::W bodypath]
	    }
	    if {[tablelist::wasExpCollCtrlClicked %W %x %y]} {
		set tablelist::priv(clickedExpCollCtrl) 1
		if {[string length [$tablelist::W editwinpath]] != 0} {
		    tablelist::doFinishEditing $tablelist::W
		}
	    } else {
		tablelist::condEditContainingCell $tablelist::W \
		    $tablelist::x $tablelist::y
		set tablelist::priv(row) \
		    [$tablelist::W nearest       $tablelist::y]
		set tablelist::priv(col) \
		    [$tablelist::W nearestcolumn $tablelist::x]
		tablelist::condBeginMove $tablelist::W $tablelist::priv(row)
		tablelist::beginSelect $tablelist::W \
		    $tablelist::priv(row) $tablelist::priv(col) 1
	    }
	}
    }
    bind TablelistBody <Double-Button-1> {
	if {[winfo exists %W]} {
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}

	    if {[$tablelist::W cget -editselectedonly]} {
		tablelist::condEditContainingCell $tablelist::W \
		    $tablelist::x $tablelist::y
	    }
	}
    }
    bind TablelistBody <B1-Motion> {
	if {$tablelist::priv(justClicked)} {
	    continue
	}

	foreach {tablelist::W tablelist::x tablelist::y} \
	    [tablelist::convEventFields %W %x %y] {}

	if {[string length $tablelist::priv(x)] == 0 ||
	    [string length $tablelist::priv(y)] == 0} {
	    set tablelist::priv(x) $tablelist::x
	    set tablelist::priv(y) $tablelist::y
	}
	set tablelist::priv(prevX) $tablelist::priv(x)
	set tablelist::priv(prevY) $tablelist::priv(y)
	set tablelist::priv(x) $tablelist::x
	set tablelist::priv(y) $tablelist::y
	tablelist::condAutoScan $tablelist::W
	if {!$tablelist::priv(clickedExpCollCtrl)} {
	    tablelist::motion $tablelist::W \
		[$tablelist::W nearest       $tablelist::y] \
		[$tablelist::W nearestcolumn $tablelist::x] 1
	    tablelist::condShowTarget $tablelist::W $tablelist::y
	}
    }
    bind TablelistBody <ButtonRelease-1> {
	if {[winfo exists %W]} {
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}

	    set tablelist::priv(x) ""
	    set tablelist::priv(y) ""
	    after cancel $tablelist::priv(afterId)
	    set tablelist::priv(afterId) ""
	    set tablelist::priv(justReleased) 1
	    after 100 [list set tablelist::priv(justReleased) 0]
	    set tablelist::priv(releasedInEditWin) 0
	    if {!$tablelist::priv(clickedExpCollCtrl)} {
		if {$tablelist::priv(justClicked)} {
		    tablelist::moveOrActivate $tablelist::W \
			$tablelist::priv(row) $tablelist::priv(col) 1
		} else {
		    tablelist::moveOrActivate $tablelist::W \
			[$tablelist::W nearest       $tablelist::y] \
			[$tablelist::W nearestcolumn $tablelist::x] \
			[expr {$tablelist::x >= 0 &&
			       $tablelist::x < [winfo width $tablelist::W] &&
			       $tablelist::y >= [winfo y $tablelist::W.body] &&
			       $tablelist::y < [winfo height $tablelist::W]}]
		}
	    }
	    set tablelist::priv(clickedExpCollCtrl) 0
	    after 100 [list tablelist::condEvalInvokeCmd $tablelist::W]
	}
    }
    bind TablelistBody <Shift-Button-1> {
	foreach {tablelist::W tablelist::x tablelist::y} \
	    [tablelist::convEventFields %W %x %y] {}

	tablelist::beginExtend $tablelist::W \
	    [$tablelist::W nearest       $tablelist::y] \
	    [$tablelist::W nearestcolumn $tablelist::x]
    }
    bind TablelistBody <Control-Button-1> {
	foreach {tablelist::W tablelist::x tablelist::y} \
	    [tablelist::convEventFields %W %x %y] {}

	tablelist::beginToggle $tablelist::W \
	    [$tablelist::W nearest       $tablelist::y] \
	    [$tablelist::W nearestcolumn $tablelist::x]
    }

    bind TablelistBody <Return> {
	tablelist::condEditActiveCell [tablelist::getTablelistPath %W]
    }
    bind TablelistBody <KP_Enter> {
	tablelist::condEditActiveCell [tablelist::getTablelistPath %W]
    }
    bind TablelistBody <Tab> {
	tablelist::nextPrevCell [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody <Shift-Tab> {
	tablelist::nextPrevCell [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody <<PrevWindow>> {
	tablelist::nextPrevCell [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody <plus> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] plus
    }
    bind TablelistBody <minus> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] minus
    }
    bind TablelistBody <KP_Add> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] plus
    }
    bind TablelistBody <KP_Subtract> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] minus
    }

    foreach {virtual event} {
	PrevLine <Up>		 NextLine <Down>
	PrevChar <Left>		 NextChar <Right>
	LineStart <Home>	 LineEnd <End>
	PrevWord <Control-Left>	 NextWord <Control-Right>

	SelectPrevLine <Shift-Up>     SelectNextLine <Shift-Down>
	SelectPrevChar <Shift-Left>   SelectNextChar <Shift-Right>
	SelectLineStart <Shift-Home>  SelectLineEnd <Shift-End>
	SelectAll <Control-slash>     SelectNone <Control-backslash>} {
	if {[llength [event info <<$virtual>>]] == 0} {
	    set eventArr($virtual) $event
	} else {
	    set eventArr($virtual) <<$virtual>>
	}
    }

    bind TablelistBody $eventArr(PrevLine) {
	tablelist::upDown [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(NextLine) {
	tablelist::upDown [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(PrevChar) {
	tablelist::leftRight [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(NextChar) {
	tablelist::leftRight [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody <Prior> {
	tablelist::priorNext [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody <Next> {
	tablelist::priorNext [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(LineStart) {
	tablelist::homeEnd [tablelist::getTablelistPath %W] Home
    }
    bind TablelistBody $eventArr(LineEnd) {
	tablelist::homeEnd [tablelist::getTablelistPath %W] End
    }
    bind TablelistBody <Control-Home> {
	tablelist::firstLast [tablelist::getTablelistPath %W] first
    }
    bind TablelistBody <Control-End> {
	tablelist::firstLast [tablelist::getTablelistPath %W] last
    }
    bind TablelistBody $eventArr(SelectPrevLine) {
	tablelist::extendUpDown [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(SelectNextLine) {
	tablelist::extendUpDown [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(SelectPrevChar) {
	tablelist::extendLeftRight [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(SelectNextChar) {
	tablelist::extendLeftRight [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(SelectLineStart) {
	tablelist::extendToHomeEnd [tablelist::getTablelistPath %W] Home
    }
    bind TablelistBody $eventArr(SelectLineEnd) {
	tablelist::extendToHomeEnd [tablelist::getTablelistPath %W] End
    }
    bind TablelistBody <Shift-Control-Home> {
	tablelist::extendToFirstLast [tablelist::getTablelistPath %W] first
    }
    bind TablelistBody <Shift-Control-End> {
	tablelist::extendToFirstLast [tablelist::getTablelistPath %W] last
    }
    bind TablelistBody <space> {
	set tablelist::W [tablelist::getTablelistPath %W]

	tablelist::beginSelect $tablelist::W \
	    [$tablelist::W index active] [$tablelist::W columnindex active]
    }
    bind TablelistBody <Select> {
	set tablelist::W [tablelist::getTablelistPath %W]

	tablelist::beginSelect $tablelist::W \
	    [$tablelist::W index active] [$tablelist::W columnindex active]
    }
    bind TablelistBody <Control-Shift-space> {
	set tablelist::W [tablelist::getTablelistPath %W]

	tablelist::beginExtend $tablelist::W \
	    [$tablelist::W index active] [$tablelist::W columnindex active]
    }
    bind TablelistBody <Shift-Select> {
	set tablelist::W [tablelist::getTablelistPath %W]

	tablelist::beginExtend $tablelist::W \
	    [$tablelist::W index active] [$tablelist::W columnindex active]
    }
    bind TablelistBody <Escape> {
	tablelist::cancelSelection [tablelist::getTablelistPath %W]
    }
    bind TablelistBody $eventArr(SelectAll) {
	tablelist::selectAll [tablelist::getTablelistPath %W]
    }
    bind TablelistBody $eventArr(SelectNone) {
	set tablelist::W [tablelist::getTablelistPath %W]

	if {[string compare [$tablelist::W cget -selectmode] "browse"] != 0} {
	    $tablelist::W selection clear 0 end
	    event generate $tablelist::W <<TablelistSelect>>
	}
    }
    foreach pattern {Tab Shift-Tab ISO_Left_Tab hpBackTab} {
	catch {
	    foreach modifier {Control Meta} {
		bind TablelistBody <$modifier-$pattern> [format {
		    mwutil::processTraversal %%W Tablelist <%s>
		} $pattern]
	    }
	}
    }

    variable winSys
    catch {
	if {[string compare $winSys "classic"] == 0 ||
	    [string compare $winSys "aqua"] == 0} {
	    bind TablelistBody <MouseWheel> {
		[tablelist::getTablelistPath %W] yview scroll [expr {-%D}] units
		break
	    }
	    bind TablelistBody <Shift-MouseWheel> {
		[tablelist::getTablelistPath %W] xview scroll [expr {-%D}] units
		break
	    }
	    bind TablelistBody <Option-MouseWheel> {
		[tablelist::getTablelistPath %W] yview scroll \
		    [expr {-10 * %D}] units
		break
	    }
	    bind TablelistBody <Shift-Option-MouseWheel> {
		[tablelist::getTablelistPath %W] xview scroll \
		    [expr {-10 * %D}] units
		break
	    }
	} else {
	    bind TablelistBody <MouseWheel> {
		[tablelist::getTablelistPath %W] yview scroll \
		    [expr {-(%D / 120) * 4}] units
		break
	    }
	    bind TablelistBody <Shift-MouseWheel> {
		[tablelist::getTablelistPath %W] xview scroll \
		    [expr {-(%D / 120) * 4}] units
		break
	    }
	}
    }

    if {[string compare $winSys "x11"] == 0} {
	bind TablelistBody <Button-4> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] yview scroll -5 units
		break
	    }
	}
	bind TablelistBody <Button-5> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] yview scroll 5 units
		break
	    }
	}
	bind TablelistBody <Shift-Button-4> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] xview scroll -5 units
		break
	    }
	}
	bind TablelistBody <Shift-Button-5> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] xview scroll 5 units
		break
	    }
	}
    }

    foreach event {<Control-Left> <<PrevWord>> <Control-Right> <<NextWord>>
		   <Control-Prior> <Control-Next> <<Copy>>
		   <Button-2> <B2-Motion>} {
	set script [strMap {
	    "%W" "$tablelist::W"  "%x" "$tablelist::x"  "%y" "$tablelist::y"
	} [bind Listbox $event]]

	if {[string length $script] != 0} {
	    bind TablelistBody $event [format {
		if {[winfo exists %%W]} {
		    foreach {tablelist::W tablelist::x tablelist::y} \
			[tablelist::convEventFields %%W %%x %%y] {}
		    %s
		}
	    } $script]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::invokeMotionHandler
#
# Invokes the procedure handleMotionDelayed for the body of the tablelist
# widget win and the current pointer coordinates.
#------------------------------------------------------------------------------
proc tablelist::invokeMotionHandler win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set X [winfo pointerx $w]
    set Y [winfo pointery $w]
    if {$X >= 0 && $Y >= 0} {	;# the mouse pointer is on the same screen as w
	set x [expr {$X - [winfo rootx $w]}]
	set y [expr {$Y - [winfo rooty $w]}]
    } else {
	set x -1
	set y -1
    }

    handleMotionDelayed $w $x $y $X $Y "" <Motion>
}

#------------------------------------------------------------------------------
# tablelist::handleMotionDelayed
#
# This procedure is invoked when the mouse pointer enters or leaves the body of
# a tablelist widget or one of its separators, or is moving within it.  It
# schedules the execution of the handleMotion procedure 100 ms later.
#------------------------------------------------------------------------------
proc tablelist::handleMotionDelayed {w x y X Y mode event} {
    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data
    set data(motionData) [list $w $x $y $X $Y $event]
    if {![info exists data(motionId)]} {
	set data(motionId) [after 100 [list tablelist::handleMotion $win]]
    }

    if {[string compare $event "<Enter>"] == 0 &&
	[string compare $mode "NotifyNormal"] == 0} {
	set data(justEntered) 1
    }
}

#------------------------------------------------------------------------------
# tablelist::handleMotion
#
# Invokes the procedures showOrHideTooltip, updateExpCollCtrl, and updateCursor.
#------------------------------------------------------------------------------
proc tablelist::handleMotion win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(motionId)]} {
	after cancel $data(motionId)
	unset data(motionId)
    }

    set data(justEntered) 0

    foreach {w x y X Y event} $data(motionData) {}
    if {![winfo exists $w]} {
	invokeMotionHandler $win
	return ""
    }

    #
    # Get the containing cell from the coordinates relative to the tablelist
    #
    foreach {win _x _y} [convEventFields $w $x $y] {}
    set row [containingRow $win $_y]
    set col [containingCol $win $_x]

    showOrHideTooltip $win $row $col $X $Y
    updateExpCollCtrl $win $w $row $col $x

    #
    # Make sure updateCursor won't change the cursor of an embedded window
    #
    if {[string match "$data(body).frm_k*" $w] &&
	[string compare [winfo parent $w] $data(body)] == 0 &&
	[string compare $event "<Leave>"] != 0} {
	set row -1
	set col -1
    }

    updateCursor $win $row $col
}

#------------------------------------------------------------------------------
# tablelist::showOrHideTooltip
#
# If the pointer has crossed a cell boundary then the procedure removes the old
# tooltip and displays the one corresponding to the new cell.
#------------------------------------------------------------------------------
proc tablelist::showOrHideTooltip {win row col X Y} {
    upvar ::tablelist::ns${win}::data data
    if {[string length $data(-tooltipaddcommand)] == 0 ||
	[string length $data(-tooltipdelcommand)] == 0 ||
	[string compare $row,$col $data(prevCell)] == 0} {
	return ""
    }

    #
    # Remove the old tooltip, if any.  Then, if we are within a
    # cell, display the new tooltip corresponding to that cell.
    #
    event generate $win <Leave>
    catch {uplevel #0 $data(-tooltipdelcommand) [list $win]}
    set data(prevCell) $row,$col
    if {$row >= 0 && $col >= 0} {
	set focus [focus -displayof $win]
	if {[string length $focus] == 0 || [string first $win $focus] != 0 ||
	    [string compare [winfo toplevel $focus] \
	     [winfo toplevel $win]] == 0} {
	    uplevel #0 $data(-tooltipaddcommand) [list $win $row $col]
	    event generate $win <Enter> -rootx $X -rooty $Y
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateExpCollCtrl
#
# Activates or deactivates the expand/collapse control under the mouse pointer.
#------------------------------------------------------------------------------
proc tablelist::updateExpCollCtrl {win w row col x} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set indentLabel $data(body).ind_$key,$col

    #
    # Check whether the x coordinate is inside the expand/collapse control
    #
    set inExpCollCtrl 0
    if {[winfo exists $indentLabel]} {
	if {[string compare $w $data(body)] == 0 &&
	    $x < [winfo x $indentLabel] &&
	    [string compare $data($key-parent) "root"] == 0} {
	    set imgName [$indentLabel cget -image]
	    if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
			 $imgName dummy treeStyle mode depth]} {
		#
		# The mouse position is in the tablelist body, to the left
		# of an expand/collapse control of a top-level item:  Handle
		# this like a position inside the expand/collapse control
		#
		set inExpCollCtrl 1
	    }
	} elseif {[string compare $w $indentLabel] == 0} {
	    set imgName [$w cget -image]
	    if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
			 $imgName dummy treeStyle mode depth]} {
		#
		# The mouse position is in an expand/collapse
		# image (which ends with the expand/collapse
		# control):  Check whether it is inside the control
		#
		set baseWidth [image width tablelist_${treeStyle}_collapsedImg]
		if {$x >= [winfo width $w] - $baseWidth - 5} {
		    set inExpCollCtrl 1
		}
	    }
	}
    }

    #
    # Conditionally deactivate the previously activated expand/collapse control
    #
    variable priv
    set prevCellIdx $priv(prevActExpCollCtrlCell)
    if {[string length $prevCellIdx] != 0 &&
	[info exists data($prevCellIdx-indent)] &&
	(!$inExpCollCtrl || [string compare $prevCellIdx $key,$col] != 0) &&
	[winfo exists $data(body).ind_$prevCellIdx]} {
	set data($prevCellIdx-indent) \
	    [strMap {"Act" ""} $data($prevCellIdx-indent)]
	$data(body).ind_$prevCellIdx configure -image $data($prevCellIdx-indent)
	set priv(prevActExpCollCtrlCell) ""
    }

    if {!$inExpCollCtrl || [string compare $prevCellIdx $key,$col] == 0} {
	return ""
    }

    #
    # Activate the expand/collapse control under the mouse pointer
    #
    variable ${treeStyle}_collapsedActImg
    if {[info exists ${treeStyle}_collapsedActImg]} {
	set data($key,$col-indent) [strMap {
	    "SelActImg" "SelActImg" "SelImg" "SelActImg"
	    "ActImg" "ActImg" "Img" "ActImg"
	} $data($key,$col-indent)]
	$indentLabel configure -image $data($key,$col-indent)
	set priv(prevActExpCollCtrlCell) $key,$col
    }
}

#------------------------------------------------------------------------------
# tablelist::updateCursor
#
# Updates the cursor of the body component of the tablelist widget win, over
# the specified cell containing the mouse pointer.
#------------------------------------------------------------------------------
proc tablelist::updateCursor {win row col} {
    upvar ::tablelist::ns${win}::data data
    if {$data(inEditWin)} {
	set cursor $data(-cursor)
    } elseif {$data(-showeditcursor)} {
	if {$data(-editselectedonly) &&
	    ![::$win cellselection includes $row,$col]} {
	    set editable 0
	} else {
	    set editable [expr {$row >= 0 && $col >= 0 &&
			  [isCellEditable $win $row $col]}]
	}

	if {$editable} {
	    if {$row == $data(editRow) && $col == $data(editCol)} {
		set cursor $data(-cursor)
	    } else {
		variable editCursor
		if {![info exists editCursor]} {
		    makeEditCursor 
		}
		set cursor $editCursor
	    }
	} else {
	    set cursor $data(-cursor)
	}

	#
	# Special handling for cell editing with the aid of BWidget
	# ComboBox. Oakley combobox, or Tk menubutton widgets
	#
	if {$data(editRow) >= 0 && $data(editCol) >= 0} {
	    foreach c [winfo children $data(bodyFrEd)] {
		set class [winfo class $c]
		if {([string compare $class "Toplevel"] == 0 ||
		     [string compare $class "Menu"] == 0) &&
		     [winfo ismapped $c]} {
		    set cursor $data(-cursor)
		    break
		}
	    }
	}
    } else {
	set cursor $data(-cursor)
    }

    if {[string compare [$data(body) cget -cursor] $cursor] != 0} {
	$data(body) configure -cursor $cursor
    }
}

#------------------------------------------------------------------------------
# tablelist::makeEditCursor
#
# Creates the platform-specific edit cursor.
#------------------------------------------------------------------------------
proc tablelist::makeEditCursor {} {
    variable editCursor
    variable winSys

    if {[string compare $winSys "win32"] == 0} {
	variable library
	set cursorName "pencil.cur"
	set cursorFile [file join $library scripts $cursorName]
	if {$::tcl_version >= 8.4} {
	    set cursorFile [file normalize $cursorFile]
	}
	set editCursor [list @$cursorFile]

	#
	# Make sure it will work for starpacks, too
	#
	variable helpLabel
	if {[catch {$helpLabel configure -cursor $editCursor}] != 0} {
	    set tempDir $::env(TEMP)
	    file copy -force $cursorFile $tempDir
	    set editCursor [list @[file join $tempDir $cursorName]]
	}
    } else {
	set editCursor pencil
    }
}

#------------------------------------------------------------------------------
# tablelist::wasExpCollCtrlClicked
#
# This procedure is invoked when mouse button 1 is pressed in the body of a
# tablelist widget or in one of its separators.  It checks whether the mouse
# click occurred inside an expand/collapse control.
#------------------------------------------------------------------------------
proc tablelist::wasExpCollCtrlClicked {w x y} {
    foreach {win _x _y} [convEventFields $w $x $y] {}
    set row [containingRow $win $_y]
    set col [containingCol $win $_x]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set indentLabel $data(body).ind_$key,$col
    if {![winfo exists $indentLabel]} {
	return 0
    }

    #
    # Check whether the x coordinate is inside the expand/collapse control
    #
    set inExpCollCtrl 0
    if {[string compare $w $data(body)] == 0 && $x < [winfo x $indentLabel] &&
	[string compare $data($key-parent) "root"] == 0} {
	set imgName [$indentLabel cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    #
	    # The mouse position is in the tablelist body, to the left
	    # of an expand/collapse control of a top-level item:  Handle
	    # this like a position inside the expand/collapse control
	    #
	    set inExpCollCtrl 1
	}
    } elseif {[string compare $w $indentLabel] == 0} {
	set imgName [$w cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    #
	    # The mouse position is in an expand/collapse
	    # image (which ends with the expand/collapse
	    # control):  Check whether it is inside the control
	    #
	    set baseWidth [image width tablelist_${treeStyle}_collapsedImg]
	    if {$x >= [winfo width $w] - $baseWidth - 5} {
		set inExpCollCtrl 1
	    }
	}
    }

    if {!$inExpCollCtrl} {
	return 0
    }

    #
    # Save the current vertical position
    #
    set topRow [expr {int([$data(body) index @0,0]) - 1}]

    #
    # Toggle the state of the expand/collapse control
    #
    if {[string compare $mode "collapsed"] == 0} {
	::$win expand $row -partly
    } else {
	::$win collapse $row -partly
    }

    #
    # Restore the saved vertical position
    #
    $data(body) yview $topRow
    updateViewWhenIdle $win

    return 1
}

#------------------------------------------------------------------------------
# tablelist::condEditContainingCell
#
# This procedure is invoked when mouse button 1 is pressed in the body of a
# tablelist widget win or in one of its separators.  If the mouse click
# occurred inside an editable cell and the latter is not already being edited,
# then the procedure starts the interactive editing in that cell.  Otherwise it
# finishes a possibly active cell editing.
#------------------------------------------------------------------------------
proc tablelist::condEditContainingCell {win x y} {
    #
    # Get the containing cell from the coordinates relative to the parent
    #
    set row [containingRow $win $y]
    set col [containingCol $win $x]

    upvar ::tablelist::ns${win}::data data
    if {$data(justEntered) || ($data(-editselectedonly) &&
	![::$win cellselection includes $row,$col])} {
	set editable 0
    } else {
	set editable [expr {$row >= 0 && $col >= 0 &&
		      [isCellEditable $win $row $col]}]
    }

    #
    # The following check is sometimes needed on OS X if
    # editing with the aid of a menubutton is in progress
    #
    variable editCursor
    if {($row != $data(editRow) || $col != $data(editCol)) &&
	$data(-showeditcursor) && [info exists editCursor] &&
	[string compare [$data(body) cget -cursor] $editCursor] != 0} {
	set editable 0
    }

    if {$editable} {
	#
	# Get the coordinates relative to the
	# tablelist body and invoke doEditCell
	#
	set w $data(body)
	incr x -[winfo x $w]
	incr y -[winfo y $w]
	scan [$w index @$x,$y] "%d.%d" line charPos
	doEditCell $win $row $col 0 "" $charPos
    } elseif {$data(editRow) >= 0} {
	#
	# Finish the current editing
	#
	doFinishEditing $win
    }
}

#------------------------------------------------------------------------------
# tablelist::condBeginMove
#
# This procedure is typically invoked on button-1 presses in the body of a
# tablelist widget or in one of its separators.  It begins the process of
# moving the nearest row if the rows are movable and the selection mode is not
# browse or extended.
#------------------------------------------------------------------------------
proc tablelist::condBeginMove {win row} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || !$data(-movablerows) || $data(itemCount) == 0 ||
	[string compare $data(-selectmode) "browse"] == 0 ||
	[string compare $data(-selectmode) "extended"] == 0} {
	return ""
    }

    set data(sourceRow) $row
    set sourceKey [lindex $data(keyList) $row]
    set data(sourceEndRow) [nodeRow $win $sourceKey end]
    set data(sourceDescCount) [descCount $win $sourceKey]

    set data(sourceParentKey) $data($sourceKey-parent)
    set data(sourceParentRow) [keyToRow $win $data(sourceParentKey)]
    set data(sourceParentEndRow) [nodeRow $win $data(sourceParentKey) end]

    set topWin [winfo toplevel $win]
    set data(topEscBinding) [bind $topWin <Escape>]
    bind $topWin <Escape> [list tablelist::cancelMove [strMap {"%" "%%"} $win]]
}

#------------------------------------------------------------------------------
# tablelist::beginSelect
#
# This procedure is typically invoked on button-1 presses in the body of a
# tablelist widget or in one of its separators.  It begins the process of
# making a selection in the widget.  Its exact behavior depends on the
# selection mode currently in effect for the widget.
#------------------------------------------------------------------------------
proc tablelist::beginSelect {win row col {checkIfDragSrc 0}} {
    variable priv
    set priv(selClearPending) 0
    set priv(selChangePending) 0

    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    if {[string compare $data(-selectmode) "multiple"] == 0} {
		if {[::$win selection includes $row]} {
		    if {$checkIfDragSrc && [isDragSrc $win]} {
			set priv(selClearPending) 1
		    } else {
			::$win selection clear $row
		    }
		} else {
		    ::$win selection set $row
		}
	    } else {
		if {[::$win selection includes $row] &&
		    $checkIfDragSrc && [isDragSrc $win]} {
		    set priv(selChangePending) 1
		} else {
		    ::$win selection clear 0 end
		    ::$win selection set $row
		}
		::$win selection anchor $row
		set priv(selection) {}
	    }

	    set priv(prevRow) $row
	}

	cell {
	    if {[string compare $data(-selectmode) "multiple"] == 0} {
		if {[::$win cellselection includes $row,$col]} {
		    if {$checkIfDragSrc && [isDragSrc $win]} {
			set priv(selClearPending) 1
		    } else {
			::$win cellselection clear $row,$col
		    }
		} else {
		    ::$win cellselection set $row,$col
		}
	    } else {
		if {[::$win cellselection includes $row,$col] &&
		    $checkIfDragSrc && [isDragSrc $win]} {
		    set priv(selChangePending) 1
		} else {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set $row,$col
		}
		::$win cellselection anchor $row,$col
		set priv(selection) {}
	    }

	    set priv(prevRow) $row
	    set priv(prevCol) $col
	}
    }

    event generate $win <<TablelistSelect>>
}

#------------------------------------------------------------------------------
# tablelist::condAutoScan
#
# This procedure is invoked when the mouse leaves or enters the scrollable part
# of a tablelist widget's body text child while button 1 is down.  It either
# invokes the autoScan procedure or cancels its executon as an "after" command.
#------------------------------------------------------------------------------
proc tablelist::condAutoScan win {
    variable priv
    set w [::$win bodypath]
    set wX [winfo x $w]
    set wY [winfo y $w]
    set wWidth  [winfo width  $w]
    set wHeight [winfo height $w]
    set x [expr {$priv(x) - $wX}]
    set y [expr {$priv(y) - $wY}]
    set prevX [expr {$priv(prevX) - $wX}]
    set prevY [expr {$priv(prevY) - $wY}]
    set minX [minScrollableX $win]

    if {($y >= $wHeight && $prevY < $wHeight) ||
	($y < 0 && $prevY >= 0) ||
	($x >= $wWidth && $prevX < $wWidth) ||
	($x < $minX && $prevX >= $minX)} {
	if {[string length $priv(afterId)] == 0} {
	    autoScan $win
	}
    } elseif {($y < $wHeight && $prevY >= $wHeight) ||
	      ($y >= 0 && $prevY < 0) ||
	      ($x < $wWidth && $prevX >= $wWidth) ||
	      ($x >= $minX && $prevX < $minX)} {
	after cancel $priv(afterId)
	set priv(afterId) ""
    }
}

#------------------------------------------------------------------------------
# tablelist::autoScan
#
# This procedure is invoked when the mouse leaves the scrollable part of a
# tablelist widget's body text child while button 1 is down.  It scrolls the
# child up, down, left, or right, depending on where the mouse left the
# scrollable part of the tablelist's body, and reschedules itself as an "after"
# command so that the child continues to scroll until the mouse moves back into
# the window or the mouse button is released.
#------------------------------------------------------------------------------
proc tablelist::autoScan win {
    if {![array exists ::tablelist::ns${win}::data] || [isDragSrc $win] ||
	[string length [::$win editwinpath]] != 0} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(-autoscan)} {
	return ""
    }

    variable priv
    set w [::$win bodypath]
    set x [expr {$priv(x) - [winfo x $w]}]
    set y [expr {$priv(y) - [winfo y $w]}]
    set minX [minScrollableX $win]

    if {$y >= [winfo height $w]} {
	::$win yview scroll 1 units
	set ms 50
    } elseif {$y < 0} {
	::$win yview scroll -1 units
	set ms 50
    } elseif {$x >= [winfo width $w]} {
	if {$data(-titlecolumns) == 0} {
	    ::$win xview scroll 2 units
	    set ms 50
	} else {
	    ::$win xview scroll 1 units
	    set ms 250
	}
    } elseif {$x < $minX} {
	if {$data(-titlecolumns) == 0} {
	    ::$win xview scroll -2 units
	    set ms 50
	} else {
	    ::$win xview scroll -1 units
	    set ms 250
	}
    } else {
	return ""
    }

    motion $win [::$win nearest $priv(y)] [::$win nearestcolumn $priv(x)] 1
    if {[string length $tablelist::priv(x)] != 0 &&
	[string length $tablelist::priv(y)] != 0} {
	set priv(afterId) [after $ms [list tablelist::autoScan $win]]
    }
}

#------------------------------------------------------------------------------
# tablelist::minScrollableX
#
# Returns the least x coordinate within the scrollable part of the body of the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::minScrollableX win {
    upvar ::tablelist::ns${win}::data data
    if {$data(-titlecolumns) == 0} {
	return 0
    } else {
	set sep [::$win separatorpath]
	if {[winfo viewable $sep]} {
	    return [expr {[winfo x $sep] - [winfo x [::$win bodypath]] + 1}]
	} else {
	    return 0
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::motion
#
# This procedure is called to process mouse motion events in the body of a
# tablelist widget or in one of its separators. while button 1 is down.  It may
# move or extend the selection, depending on the widget's selection mode.
#------------------------------------------------------------------------------
proc tablelist::motion {win row col {checkIfDragSrc 0}} {
    if {$checkIfDragSrc && [isDragSrc $win]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    variable priv
    switch $data(-selecttype) {
	row {
	    set prRow $priv(prevRow)
	    if {$row == $prRow} {
		return ""
	    }

	    switch -- $data(-selectmode) {
		browse {
		    ::$win selection clear 0 end
		    ::$win selection set $row
		    set priv(prevRow) $row
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    if {[string length $prRow] == 0} {
			set prRow $row
			::$win selection set $row
		    }

		    if {[::$win selection includes anchor]} {
			::$win selection clear $prRow $row
			::$win selection set anchor $row
		    } else {
			::$win selection clear $prRow $row
			::$win selection clear anchor $row
		    }

		    set ancRow $data(anchorRow)
		    foreach r $priv(selection) {
			if {($r >= $prRow && $r < $row && $r < $ancRow) ||
			    ($r <= $prRow && $r > $row && $r > $ancRow)} {
			    ::$win selection set $r
			}
		    }

		    set priv(prevRow) $row
		    event generate $win <<TablelistSelect>>
		}
	    }
	}

	cell {
	    set prRow $priv(prevRow)
	    set prCol $priv(prevCol)
	    if {$row == $prRow && $col == $prCol} {
		return ""
	    }

	    switch -- $data(-selectmode) {
		browse {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set $row,$col
		    set priv(prevRow) $row
		    set priv(prevCol) $col
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    if {[string length $prRow] == 0 ||
			[string length $prCol] == 0} {
			set prRow $row
			set prcol $col
			::$win cellselection set $row,$col
		    }

		    set ancRow $data(anchorRow)
		    set ancCol $data(anchorCol)
		    if {[::$win cellselection includes anchor]} {
			::$win cellselection clear $prRow,$prCol $row,$ancCol
			::$win cellselection clear $prRow,$prCol $ancRow,$col
			::$win cellselection set anchor $row,$col
		    } else {
			::$win cellselection clear $prRow,$prCol $row,$ancCol
			::$win cellselection clear $prRow,$prCol $ancRow,$col
			::$win cellselection clear anchor $row,$col
		    }

		    foreach {rMin1 cMin1 rMax1 cMax1} \
			[normalizedRect $prRow $prCol $row $ancCol] {}
		    foreach {rMin2 cMin2 rMax2 cMax2} \
			[normalizedRect $prRow $prCol $ancRow $col] {}
		    foreach {rMin3 cMin3 rMax3 cMax3} \
			[normalizedRect $ancRow $ancCol $row $col] {}
		    foreach cellIdx $priv(selection) {
			scan $cellIdx "%d,%d" r c
			if {([cellInRect $r $c $rMin1 $cMin1 $rMax1 $cMax1] ||
			     [cellInRect $r $c $rMin2 $cMin2 $rMax2 $cMax2]) &&
			    ![cellInRect $r $c $rMin3 $cMin3 $rMax3 $cMax3]} {
			    ::$win cellselection set $r,$c
			}
		    }

		    set priv(prevRow) $row
		    set priv(prevCol) $col
		    event generate $win <<TablelistSelect>>
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::condShowTarget
#
# This procedure is called to process mouse motion events in the body of a
# tablelist widget or in one of its separators. while button 1 is down.  It
# visualizes the would-be target position of the clicked row if a move
# operation is in progress.
#------------------------------------------------------------------------------
proc tablelist::condShowTarget {win y} {
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(sourceRow)]} {
	return ""
    }

    set indentImg [doCellCget $data(sourceRow) $data(treeCol) $win -indent]
    set w $data(body)
    incr y -[winfo y $w]
    set textIdx [$w index @0,$y]
    set dlineinfo [$w dlineinfo $textIdx]
    set lineY [lindex $dlineinfo 1]
    set lineHeight [lindex $dlineinfo 3]
    set row [expr {int($textIdx) - 1}]

    if {$::tk_version < 8.3 || [string length $indentImg] == 0} {
	if {$y < $lineY + $lineHeight/2} {
	    set data(targetRow) $row
	    set gapY $lineY
	} else {
	    set y [expr {$lineY + $lineHeight}]
	    set textIdx [$w index @0,$y]
	    set row2 [expr {int($textIdx) - 1}]
	    if {$row2 == $row} {
		set row2 $data(itemCount)
	    }
	    set data(targetRow) $row2
	    set gapY $y
	}
	set data(targetChildIdx) -1
    } else {
	if {$y < $lineY + $lineHeight/4} {
	    set data(targetRow) $row
	    set data(targetChildIdx) -1
	    set gapY $lineY
	} elseif {$y < $lineY + $lineHeight*3/4} {
	    set data(targetRow) $row
	    set data(targetChildIdx) 0
	    set gapY [expr {$lineY + $lineHeight/2}]
	} else {
	    set y [expr {$lineY + $lineHeight}]
	    set textIdx [$w index @0,$y]
	    set row2 [expr {int($textIdx) - 1}]
	    if {$row2 == $row} {
		set row2 $data(itemCount)
	    }
	    set data(targetRow) $row2
	    set data(targetChildIdx) -1
	    set gapY $y
	}
    }

    #
    # Get the key and node index of the potential target parent
    #
    if {$data(targetRow) > $data(lastRow)} {
	if {$data(targetRow) > $data(sourceParentEndRow)} {
	    set targetParentKey root
	    set targetParentNodeIdx root
	} else {
	    set targetParentKey $data(sourceParentKey)
	    set targetParentNodeIdx $data(sourceParentRow)
	}
    } elseif {$data(targetChildIdx) == 0} {
	set targetParentKey [lindex $data(keyList) $data(targetRow)]
	set targetParentNodeIdx $data(targetRow)
    } else {
	set targetParentKey [::$win parentkey $data(targetRow)]
	set targetParentNodeIdx [keyToRow $win $targetParentKey]
	if {$targetParentNodeIdx < 0} {
	    set targetParentNodeIdx root
	}
    }

    if {($data(targetRow) == $data(sourceRow)) ||

	($data(targetRow) == $data(sourceParentRow) &&
	 $data(targetChildIdx) == 0) ||

	($data(targetRow) == $data(sourceEndRow) &&
	 $data(targetChildIdx) < 0) ||

	($data(targetRow) > $data(sourceRow) &&
	 $data(targetRow) <= $data(sourceRow) + $data(sourceDescCount)) ||

	([string compare $data(sourceParentKey) $targetParentKey] != 0 &&
	 ($::tk_version < 8.3 ||
	  ([string length $data(-acceptchildcommand)] != 0 &&
	   ![uplevel #0 $data(-acceptchildcommand) \
	     [list $win $targetParentNodeIdx $data(sourceRow)]]))) ||

	($data(targetChildIdx) < 0 &&
	 [string length $data(-acceptdropcommand)] != 0 &&
	 ![uplevel #0 $data(-acceptdropcommand) \
	   [list $win $data(targetRow) $data(sourceRow)]])} {

	unset data(targetRow)
	unset data(targetChildIdx)
	$w configure -cursor $data(-cursor)
	place forget $data(rowGap)
    } else {
	$w configure -cursor $data(-movecursor)
	if {$data(targetChildIdx) == 0} {
	    place $data(rowGap) -anchor w -y $gapY -height $lineHeight -width 6
	} else {
	    place $data(rowGap) -anchor w -y $gapY -height 4 \
				-width [winfo width $data(hdrTxtFr)]
	}
	raise $data(rowGap)
    }
}

#------------------------------------------------------------------------------
# tablelist::moveOrActivate
#
# This procedure is invoked whenever mouse button 1 is released in the body of
# a tablelist widget or in one of its separators.  It either moves the
# previously clicked row before or after the one containing the mouse cursor,
# or activates the given nearest item or element (depending on the widget's
# selection type).
#------------------------------------------------------------------------------
proc tablelist::moveOrActivate {win row col inside} {
    variable priv
    upvar ::tablelist::ns${win}::data data
    if {$priv(selClearPending) && $inside} {
	switch $data(-selecttype) {
	    row {
		if {$row == $priv(prevRow)} {
		    ::$win selection clear $priv(prevRow)
		}
	    }
	    cell {
		if {$row == $priv(prevRow) && $col == $priv(prevCol)} {
		    ::$win cellselection clear $priv(prevRow),$priv(prevCol)
		}
	    }
	}

	event generate $win <<TablelistSelect>>
	set priv(selClearPending) 0
    } elseif {$priv(selChangePending) && $inside} {
	switch $data(-selecttype) {
	    row {
		if {$row == $priv(prevRow)} {
		    ::$win selection clear 0 end
		    ::$win selection set $priv(prevRow)
		}
	    }
	    cell {
		if {$row == $priv(prevRow) && $col == $priv(prevCol)} {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set $priv(prevRow),$priv(prevCol)
		}
	    }
	}

	event generate $win <<TablelistSelect>>
	set priv(selChangePending) 0
    }

    #
    # Return if both <Button-1> and <ButtonRelease-1> occurred in the
    # temporary embedded widget used for interactive cell editing
    #
    if {$priv(clickedInEditWin) && $priv(releasedInEditWin)} {
	return ""
    }

    if {[info exists data(sourceRow)]} {
	set sourceRow $data(sourceRow)
	unset data(sourceRow)
	unset data(sourceEndRow)
	unset data(sourceDescCount)
	unset data(sourceParentKey)
	unset data(sourceParentRow)
	unset data(sourceParentEndRow)
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	$data(body) configure -cursor $data(-cursor)
	place forget $data(rowGap)

	if {[info exists data(targetRow)]} {
	    set sourceKey [lindex $data(keyList) $sourceRow]
	    set targetRow $data(targetRow)
	    unset data(targetRow)

	    if {$targetRow > $data(lastRow)} {
		if {[catch {::$win move $sourceRow $targetRow}] == 0} {
		    set targetParentNodeIdx [::$win parentkey $sourceRow]
		} else {
		    ::$win move $sourceRow root end
		    set targetParentNodeIdx root
		}

		set targetChildIdx [::$win childcount $targetParentNodeIdx]
	    } else {
		set targetChildIdx $data(targetChildIdx)
		unset data(targetChildIdx)

		if {$targetChildIdx == 0} {
		    set targetParentNodeIdx [lindex $data(keyList) $targetRow]
		    ::$win expand $targetParentNodeIdx -partly
		    ::$win move $sourceKey $targetParentNodeIdx $targetChildIdx
		} else {
		    set targetParentNodeIdx [::$win parentkey $targetRow]
		    set targetChildIdx [::$win childindex $targetRow]
		    ::$win move $sourceRow $targetParentNodeIdx $targetChildIdx
		}
	    }

	    set userData [list $sourceKey $targetParentNodeIdx $targetChildIdx]
	    genVirtualEvent $win <<TablelistRowMoved>> $userData

	    switch $data(-selecttype) {
		row  { ::$win activate $sourceKey }
		cell { ::$win activatecell $sourceKey,$col }
	    }

	    return ""
	}
    }

    switch $data(-selecttype) {
	row  { ::$win activate $row }
	cell { ::$win activatecell $row,$col }
    }
}

#------------------------------------------------------------------------------
# tablelist::condEvalInvokeCmd
#
# This procedure is invoked when mouse button 1 is released in the body of a
# tablelist widget win or in one of its separators.  If interactive cell
# editing is in progress in a column whose associated edit window has an invoke
# command that hasn't yet been called in the current edit session, then the
# procedure evaluates that command.
#------------------------------------------------------------------------------
proc tablelist::condEvalInvokeCmd win {
    #
    # This is an "after 100" callback; check whether the window exists
    #
    if {![array exists ::tablelist::ns${win}::data]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(editCol) < 0} {
	return ""
    }

    variable editWin
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    if {[string length $editWin($name-invokeCmd)] == 0 || $data(invoked)} {
	return ""
    }

    #
    # Return if both <Button-1> and <ButtonRelease-1> occurred in the
    # temporary embedded widget used for interactive cell editing
    #
    variable priv
    if {$priv(clickedInEditWin) && $priv(releasedInEditWin)} {
	return ""
    }

    #
    # Check whether the edit window is a checkbutton,
    # and return if it is an editable combobox widget
    #
    set isCheckbtn 0
    set w $data(bodyFrEd)
    switch [winfo class $w] {
	Checkbutton -
	TCheckbutton {
	    set isCheckbtn 1
	}
	TCombobox {
	    if {[string compare [$w cget -state] "normal"] == 0} {
		return ""
	    }
	}
	ComboBox -
	Combobox {
	    if {[$w cget -editable]} {
		return ""
	    }
	}
    }

    #
    # Evaluate the edit window's invoke command
    #
    eval [strMap {"%W" "$w"} $editWin($name-invokeCmd)]
    set data(invoked) 1

    #
    # If the edit window is a checkbutton and the value of the
    # -instanttoggle option is true then finish the editing
    #
    if {$isCheckbtn && $data(-instanttoggle)} {
	doFinishEditing $win
    }
}

#------------------------------------------------------------------------------
# tablelist::cancelMove
#
# This procedure is invoked to process <Escape> events in the top-level window
# containing the tablelist widget win during a row move operation.  It cancels
# the action in progress.
#------------------------------------------------------------------------------
proc tablelist::cancelMove win {
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(sourceRow)]} {
	return ""
    }

    unset data(sourceRow)
    unset data(sourceEndRow)
    unset data(sourceDescCount)
    unset data(sourceParentKey)
    unset data(sourceParentRow)
    unset data(sourceParentEndRow)
    if {[info exists data(targetRow)]} {
	unset data(targetRow)
    }
    if {[info exists data(targetChildIdx)]} {
	unset data(targetChildIdx)
    }
    bind [winfo toplevel $win] <Escape> $data(topEscBinding)
    $data(body) configure -cursor $data(-cursor)
    place forget $data(rowGap)
}

#------------------------------------------------------------------------------
# tablelist::beginExtend
#
# This procedure is typically invoked on shift-button-1 presses in the body of
# a tablelist widget or in one of its separators.  It begins the process of
# extending a selection in the widget.  Its exact behavior depends on the
# selection mode currently in effect for the widget.
#------------------------------------------------------------------------------
proc tablelist::beginExtend {win row col} {
    if {[string compare [::$win cget -selectmode] "extended"] != 0} {
	return ""
    }

    if {[::$win selection includes anchor]} {
	motion $win $row $col
    } else {
	beginSelect $win $row $col
    }
}

#------------------------------------------------------------------------------
# tablelist::beginToggle
#
# This procedure is typically invoked on control-button-1 presses in the body
# of a tablelist widget or in one of its separators.  It begins the process of
# toggling a selection in the widget.  Its exact behavior depends on the
# selection mode currently in effect for the widget.
#------------------------------------------------------------------------------
proc tablelist::beginToggle {win row col} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selectmode) "extended"] != 0} {
	return ""
    }

    variable priv
    switch $data(-selecttype) {
	row {
	    set priv(selection) [::$win curselection]
	    set priv(prevRow) $row
	    ::$win selection anchor $row
	    if {[::$win selection includes $row]} {
		::$win selection clear $row
	    } else {
		::$win selection set $row
	    }
	}

	cell {
	    set priv(selection) [::$win curcellselection]
	    set priv(prevRow) $row
	    set priv(prevCol) $col
	    ::$win cellselection anchor $row,$col
	    if {[::$win cellselection includes $row,$col]} {
		::$win cellselection clear $row,$col
	    } else {
		::$win cellselection set $row,$col
	    }
	}
    }

    event generate $win <<TablelistSelect>>
}

#------------------------------------------------------------------------------
# tablelist::condEditActiveCell
#
# This procedure is invoked whenever Return or KP_Enter is pressed in the body
# of a tablelist widget.  If the selection type is cell and the active cell is
# editable then the procedure starts the interactive editing in that cell.
#------------------------------------------------------------------------------
proc tablelist::condEditActiveCell win {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selecttype) "cell"] != 0 ||
	[firstViewableRow $win] < 0 || [firstViewableCol $win] < 0} {
	return ""
    }

    set row $data(activeRow)
    set col $data(activeCol)
    if {[isCellEditable $win $row $col]} {
	doEditCell $win $row $col 0
    }
}

#------------------------------------------------------------------------------
# tablelist::plusMinus
#
# Partially expands or collapses the active row if possible.
#------------------------------------------------------------------------------
proc tablelist::plusMinus {win keysym} {
    upvar ::tablelist::ns${win}::data data
    set row $data(activeRow)
    set col $data(treeCol)
    set key [lindex $data(keyList) $row]
    set op ""

    if {[info exists data($key,$col-indent)]} {
	set indentLabel $data(body).ind_$key,$col
	set imgName [$indentLabel cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    if {[string compare $keysym "plus"] == 0 &&
		[string compare $mode "collapsed"] == 0} {
		set op "expand"
	    } elseif {[string compare $keysym "minus"] == 0 &&
		      [string compare $mode "expanded"] == 0} {
		set op "collapse"
	    }
	}
    }

    if {[string length $op] != 0} {
	#
	# Save the current vertical position
	#
	set topRow [expr {int([$data(body) index @0,0]) - 1}]

	#
	# Toggle the state of the expand/collapse control
	#
	::$win $op $row -partly

	#
	# Restore the saved vertical position
	#
	$data(body) yview $topRow
	updateViewWhenIdle $win
    }
}

#------------------------------------------------------------------------------
# tablelist::nextPrevCell
#
# Does nothing unless the selection type is cell; in this case it moves the
# location cursor (active element) to the next or previous element, and changes
# the selection if we are in browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::nextPrevCell {win amount} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    # Nothing
	}

	cell {
	    if {$data(editRow) >= 0} {
		return -code break ""
	    }

	    set row $data(activeRow)
	    set col $data(activeCol)
	    set oldRow $row
	    set oldCol $col

	    while 1 {
		incr col $amount
		if {$col < 0} {
		    incr row $amount
		    if {$row < 0} {
			set row $data(lastRow)
		    }
		    set col $data(lastCol)
		} elseif {$col > $data(lastCol)} {
		    incr row $amount
		    if {$row > $data(lastRow)} {
			set row 0
		    }
		    set col 0
		}

		if {$row == $oldRow && $col == $oldCol} {
		    return -code break ""
		} elseif {[isRowViewable $win $row] && !$data($col-hide)} {
		    condChangeSelection $win $row $col
		    return -code break ""
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::upDown
#
# Moves the location cursor (active item or element) up or down by one line,
# and changes the selection if we are in browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::upDown {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {$data(editRow) >= 0} {
	return ""
    }

    switch $data(-selecttype) {
	row {
	    set row $data(activeRow)
	    set col -1
	}

	cell {
	    set row $data(activeRow)
	    set col $data(activeCol)
	}
    }

    while 1 {
	incr row $amount
	if {$row < 0 || $row > $data(lastRow)} {
	    return ""
	} elseif {[isRowViewable $win $row]} {
	    condChangeSelection $win $row $col
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::leftRight
#
# Partially expands or collapses the active row if possible.  Otherwise, if the
# tablelist widget's selection type is "row" then this procedure scrolls the
# widget's view left or right by the width of the character "0".  Otherwise it
# moves the location cursor (active element) left or right by one column, and
# changes the selection if we are in browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::leftRight {win amount} {
    upvar ::tablelist::ns${win}::data data
    set row $data(activeRow)
    set col $data(treeCol)
    set key [lindex $data(keyList) $row]
    set op ""

    if {[info exists data($key,$col-indent)]} {
	set indentLabel $data(body).ind_$key,$col
	set imgName [$indentLabel cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    if {$amount > 0 && [string compare $mode "collapsed"] == 0} {
		set op "expand"
	    } elseif {$amount < 0 && [string compare $mode "expanded"] == 0} {
		set op "collapse"
	    }
	}
    }

    if {[string length $op] == 0} {
	switch $data(-selecttype) {
	    row {
		::$win xview scroll $amount units
	    }

	    cell {
		if {$data(editRow) >= 0} {
		    return ""
		}

		set col $data(activeCol)
		while 1 {
		    incr col $amount
		    if {$col < 0 || $col > $data(lastCol)} {
			return ""
		    } elseif {!$data($col-hide)} {
			condChangeSelection $win $row $col
			return ""
		    }
		}
	    }
	}
    } else {
	#
	# Save the current vertical position
	#
	set topRow [expr {int([$data(body) index @0,0]) - 1}]

	#
	# Toggle the state of the expand/collapse control
	#
	::$win $op $row -partly

	#
	# Restore the saved vertical position
	#
	$data(body) yview $topRow
	updateViewWhenIdle $win
    }
}

#------------------------------------------------------------------------------
# tablelist::priorNext
#
# Scrolls the tablelist view up or down by one page.
#------------------------------------------------------------------------------
proc tablelist::priorNext {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {$data(editRow) >= 0} {
	return ""
    }

    ::$win yview scroll $amount pages
    ::$win activate @0,0
    update idletasks
}

#------------------------------------------------------------------------------
# tablelist::homeEnd
#
# If selecttype is row then the procedure scrolls the tablelist widget
# horizontally to its left or right edge.  Otherwise it sets the location
# cursor (active element) to the first/last element of the active row, selects
# that element, and deselects everything else in the widget.
#------------------------------------------------------------------------------
proc tablelist::homeEnd {win keysym} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    switch $keysym {
		Home { ::$win xview moveto 0 }
		End  { ::$win xview moveto 1 }
	    }
	}

	cell {
	    set row $data(activeRow)
	    switch $keysym {
		Home { set col [firstViewableCol $win] }
		End  { set col [ lastViewableCol $win] }
	    }
	    changeSelection $win $row $col
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::firstLast
#
# Sets the location cursor (active item or element) to the first/last item or
# element in the tablelist widget, selects that item or element, and deselects
# everything else in the widget.
#------------------------------------------------------------------------------
proc tablelist::firstLast {win target} {
    switch $target {
	first {
	    set row [firstViewableRow $win]
	    set col [firstViewableCol $win]
	}

	last {
	    set row [lastViewableRow $win]
	    set col [lastViewableCol $win]
	}
    }

    changeSelection $win $row $col
}

#------------------------------------------------------------------------------
# tablelist::extendUpDown
#
# Does nothing unless we are in extended selection mode; in this case it moves
# the location cursor (active item or element) up or down by one line, and
# extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendUpDown {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selectmode) "extended"] != 0} {
	return ""
    }

    switch $data(-selecttype) {
	row {
	    set row $data(activeRow)
	    while 1 {
		incr row $amount
		if {$row < 0 || $row > $data(lastRow)} {
		    return ""
		} elseif {[isRowViewable $win $row]} {
		    ::$win activate $row
		    ::$win see active
		    motion $win $data(activeRow) -1
		    return ""
		}
	    }
	}

	cell {
	    set row $data(activeRow)
	    set col $data(activeCol)
	    while 1 {
		incr row $amount
		if {$row < 0 || $row > $data(lastRow)} {
		    return ""
		} elseif {[isRowViewable $win $row]} {
		    ::$win activatecell $row,$col
		    ::$win seecell active
		    motion $win $data(activeRow) $data(activeCol)
		    return ""
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::extendLeftRight
#
# Does nothing unless we are in extended selection mode and the selection type
# is cell; in this case it moves the location cursor (active element) left or
# right by one column, and extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendLeftRight {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selectmode) "extended"] != 0} {
	return ""
    }

    switch $data(-selecttype) {
	row {
	    # Nothing
	}

	cell {
	    set row $data(activeRow)
	    set col $data(activeCol)
	    while 1 {
		incr col $amount
		if {$col < 0 || $col > $data(lastCol)} {
		    return ""
		} elseif {!$data($col-hide)} {
		    ::$win activatecell $row,$col
		    ::$win seecell active
		    motion $win $data(activeRow) $data(activeCol)
		    return ""
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::extendToHomeEnd
#
# Does nothing unless the selection mode is multiple or extended and the
# selection type is cell; in this case it moves the location cursor (active
# element) to the first/last element of the active row, and, if we are in
# extended mode, it extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendToHomeEnd {win keysym} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    # Nothing
	}

	cell {
	    set row $data(activeRow)
	    switch $keysym {
		Home { set col [firstViewableCol $win] }
		End  { set col [ lastViewableCol $win] }
	    }

	    switch -- $data(-selectmode) {
		multiple {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		}
		extended {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		    if {[::$win selection includes anchor]} {
			motion $win $row $col
		    }
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::extendToFirstLast
#
# Does nothing unless the selection mode is multiple or extended; in this case
# it moves the location cursor (active item or element) to the first/last item
# or element in the tablelist widget, and, if we are in extended mode, it
# extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendToFirstLast {win target} {
    switch $target {
	first {
	    set row [firstViewableRow $win]
	    set col [firstViewableCol $win]
	}

	last {
	    set row [lastViewableRow $win]
	    set col [lastViewableCol $win]
	}
    }

    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    switch -- $data(-selectmode) {
		multiple {
		    ::$win activate $row
		    ::$win see $row
		}
		extended {
		    ::$win activate $row
		    ::$win see $row
		    if {[::$win selection includes anchor]} {
			motion $win $row -1
		    }
		}
	    }
	}

	cell {
	    switch -- $data(-selectmode) {
		multiple {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		}
		extended {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		    if {[::$win selection includes anchor]} {
			motion $win $row $col
		    }
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::cancelSelection
#
# This procedure is invoked to cancel an extended selection in progress.  If
# there is an extended selection in progress, it restores all of the elements
# to their previous selection state.
#------------------------------------------------------------------------------
proc tablelist::cancelSelection win {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selectmode) "extended"] != 0} {
	return ""
    }

    variable priv
    switch $data(-selecttype) {
	row {
	    if {[string length $priv(prevRow)] == 0} {
		return ""
	    }

	    ::$win selection clear 0 end
	    foreach row $priv(selection) {
		::$win selection set $row
	    }
	    event generate $win <<TablelistSelect>>
	}

	cell {
	    if {[string length $priv(prevRow)] == 0 ||
		[string length $priv(prevCol)] == 0} {
		return ""
	    }

	    ::$win selection clear 0 end
	    foreach cellIdx $priv(selection) {
		::$win cellselection set $cellIdx
	    }
	    event generate $win <<TablelistSelect>>
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::selectAll
#
# This procedure is invoked to handle the "select all" operation.  For single
# and browse mode, it just selects the active item or element.  Otherwise it
# selects everything in the widget.
#------------------------------------------------------------------------------
proc tablelist::selectAll win {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    if {[string compare $data(-selectmode) "single"] == 0 ||
		[string compare $data(-selectmode) "browse"] == 0} {
		::$win selection clear 0 end
		::$win selection set active
	    } else {
		::$win selection set 0 end
	    }
	}

	cell {
	    if {[string compare $data(-selectmode) "single"] == 0 ||
		[string compare $data(-selectmode) "browse"] == 0} {
		::$win cellselection clear 0,0 end
		::$win cellselection set active
	    } else {
		::$win cellselection set 0,0 end
	    }
	}
    }

    event generate $win <<TablelistSelect>>
}

#------------------------------------------------------------------------------
# tablelist::isDragSrc
#
# Checks whether the body component of the tablelist widget win is a BWidget or
# TkDND drag source for mouse button 1.
#------------------------------------------------------------------------------
proc tablelist::isDragSrc win {
    upvar ::tablelist::ns${win}::data data
    set bindTags [bindtags $data(body)]
    return [expr {[info exists data(sourceRow)] || $data(-customdragsource) ||
		  [lsearch -exact $bindTags "BwDrag1"] >= 0 ||
		  [lsearch -exact $bindTags "TkDND_Drag1"] >= 0
    }]
}

#------------------------------------------------------------------------------
# tablelist::normalizedRect
#
# Returns a list of the form {minRow minCol maxRow maxCol}, built from the
# given arguments.
#------------------------------------------------------------------------------
proc tablelist::normalizedRect {row1 col1 row2 col2} {
    if {$row1 <= $row2} {
	set minRow $row1
	set maxRow $row2
    } else {
	set minRow $row2
	set maxRow $row1
    }

    if {$col1 <= $col2} {
	set minCol $col1
	set maxCol $col2
    } else {
	set minCol $col2
	set maxCol $col1
    }

    return [list $minRow $minCol $maxRow $maxCol]
}

#------------------------------------------------------------------------------
# tablelist::cellInRect
#
# Checks whether the cell row,col is contained in the given rectangular range.
#------------------------------------------------------------------------------
proc tablelist::cellInRect {row col minRow minCol maxRow maxCol} {
    return [expr {$row >= $minRow && $row <= $maxRow &&
		  $col >= $minCol && $col <= $maxCol}]
}

#------------------------------------------------------------------------------
# tablelist::firstViewableRow
#
# Returns the index of the first viewable row of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::firstViewableRow win {
    upvar ::tablelist::ns${win}::data data
    for {set row 0} {$row < $data(itemCount)} {incr row} {
	if {[isRowViewable $win $row]} {
	    return $row
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::lastViewableRow
#
# Returns the index of the last viewable row of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::lastViewableRow win {
    upvar ::tablelist::ns${win}::data data
    for {set row $data(lastRow)} {$row >= 0} {incr row -1} {
	if {[isRowViewable $win $row]} {
	    return $row
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::firstViewableCol
#
# Returns the index of the first non-hidden column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::firstViewableCol win {
    upvar ::tablelist::ns${win}::data data
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {!$data($col-hide)} {
	    return $col
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::lastViewableCol
#
# Returns the index of the last non-hidden column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::lastViewableCol win {
    upvar ::tablelist::ns${win}::data data
    for {set col $data(lastCol)} {$col >= 0} {incr col -1} {
	if {!$data($col-hide)} {
	    return $col
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::condChangeSelection
#
# Activates the given item or element, and selects it exclusively if we are in
# browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::condChangeSelection {win row col} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    ::$win activate $row
	    ::$win see active

	    switch -- $data(-selectmode) {
		browse {
		    ::$win selection clear 0 end
		    ::$win selection set active
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    ::$win selection clear 0 end
		    ::$win selection set active
		    ::$win selection anchor active
		    variable priv
		    set priv(selection) {}
		    set priv(prevRow) $data(activeRow)
		    event generate $win <<TablelistSelect>>
		}
	    }
	}

	cell {
	    ::$win activatecell $row,$col
	    ::$win seecell active

	    switch -- $data(-selectmode) {
		browse {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set active
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set active
		    ::$win cellselection anchor active
		    variable priv
		    set priv(selection) {}
		    set priv(prevRow) $data(activeRow)
		    set priv(prevCol) $data(activeCol)
		    event generate $win <<TablelistSelect>>
		}
	    }
	}
    }

    update idletasks
}

#------------------------------------------------------------------------------
# tablelist::changeSelection
#
# Activates the given item or element and selects it exclusively.
#------------------------------------------------------------------------------
proc tablelist::changeSelection {win row col} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    ::$win activate $row
	    ::$win see active

	    ::$win selection clear 0 end
	    ::$win selection set active
	}

	cell {
	    ::$win activatecell $row,$col
	    ::$win seecell active

	    ::$win cellselection clear 0,0 end
	    ::$win cellselection set active
	}
    }

    event generate $win <<TablelistSelect>>
}

#
# Binding tags TablelistLabel, TablelistSubLabel, and TablelistArrow
# ==================================================================
#

#------------------------------------------------------------------------------
# tablelist::defineTablelistSubLabel
#
# Defines the binding tag TablelistSubLabel (for sublabels of tablelist labels)
# to have the same events as TablelistLabel and the binding scripts obtained
# from those of TablelistLabel by replacing the widget %W with the containing
# label as well as the %x and %y fields with the corresponding coordinates
# relative to that label.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistSubLabel {} {
    foreach event [bind TablelistLabel] {
	set script [strMap {
	    "%W" "$tablelist::W"  "%x" "$tablelist::x"  "%y" "$tablelist::y"
	} [bind TablelistLabel $event]]

	bind TablelistSubLabel $event [format {
	    set tablelist::W \
		[string range %%W 0 [expr {[string length %%W] - 4}]]
	    set tablelist::x \
		[expr {%%x + [winfo x %%W] - [winfo x $tablelist::W]}]
	    set tablelist::y \
		[expr {%%y + [winfo y %%W] - [winfo y $tablelist::W]}]
	    %s
	} $script]
    }
}

#------------------------------------------------------------------------------
# tablelist::defineTablelistArrow
#
# Defines the binding tag TablelistArrow (for sort arrows) to have the same
# events as TablelistLabel and the binding scripts obtained from those of
# TablelistLabel by replacing the widget %W with the containing label as well
# as the %x and %y fields with the corresponding coordinates relative to that
# label.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistArrow {} {
    foreach event [bind TablelistLabel] {
	set script [strMap {
	    "%W" "$tablelist::W"  "%x" "$tablelist::x"  "%y" "$tablelist::y"
	} [bind TablelistLabel $event]]

	bind TablelistArrow $event [format {
	    set tablelist::W \
		[winfo parent %%W].l[string range [winfo name %%W] 1 end]
	    set tablelist::x \
		[expr {%%x + [winfo x %%W] - [winfo x $tablelist::W]}]
	    set tablelist::y \
		[expr {%%y + [winfo y %%W] - [winfo y $tablelist::W]}]
	    %s
	} $script]
    }
}

#------------------------------------------------------------------------------
# tablelist::labelEnter
#
# This procedure is invoked when the mouse pointer enters the header label w of
# a tablelist widget, or is moving within that label.  It updates the cursor,
# displays the tooltip, and activates or deactivates the label, depending on
# whether the pointer is on its right border or not.
#------------------------------------------------------------------------------
proc tablelist::labelEnter {w X Y x} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    configLabel $w -cursor $data(-cursor)

    if {[string length $data(-tooltipaddcommand)] != 0 &&
	[string length $data(-tooltipdelcommand)] != 0 &&
	$col != $data(prevCol)} {
	#
	# Display the tooltip corresponding to this label
	#
	set data(prevCol) $col
	set focus [focus -displayof $win]
	if {[string length $focus] == 0 ||
	    [string first $win $focus] != 0 ||
	    [string compare [winfo toplevel $focus] \
	     [winfo toplevel $win]] == 0} {
	    uplevel #0 $data(-tooltipaddcommand) [list $win -1 $col]
	    event generate $win <Leave>
	    event generate $win <Enter> -rootx $X -rooty $Y
	}
    }

    if {$data(isDisabled)} {
	return ""
    }

    if {[inResizeArea $w $x col] &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	configLabel $w -cursor $data(-resizecursor)
	configLabel $w -active 0
    } else {
	configLabel $w -active 1
    }
}

#------------------------------------------------------------------------------
# tablelist::labelLeave
#
# This procedure is invoked when the mouse pointer leaves the header label w of
# a tablelist widget.  It removes the tooltip and deactivates the label.
#------------------------------------------------------------------------------
proc tablelist::labelLeave {w X x y} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    #
    # The following code is needed because the event
    # can also occur in a widget placed into the label
    #
    upvar ::tablelist::ns${win}::data data
    set hdrX [winfo rootx $data(hdr)]
    if {$X >= $hdrX && $X < $hdrX + [winfo width $data(hdr)] &&
	$x >= 1 && $x < [winfo width $w] - 1 &&
	$y >= 0 && $y < [winfo height $w]} {
	return ""
    }

    if {[string length $data(-tooltipaddcommand)] != 0 &&
	[string length $data(-tooltipdelcommand)] != 0} {
	#
	# Remove the tooltip, if any
	#
	event generate $win <Leave>
	catch {uplevel #0 $data(-tooltipdelcommand) [list $win]}
	set data(prevCol) -1
    }

    if {$data(isDisabled)} {
	return ""
    }

    configLabel $w -active 0
}

#------------------------------------------------------------------------------
# tablelist::labelB1Down
#
# This procedure is invoked when mouse button 1 is pressed in the header label
# w of a tablelist widget.  If the pointer is on the right border of the label
# then the procedure records its x-coordinate relative to the label, the width
# of the column, and some other data needed later.  Otherwise it saves the
# label's relief so it can be restored later, and changes the relief to sunken.
#------------------------------------------------------------------------------
proc tablelist::labelB1Down {w x shiftPressed} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) ||
	[info exists data(colBeingResized)]} {	;# resize operation in progress
	return ""
    }

    set data(labelClicked) 1
    set data(X) [expr {[winfo rootx $w] + $x}]
    set data(shiftPressed) $shiftPressed

    if {[inResizeArea $w $x col] &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	set data(colBeingResized) $col
	set data(colResized) 0

	set w $data(body)
	set topTextIdx [$w index @0,0]
	set btmTextIdx [$w index @0,[expr {[winfo height $w] - 1}]]
	$w tag add visibleLines "$topTextIdx linestart" "$btmTextIdx lineend"
	set data(topRow) [expr {int($topTextIdx) - 1}]
	set data(btmRow) [expr {int($btmTextIdx) - 1}]

	set w $data(hdrTxtFrLbl)$col
	set labelWidth [winfo width $w]
	set data(oldStretchedColWidth) [expr {$labelWidth - 2*$data(charWidth)}]
	set data(oldColDelta) $data($col-delta)
	set data(configColWidth) [lindex $data(-columns) [expr {3*$col}]]

	if {[lsearch -exact $data(arrowColList) $col] >= 0} {
	    set canvasWidth $data(arrowWidth)
	    if {[llength $data(arrowColList)] > 1} {
		incr canvasWidth 6
	    }
	    set data(minColWidth) $canvasWidth
	} elseif {$data($col-wrap)} {
	    set data(minColWidth) $data(charWidth)
	} else {
	    set data(minColWidth) 0
	}
	incr data(minColWidth)

	set data(focus) [focus -displayof $win]
	set topWin [winfo toplevel $win]
	focus $topWin
	set data(topEscBinding) [bind $topWin <Escape>]
	bind $topWin <Escape> \
	     [list tablelist::escape [strMap {"%" "%%"} $win] $col]
    } else {
	set data(inClickedLabel) 1
	set data(relief) [$w cget -relief]

	if {[info exists data($col-labelcommand)] ||
	    [string length $data(-labelcommand)] != 0} {
	    set data(changeRelief) 1
	    configLabel $w -relief sunken -pressed 1
	} else {
	    set data(changeRelief) 0
	}

	if {$data(-movablecolumns)} {
	    set data(focus) [focus -displayof $win]
	    set topWin [winfo toplevel $win]
	    focus $topWin
	    set data(topEscBinding) [bind $topWin <Escape>]
	    bind $topWin <Escape> \
		 [list tablelist::escape [strMap {"%" "%%"} $win] $col]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::labelB1Motion
#
# This procedure is invoked to process mouse motion events in the header label
# w of a tablelist widget while button 1 is down.  If this event occured during
# a column resize operation then the procedure computes the difference between
# the pointer's new x-coordinate relative to that label and the one recorded by
# the last invocation of labelB1Down, and adjusts the width of the
# corresponding column accordingly.  Otherwise a horizontal scrolling is
# performed if needed, and the would-be target position of the clicked label is
# visualized if the columns are movable.
#------------------------------------------------------------------------------
proc tablelist::labelB1Motion {w X x y} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked)} {
	return ""
    }

    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	set width [expr {$data(oldStretchedColWidth) + $X - $data(X)}]
	if {$width >= $data(minColWidth)} {
	    set col $data(colBeingResized)
	    set data(colResized) 1
	    set idx [expr {3*$col}]
	    set data(-columns) [lreplace $data(-columns) $idx $idx -$width]
	    set idx [expr {2*$col}]
	    set data(colList) [lreplace $data(colList) $idx $idx $width]
	    set data($col-lastStaticWidth) $width
	    set data($col-delta) 0
	    redisplayCol $win $col $data(topRow) $data(btmRow)

	    #
	    # Handle the case that the bottom row has become
	    # greater (due to the redisplayCol invocation)
	    #
	    set b $data(body)
	    set btmTextIdx [$b index @0,$data(btmY)]
	    set btmRow [expr {int($btmTextIdx) - 1}]
	    if {$btmRow > $data(lastRow)} {		;# text widget bug
		set btmRow $data(lastRow)
	    }
	    while {$btmRow > $data(btmRow)} {
		$b tag add visibleLines [expr {double($data(btmRow) + 2)}] \
					"$btmTextIdx lineend"
		incr data(btmRow)
		redisplayCol $win $col $data(btmRow) $btmRow
		set data(btmRow) $btmRow

		set btmTextIdx [$b index @0,$data(btmY)]
		set btmRow [expr {int($btmTextIdx) - 1}]
		if {$btmRow > $data(lastRow)} {		;# text widget bug
		    set btmRow $data(lastRow)
		}
	    }

	    #
	    # Handle the case that the top row has become
	    # less (due to the redisplayCol invocation)
	    #
	    set topTextIdx [$b index @0,0]
	    set topRow [expr {int($topTextIdx) - 1}]
	    while {$topRow < $data(topRow)} {
		$b tag add visibleLines "$topTextIdx linestart" \
					"[expr {double($data(topRow))}] lineend"
		incr data(topRow) -1
		redisplayCol $win $col $topRow $data(topRow)
		set data(topRow) $topRow

		set topTextIdx [$b index @0,0]
		set topRow [expr {int($topTextIdx) - 1}]
	    }

	    adjustColumns $win {} 0
	    adjustElidedText $win
	    redisplayVisibleItems $win
	    updateColors $win
	    updateVScrlbarWhenIdle $win
	}
    } else {
	#
	# Scroll the window horizontally if needed
	#
	set hdrX [winfo rootx $data(hdr)]
	if {$data(-titlecolumns) == 0 || ![winfo viewable $data(sep)]} {
	    set leftX $hdrX
	} else {
	    set leftX [expr {[winfo rootx $data(sep)] + 1}]
	}
	set rightX [expr {$hdrX + [winfo width $data(hdr)]}]
	set scroll 0
	if {($X >= $rightX && $data(X) < $rightX) ||
	    ($X < $leftX && $data(X) >= $leftX)} {
	    set scroll 1
	} elseif {($X < $rightX && $data(X) >= $rightX) ||
		  ($X >= $leftX && $data(X) < $leftX)} {
	    after cancel $data(afterId)
	    set data(afterId) ""
	}
	set data(X) $X
	if {$scroll} {
	    horizAutoScan $win
	}

	if {$x >= 1 && $x < [winfo width $w] - 1 &&
	    $y >= 0 && $y < [winfo height $w]} {
	    #
	    # The following code is needed because the event
	    # can also occur in a widget placed into the label
	    #
	    set data(inClickedLabel) 1
	    configLabel $w -cursor $data(-cursor)
	    $data(hdrTxtFrCanv)$col configure -cursor $data(-cursor)
	    if {$data(changeRelief)} {
		configLabel $w -relief sunken -pressed 1
	    }

	    place forget $data(colGap)
	} else {
	    #
	    # The following code is needed because the event
	    # can also occur in a widget placed into the label
	    #
	    set data(inClickedLabel) 0
	    configLabel $w -relief $data(relief) -pressed 0

	    if {$data(-movablecolumns)} {
		#
		# Get the target column index
		#
		set contW [winfo containing -displayof $w $X [winfo rooty $w]]
		if {[parseLabelPath $contW dummy targetCol]} {
		    set master $contW
		    if {$X < [winfo rootx $contW] + [winfo width $contW]/2} {
			set relx 0.0
		    } else {
			incr targetCol
			set relx 1.0
		    }
		} elseif {[string compare $contW $data(colGap)] == 0} {
		    set targetCol $data(targetCol)
		    set master $data(master)
		    set relx $data(relx)
		} elseif {$X >= $rightX || $X >= [winfo rootx $w]} {
		    for {set targetCol $data(lastCol)} {$targetCol >= 0} \
			{incr targetCol -1} {
			if {!$data($targetCol-hide)} {
			    break
			}
		    }
		    incr targetCol
		    set master $data(hdrTxtFr)
		    set relx 1.0
		} else {
		    for {set targetCol 0} {$targetCol < $data(colCount)} \
			{incr targetCol} {
			if {!$data($targetCol-hide)} {
			    break
			}
		    }
		    set master $data(hdrTxtFr)
		    set relx 0.0
		}

		#
		# Visualize the would-be target position
		# of the clicked label if appropriate
		#
		if {$targetCol == $col || $targetCol == $col + 1 ||
		    ($data(-protecttitlecolumns) &&
		     (($col >= $data(-titlecolumns) &&
		       $targetCol < $data(-titlecolumns)) ||
		      ($col < $data(-titlecolumns) &&
		       $targetCol > $data(-titlecolumns))))} {
		    if {[info exists data(targetCol)]} {
			unset data(targetCol)
		    }
		    configLabel $w -cursor $data(-cursor)
		    $data(hdrTxtFrCanv)$col configure -cursor $data(-cursor)
		    place forget $data(colGap)
		} else {
		    set data(targetCol) $targetCol
		    set data(master) $master
		    set data(relx) $relx
		    configLabel $w -cursor $data(-movecolumncursor)
		    $data(hdrTxtFrCanv)$col configure -cursor \
					    $data(-movecolumncursor)
		    place $data(colGap) -in $master -anchor n \
					-bordermode outside \
					-relheight 1.0 -relx $relx
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::labelB1Enter
#
# This procedure is invoked when the mouse pointer enters the header label w of
# a tablelist widget while mouse button 1 is down.  If the label was not
# previously clicked then nothing happens.  Otherwise, if this event occured
# during a column resize operation then the procedure updates the mouse cursor
# accordingly.  Otherwise it changes the label's relief to sunken.
#------------------------------------------------------------------------------
proc tablelist::labelB1Enter w {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked)} {
	return ""
    }

    configLabel $w -cursor $data(-cursor)

    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	configLabel $w -cursor $data(-resizecursor)
    } else {
	set data(inClickedLabel) 1
	if {$data(changeRelief)} {
	    configLabel $w -relief sunken -pressed 1
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::labelB1Leave
#
# This procedure is invoked when the mouse pointer leaves the header label w of
# a tablelist widget while mouse button 1 is down.  If the label was not
# previously clicked then nothing happens.  Otherwise, if no column resize
# operation is in progress then the procedure restores the label's relief, and,
# if the columns are movable, then it changes the mouse cursor, too.
#------------------------------------------------------------------------------
proc tablelist::labelB1Leave {w x y} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked) ||
	[info exists data(colBeingResized)]} {	;# resize operation in progress
	return ""
    }

    #
    # The following code is needed because the event
    # can also occur in a widget placed into the label
    #
    if {$x >= 1 && $x < [winfo width $w] - 1 &&
	$y >= 0 && $y < [winfo height $w]} {
	return ""
    }

    set data(inClickedLabel) 0
    configLabel $w -relief $data(relief) -pressed 0
}

#------------------------------------------------------------------------------
# tablelist::labelB1Up
#
# This procedure is invoked when mouse button 1 is released, if it was
# previously clicked in a label of the tablelist widget win.  If this event
# occured during a column resize operation then the procedure redisplays the
# column and stretches the stretchable columns.  Otherwise, if the mouse button
# was released in the previously clicked label then the procedure restores the
# label's relief and invokes the command specified by the -labelcommand or
# -labelcommand2 configuration option, passing to it the widget name and the
# column number as arguments.  Otherwise the column of the previously clicked
# label is moved before the column containing the mouse cursor or to its right,
# if the columns are movable.
#------------------------------------------------------------------------------
proc tablelist::labelB1Up {w X} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked)} {
	return ""
    }

    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	configLabel $w -cursor $data(-cursor)
	if {[winfo exists $data(focus)]} {
	    focus $data(focus)
	}
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	set col $data(colBeingResized)
	if {$data(colResized)} {
	    if {$data(-width) <= 0} {
		$data(hdr) configure -width $data(hdrPixels)
		$data(lb) configure -width \
			  [expr {$data(hdrPixels) / $data(charWidth)}]
	    } elseif {[info exists data(stretchableCols)] &&
		      [lsearch -exact $data(stretchableCols) $col] >= 0} {
		set oldColWidth \
		    [expr {$data(oldStretchedColWidth) - $data(oldColDelta)}]
		set stretchedColWidth \
		    [expr {$data(oldStretchedColWidth) + $X - $data(X)}]
		if {$oldColWidth < $data(stretchablePixels) &&
		    $stretchedColWidth >= $data(minColWidth) &&
		    $stretchedColWidth < $oldColWidth + $data(delta)} {
		    #
		    # Compute the new column width,
		    # using the following equations:
		    #
		    # $colWidth = $stretchedColWidth - $colDelta
		    # $colDelta / $colWidth =
		    #    ($data(delta) - $colWidth + $oldColWidth) /
		    #    ($data(stretchablePixels) + $colWidth - $oldColWidth)
		    #
		    set colWidth [expr {
			$stretchedColWidth *
			($data(stretchablePixels) - $oldColWidth) /
			($data(stretchablePixels) + $data(delta) -
			 $stretchedColWidth)
		    }]
		    if {$colWidth < 1} {
			set colWidth 1
		    }
		    set idx [expr {3*$col}]
		    set data(-columns) \
			[lreplace $data(-columns) $idx $idx -$colWidth]
		    set idx [expr {2*$col}]
		    set data(colList) \
			[lreplace $data(colList) $idx $idx $colWidth]
		    set data($col-delta) [expr {$stretchedColWidth - $colWidth}]
		}
	    }
	}
	unset data(colBeingResized)
	$data(body) tag remove visibleLines 1.0 end
	$data(body) tag configure visibleLines -tabs {}

	if {$data(colResized)} {
	    redisplayCol $win $col 0 last
	    adjustColumns $win {} 0
	    stretchColumns $win $col
	    updateColors $win

	    genVirtualEvent $win <<TablelistColumnResized>> $col
	}
    } else {
	if {[info exists data(X)]} {
	    unset data(X)
	    after cancel $data(afterId)
	    set data(afterId) ""
	}
    	if {$data(-movablecolumns)} {
	    if {[winfo exists $data(focus)]} {
		focus $data(focus)
	    }
	    bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	    place forget $data(colGap)
	}

	if {$data(inClickedLabel)} {
	    configLabel $w -relief $data(relief) -pressed 0
	    if {$data(shiftPressed)} {
		if {[info exists data($col-labelcommand2)]} {
		    uplevel #0 $data($col-labelcommand2) [list $win $col]
		} elseif {[string length $data(-labelcommand2)] != 0} {
		    uplevel #0 $data(-labelcommand2) [list $win $col]
		}
	    } else {
		if {[info exists data($col-labelcommand)]} {
		    uplevel #0 $data($col-labelcommand) [list $win $col]
		} elseif {[string length $data(-labelcommand)] != 0} {
		    uplevel #0 $data(-labelcommand) [list $win $col]
		}
	    }
	} elseif {$data(-movablecolumns)} {
	    $data(hdrTxtFrCanv)$col configure -cursor $data(-cursor)
	    if {[info exists data(targetCol)]} {
		set sourceColName [doColCget $col $win -name]
		set targetColName [doColCget $data(targetCol) $win -name]

		moveCol $win $col $data(targetCol)

		set userData \
		    [list $col $data(targetCol) $sourceColName $targetColName]
		genVirtualEvent $win <<TablelistColumnMoved>> $userData

		unset data(targetCol)
	    }
	}
    }

    set data(labelClicked) 0
}

#------------------------------------------------------------------------------
# tablelist::labelB3Down
#
# This procedure is invoked when mouse button 3 is pressed in the header label
# w of a tablelist widget.  If the Shift key was down when this event occured
# then the procedure restores the last static width of the given column;
# otherwise it configures the width of the given column to be just large enough
# to hold all the elements (including the label).
#------------------------------------------------------------------------------
proc tablelist::labelB3Down {w shiftPressed} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(isDisabled) &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	if {$shiftPressed} {
	    doColConfig $col $win -width -$data($col-lastStaticWidth)
	} else {
	    doColConfig $col $win -width 0
	}

	genVirtualEvent $win <<TablelistColumnResized>> $col
    }
}

#------------------------------------------------------------------------------
# tablelist::labelDblB1
#
# This procedure is invoked when the header label w of a tablelist widget is
# double-clicked.  If the pointer is on the right border of the label then the
# procedure performs the same action as labelB3Down.
#------------------------------------------------------------------------------
proc tablelist::labelDblB1 {w x shiftPressed} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(isDisabled) && [inResizeArea $w $x col] &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	if {$shiftPressed} {
	    doColConfig $col $win -width -$data($col-lastStaticWidth)
	} else {
	    doColConfig $col $win -width 0
	}

	genVirtualEvent $win <<TablelistColumnResized>> $col
    }
}

#------------------------------------------------------------------------------
# tablelist::escape
#
# This procedure is invoked to process <Escape> events in the top-level window
# containing the tablelist widget win during a column resize or move operation.
# The procedure cancels the action in progress and, in case of column resizing,
# it restores the initial width of the respective column.
#------------------------------------------------------------------------------
proc tablelist::escape {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrLbl)$col
    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	configLabel $w -cursor $data(-cursor)
	update idletasks
	if {![array exists ::tablelist::ns${win}::data]} {
	    return ""
	}
	if {[winfo exists $data(focus)]} {
	    focus $data(focus)
	}
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	set data(labelClicked) 0
	set col $data(colBeingResized)
	set idx [expr {3*$col}]
	setupColumns $win [lreplace $data(-columns) $idx $idx \
				    $data(configColWidth)] 0
	redisplayCol $win $col $data(topRow) $data(btmRow)
	unset data(colBeingResized)
	$data(body) tag remove visibleLines 1.0 end
	$data(body) tag configure visibleLines -tabs {}
	adjustColumns $win {} 1
	updateColors $win
    } elseif {!$data(inClickedLabel)} {
	configLabel $w -cursor $data(-cursor)
	$data(hdrTxtFrCanv)$col configure -cursor $data(-cursor)
	if {[winfo exists $data(focus)]} {
	    focus $data(focus)
	}
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	place forget $data(colGap)
	if {[info exists data(targetCol)]} {
	    unset data(targetCol)
	}
	if {[info exists data(X)]} {
	    unset data(X)
	    after cancel $data(afterId)
	    set data(afterId) ""
	}
	set data(labelClicked) 0
    }
}

#------------------------------------------------------------------------------
# tablelist::horizAutoScan
#
# This procedure is invoked when the mouse leaves the scrollable part of a
# tablelist widget's header frame while button 1 is down.  It scrolls the
# header and reschedules itself as an after command so that the header
# continues to scroll until the mouse moves back into the window or the mouse
# button is released.
#------------------------------------------------------------------------------
proc tablelist::horizAutoScan win {
    if {![array exists ::tablelist::ns${win}::data]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {![info exists data(X)]} {
	return ""
    }

    set X $data(X)
    set hdrX [winfo rootx $data(hdr)]
    if {$data(-titlecolumns) == 0 || ![winfo viewable $data(sep)]} {
	set leftX $hdrX
    } else {
	set leftX [expr {[winfo rootx $data(sep)] + 1}]
    }
    set rightX [expr {$hdrX + [winfo width $data(hdr)]}]
    if {$data(-titlecolumns) == 0} {
	set units 2
	set ms 50
    } else {
	set units 1
	set ms 250
    }

    if {$X >= $rightX} {
	::$win xview scroll $units units
    } elseif {$X < $leftX} {
	::$win xview scroll -$units units
    } else {
	return ""
    }

    set data(afterId) [after $ms [list tablelist::horizAutoScan $win]]
}

#------------------------------------------------------------------------------
# tablelist::inResizeArea
#
# Checks whether the given x coordinate relative to the header label w of a
# tablelist widget is in the resize area of that label or of the one to its
# left.
#------------------------------------------------------------------------------
proc tablelist::inResizeArea {w x colName} {
    if {![parseLabelPath $w dummy _col]} {
	return 0
    }


    upvar $colName col
    if {$x >= [winfo width $w] - 5} {
	set col $_col
	return 1
    } elseif {$x < 5} {
	set X [expr {[winfo rootx $w] - 3}]
	set contW [winfo containing -displayof $w $X [winfo rooty $w]]
	return [parseLabelPath $contW dummy col]
    } else {
	return 0
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistConfig.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
#==============================================================================
# Contains private configuration procedures for tablelist widgets.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#------------------------------------------------------------------------------
# tablelist::extendConfigSpecs
#
# Extends the elements of the array configSpecs.
#------------------------------------------------------------------------------
proc tablelist::extendConfigSpecs {} {
    variable usingTile
    variable helpLabel
    variable configSpecs
    variable winSys

    #
    # Extend some elements of the array configSpecs
    #
    lappend configSpecs(-acceptchildcommand)	{}
    lappend configSpecs(-acceptdropcommand)	{}
    lappend configSpecs(-activestyle)		frame
    lappend configSpecs(-autofinishediting)	0
    lappend configSpecs(-autoscan)		1
    lappend configSpecs(-collapsecommand)	{}
    lappend configSpecs(-colorizecommand)	{}
    lappend configSpecs(-columns)		{}
    lappend configSpecs(-columntitles)		{}
    lappend configSpecs(-customdragsource)	0
    lappend configSpecs(-editendcommand)	{}
    lappend configSpecs(-editselectedonly)	0
    lappend configSpecs(-editstartcommand)	{}
    lappend configSpecs(-expandcommand)		{}
    lappend configSpecs(-forceeditendcommand)	0
    lappend configSpecs(-fullseparators)	0
    lappend configSpecs(-incrarrowtype)		up
    lappend configSpecs(-instanttoggle)		0
    lappend configSpecs(-labelcommand)		{}
    lappend configSpecs(-labelcommand2)		{}
    lappend configSpecs(-labelrelief)		raised
    lappend configSpecs(-listvariable)		{}
    lappend configSpecs(-movablecolumns)	0
    lappend configSpecs(-movablerows)		0
    lappend configSpecs(-populatecommand)	{}
    lappend configSpecs(-protecttitlecolumns)	0
    lappend configSpecs(-resizablecolumns)	1
    lappend configSpecs(-selecttype)		row
    lappend configSpecs(-setfocus)		1
    lappend configSpecs(-showarrow)		1
    lappend configSpecs(-showeditcursor)	1
    lappend configSpecs(-showhorizseparator)	1
    lappend configSpecs(-showlabels)		1
    lappend configSpecs(-showseparators)	0
    lappend configSpecs(-snipstring)		...
    lappend configSpecs(-sortcommand)		{}
    lappend configSpecs(-spacing)		0
    lappend configSpecs(-stretch)		{}
    lappend configSpecs(-stripebackground)	{}
    lappend configSpecs(-stripeforeground)	{}
    lappend configSpecs(-stripeheight)		1
    lappend configSpecs(-targetcolor)		black
    lappend configSpecs(-tight)			0
    lappend configSpecs(-titlecolumns)		0
    lappend configSpecs(-tooltipaddcommand)	{}
    lappend configSpecs(-tooltipdelcommand)	{}
    lappend configSpecs(-treecolumn)		0

    #
    # Append the default values of the configuration options
    # of a temporary, invisible listbox widget to the values
    # of the corresponding elements of the array configSpecs
    #
    set helpListbox .__helpListbox
    for {set n 2} {[winfo exists $helpListbox]} {incr n} {
	set helpListbox .__helpListbox$n
    }
    listbox $helpListbox
    foreach configSet [$helpListbox configure] {
	if {[llength $configSet] != 2} {
	    set opt [lindex $configSet 0]
	    if {[info exists configSpecs($opt)]} {
		lappend configSpecs($opt) [lindex $configSet 3]
	    }
	}
    }
    destroy $helpListbox

    set helpLabel .__helpLabel
    for {set n 0} {[winfo exists $helpLabel]} {incr n} {
	set helpLabel .__helpLabel$n
    }

    if {$usingTile} {
	foreach opt {-highlightbackground -highlightcolor -highlightthickness
		     -labelactivebackground -labelactiveforeground
		     -labelbackground -labelbg -labeldisabledforeground
		     -labelheight} {
	    unset configSpecs($opt)
	}

	#
	# Append theme-specific values to some elements of the
	# array configSpecs and initialize some tree resources
	#
	if {[string compare [getCurrentTheme] "tileqt"] == 0} {
	    tileqt_kdeStyleChangeNotification 
	}
	setThemeDefaults
	variable themeDefaults
	set treeStyle $themeDefaults(-treestyle)
	${treeStyle}TreeImgs 
	variable maxIndentDepths
	set maxIndentDepths($treeStyle) 0

	ttk::label $helpLabel -takefocus 0

	#
	# Define the header label layout
	#
	style theme settings "default" {
	    style layout TablelistHeader.TLabel {
		Treeheading.cell
		Treeheading.border -children {
		    Label.padding -children {
			Label.label
		    }
		}
	    }
	}
	if {[string length [package provide ttk::theme::aqua]] != 0 ||
	    [string length [package provide tile::theme::aqua]] != 0} {
	    style theme settings "aqua" {
		if {[info exists tile::patchlevel] &&
		    [string compare $tile::patchlevel "0.6.4"] < 0} {
		    style layout TablelistHeader.TLabel {
			Treeheading.cell
			Label.padding -children {
			    Label.label -side top
			    Separator.hseparator -side bottom
			}
		    }
		} else {
		    style layout TablelistHeader.TLabel {
			Treeheading.cell
			Label.padding -children {
			    Label.label -side top
			}
		    }
		}
		style map TablelistHeader.TLabel -foreground [list \
		    {disabled background} #a3a3a3 disabled #a3a3a3 \
		    background black]
	    }
	}
    } else {
	if {$::tk_version < 8.3} {
	    unset configSpecs(-acceptchildcommand)
	    unset configSpecs(-collapsecommand)
	    unset configSpecs(-expandcommand)
	    unset configSpecs(-populatecommand)
	    unset configSpecs(-titlecolumns)
	    unset configSpecs(-treecolumn)
	    unset configSpecs(-treestyle)
	}

	#
	# Append the default values of some configuration options
	# of an invisible label widget to the values of the
	# corresponding -label* elements of the array configSpecs
	#
	tk::label $helpLabel -takefocus 0
	foreach optTail {font height} {
	    set configSet [$helpLabel configure -$optTail]
	    lappend configSpecs(-label$optTail) [lindex $configSet 3]
	}
	if {[catch {$helpLabel configure -activebackground} configSet1] == 0 &&
	    [catch {$helpLabel configure -activeforeground} configSet2] == 0} {
	    lappend configSpecs(-labelactivebackground) [lindex $configSet1 3]
	    lappend configSpecs(-labelactiveforeground) [lindex $configSet2 3]
	} else {
	    unset configSpecs(-labelactivebackground)
	    unset configSpecs(-labelactiveforeground)
	}
	if {[catch {$helpLabel configure -disabledforeground} configSet] == 0} {
	    lappend configSpecs(-labeldisabledforeground) [lindex $configSet 3]
	} else {
	    unset configSpecs(-labeldisabledforeground)
	}
	if {[string compare $winSys "win32"] == 0 &&
	    $::tcl_platform(osVersion) < 5.1} {
	    lappend configSpecs(-labelpady) 0
	} else {
	    set configSet [$helpLabel configure -pady]
	    lappend configSpecs(-labelpady) [lindex $configSet 3]
	}

	#
	# Steal the default values of some configuration
	# options from a temporary, invisible button widget
	#
	set helpButton .__helpButton
	for {set n 0} {[winfo exists $helpButton]} {incr n} {
	    set helpButton .__helpButton$n
	}
	button $helpButton
	foreach opt {-disabledforeground -state} {
	    if {[llength $configSpecs($opt)] == 3} {
		set configSet [$helpButton configure $opt]
		lappend configSpecs($opt) [lindex $configSet 3]
	    }
	}
	foreach optTail {background foreground} {
	    set configSet [$helpButton configure -$optTail]
	    lappend configSpecs(-label$optTail) [lindex $configSet 3]
	}
	if {[string compare $winSys "classic"] == 0 ||
	    [string compare $winSys "aqua"] == 0} {
	    lappend configSpecs(-labelborderwidth) 1
	} else {
	    set configSet [$helpButton configure -borderwidth]
	    lappend configSpecs(-labelborderwidth) [lindex $configSet 3]
	}
	destroy $helpButton

	#
	# Set the default values of the -arrowcolor,
	# -arrowdisabledcolor, -arrowstyle, and -treestyle options
	#
	switch $winSys {
	    x11 {
		set arrowColor		black
		set arrowDisabledColor	#a3a3a3
		set arrowStyle		flat7x5
		set treeStyle		gtk
	    }

	    win32 {
		if {$::tcl_platform(osVersion) < 5.1} {		;# Win native
		    set arrowColor		{}
		    set arrowDisabledColor	{}
		    set arrowStyle		sunken8x7
		    set treeStyle		winnative

		} elseif {$::tcl_platform(osVersion) == 5.1} {	;# Win XP
		    switch [winfo rgb . SystemHighlight] {
			"12593 27242 50629" {			;# Win XP Blue
			    set arrowColor	#aca899
			    set arrowStyle	flat9x5
			    set treeStyle	winxpBlue
			}
			"37779 41120 28784" {			;# Win XP Olive
			    set arrowColor	#aca899
			    set arrowStyle	flat9x5
			    set treeStyle	winxpOlive
			}
			"45746 46260 49087" {			;# Win XP Silver
			    set arrowColor	#aca899
			    set arrowStyle	flat9x5
			    set treeStyle	winxpSilver
			}
			default {				;# Win Classic
			    set arrowColor	SystemButtonShadow
			    set arrowStyle	flat7x4
			    set treeStyle	winnative
			}
		    }
		    set arrowDisabledColor	SystemDisabledText

		} elseif {$::tcl_platform(osVersion) == 6.0} {	;# Win Vista
		    variable scalingpct

		    switch [winfo rgb . SystemHighlight] {
			"13107 39321 65535" {			;# Vista Aero
			    set arrowColor	#569bc0
			    switch $scalingpct {
				100 { set arrowStyle	photo7x4 }
				125 { set arrowStyle	photo9x5 }
				150 { set arrowStyle	photo11x6 }
				200 { set arrowStyle	photo15x8 }
			    }
			    set treeStyle	vistaAero
			}
			default {				;# Win Classic
			    set arrowColor	SystemButtonShadow
			    switch $scalingpct {
				100 { set arrowStyle	flat7x4 }
				125 { set arrowStyle	flat9x5 }
				150 { set arrowStyle	flat11x6 }
				200 { set arrowStyle	flat15x8 }
			    }
			    set treeStyle	vistaClassic
			}
		    }
		    set arrowDisabledColor	SystemDisabledText

		} elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 7/8
		    variable scalingpct

		    switch [winfo rgb . SystemHighlight] {
			"13107 39321 65535" {			;# Win 7/8 Aero
			    set arrowColor	#569bc0
			    switch $scalingpct {
				100 { set arrowStyle	photo7x4 }
				125 { set arrowStyle	photo9x5 }
				150 { set arrowStyle	photo11x6 }
				200 { set arrowStyle	photo15x8 }
			    }
			    set treeStyle	win7Aero
			}
			default {				;# Win Classic
			    set arrowColor	SystemButtonShadow
			    switch $scalingpct {
				100 { set arrowStyle	flat7x4 }
				125 { set arrowStyle	flat9x5 }
				150 { set arrowStyle	flat11x6 }
				200 { set arrowStyle	flat15x8 }
			    }
			    set treeStyle	win7Classic
			}
		    }
		    set arrowDisabledColor	SystemDisabledText

		} else {					;# Win 10
		    variable scalingpct
		    switch $scalingpct {
			100 { set arrowStyle	flatAngle7x4 }
			125 { set arrowStyle	flatAngle9x5 }
			150 { set arrowStyle	flatAngle11x6 }
			200 { set arrowStyle	flatAngle15x8 }
		    }

		    set arrowColor		#595959
		    set arrowDisabledColor	SystemDisabledText
		    set treeStyle		win10
		}
	    }

	    classic -
	    aqua {
		scan $::tcl_platform(osVersion) "%d" majorOSVersion
		if {$majorOSVersion >= 14} {		;# OS X 10.10 or higher
		    set arrowColor	#404040
		    set arrowStyle	flatAngle7x4
		} else {
		    set arrowColor	#717171
		    variable pngSupported
		    if {$pngSupported} {
			set arrowStyle	photo7x7
		    } else {
			set arrowStyle	flat7x7
		    }
		}
		set arrowDisabledColor	#a3a3a3
		set treeStyle		aqua
	    }
	}
	lappend configSpecs(-arrowcolor)		$arrowColor
	lappend configSpecs(-arrowdisabledcolor)	$arrowDisabledColor
	lappend configSpecs(-arrowstyle)		$arrowStyle
	if {$::tk_version >= 8.3} {
	    lappend configSpecs(-treestyle)		$treeStyle
	    ${treeStyle}TreeImgs 
	    variable maxIndentDepths
	    set maxIndentDepths($treeStyle) 0
	}
    }

    #
    # Set the default values of the -movecolumncursor,
    # -movecursor, and -resizecursor options
    #
    switch $winSys {
	x11 -
	win32 {
	    set movecolumnCursor	icon
	    set moveCursor		hand2
	    set resizeCursor		sb_h_double_arrow
	}

	classic -
	aqua {
	    set movecolumnCursor	closedhand
	    set moveCursor		pointinghand
	    if {[catch {$helpLabel configure -cursor resizeleftright}] == 0} {
		set resizeCursor	resizeleftright
	    } else {
		set resizeCursor	sb_h_double_arrow
	    }
	}
    }
    lappend configSpecs(-movecolumncursor)	$movecolumnCursor
    lappend configSpecs(-movecursor)		$moveCursor
    lappend configSpecs(-resizecursor)		$resizeCursor

    variable centerArrows 0
    if {[string compare $winSys "win32"] == 0 &&
	$::tcl_platform(osVersion) >= 6.0 &&
	[string compare [winfo rgb . SystemHighlight] \
			"13107 39321 65535"] == 0} {
	set centerArrows 1
    }
}

#------------------------------------------------------------------------------
# tablelist::doConfig
#
# Applies the value val of the configuration option opt to the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::doConfig {win opt val} {
    variable usingTile
    variable helpLabel
    variable configSpecs
    upvar ::tablelist::ns${win}::data data

    #
    # Apply the value to the widget(s) corresponding to the given option
    #
    switch [lindex $configSpecs($opt) 2] {
	c {
	    #
	    # Apply the value to all children and save the
	    # properly formatted value of val in data($opt)
	    #
	    foreach w [winfo children $win] {
		if {[regexp {^(body|hdr|h?sep[0-9]*)$} [winfo name $w]]} {
		    $w configure $opt $val
		}
	    }
	    $data(hdrTxt) configure $opt $val
	    $data(hdrFrLbl) configure $opt $val
	    $data(cornerLbl) configure $opt $val
	    foreach w [winfo children $data(hdrTxtFr)] {
		$w configure $opt $val
	    }
	    set data($opt) [$data(hdrFrLbl) cget $opt]
	}

	b {
	    #
	    # Apply the value to the body text widget and save
	    # the properly formatted value of val in data($opt)
	    #
	    set w $data(body)
	    $w configure $opt $val
	    set data($opt) [$w cget $opt]

	    switch -- $opt {
		-background {
		    #
		    # Apply the value to the frame (because of the shadow
		    # colors of its 3-D border), to the separators,
		    # to the header frame, and to the "disabled" tag
		    #
		    if {$usingTile} {
			styleConfig Frame$win.TFrame $opt $val
			styleConfig Seps$win.TSeparator $opt $val
		    } else {
			$win configure $opt $val
			foreach c [winfo children $win] {
			    if {[regexp {^(sep[0-9]+|hsep)$} [winfo name $c]]} {
				$c configure $opt $val
			    }
			}
		    }
		    $data(hdr) configure $opt $val
		    $w tag configure disabled $opt $val
		    updateColorsWhenIdle $win
		}
		-font {
		    #
		    # Apply the value to the listbox child, rebuild the lists
		    # of the column fonts and tag names, configure the edit
		    # window if present, set up and adjust the columns, and
		    # make sure the items will be redisplayed at idle time
		    #
		    $data(lb) configure $opt $val
		    set data(charWidth) [font measure $val -displayof $win 0]
		    makeColFontAndTagLists $win
		    if {$data(editRow) >= 0} {
			setEditWinFont $win
		    }
		    for {set col 0} {$col < $data(colCount)} {incr col} {
			if {$data($col-maxwidth) > 0} {
			    set data($col-maxPixels) \
				[charsToPixels $win $val $data($col-maxwidth)]
			}
		    }
		    setupColumns $win $data(-columns) 0
		    adjustColumns $win allCols 1
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-foreground {
		    #
		    # Set the background color of the main separator
		    # (if any) to the specified value, and apply
		    # this value to the "disabled" tag if needed
		    #
		    if {$usingTile} {
			styleConfig Sep$win.TSeparator -background $val
		    } else {
			if {[winfo exists $data(sep)]} {
			    $data(sep) configure -background $val
			}
		    }
		    if {[string length $data(-disabledforeground)] == 0} {
			$w tag configure disabled $opt $val
		    }
		    updateColorsWhenIdle $win
		}
	    }
	}

	l {
	    #
	    # Apply the value to all not individually configured labels
	    # and save the properly formatted value of val in data($opt)
	    #
	    set optTail [string range $opt 6 end]	;# remove the -label
	    configLabel $data(hdrFrLbl) -$optTail $val
	    configLabel $data(cornerLbl) -$optTail $val
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set w $data(hdrTxtFrLbl)$col
		if {![info exists data($col$opt)]} {
		    configLabel $w -$optTail $val
		}
	    }
	    if {$usingTile && [string compare $opt "-labelpady"] == 0} {
		set data($opt) $val
	    } else {
		set data($opt) [$data(hdrFrLbl) cget -$optTail]
	    }

	    switch -- $opt {
		-labelbackground -
		-labelforeground {
		    #
		    # Apply the value to $data(hdrTxt) and conditionally
		    # to the canvases displaying up- or down-arrows
		    #
		    $helpLabel configure -$optTail $val
		    set data($opt) [$helpLabel cget -$optTail]
		    $data(hdrTxt) configure -$optTail $data($opt)
		    foreach col $data(arrowColList) {
			if {![info exists data($col$opt)]} {
			    configCanvas $win $col
			}
		    }
		}
		-labelborderwidth {
		    #
		    # Adjust the columns (including
		    # the height of the header frame)
		    #
		    adjustColumns $win allLabels 1

		    set borderWidth [winfo pixels $win $data($opt)]
		    if {$borderWidth < 0} {
			set borderWidth 0
		    }
		    place configure $data(cornerLbl) -x -$borderWidth \
			-width [expr {2*$borderWidth}]
		}
		-labeldisabledforeground {
		    #
		    # Conditionally apply the value to the
		    # canvases displaying up- or down-arrows
		    #
		    foreach col $data(arrowColList) {
			if {![info exists data($col$opt)]} {
			    configCanvas $win $col
			}
		    }
		}
		-labelfont {
		    #
		    # Apply the value to $data(hdrTxt) and adjust the
		    # columns (including the height of the header frame)
		    #
		    $data(hdrTxt) configure -$optTail $data($opt)
		    adjustColumns $win allLabels 1
		}
		-labelheight -
		-labelpady {
		    #
		    # Adjust the height of the header frame
		    #
		    adjustHeaderHeight $win
		}
	    }
	}

	f {
	    #
	    # Apply the value to the frame and save the
	    # properly formatted value of val in data($opt)
	    #
	    $win configure $opt $val
	    set data($opt) [$win cget $opt]
	}

	w {
	    switch -- $opt {
		-acceptchildcommand -
		-acceptdropcommand -
		-collapsecommand -
		-colorizecommand -
		-editendcommand -
		-editstartcommand -
		-expandcommand -
		-labelcommand -
		-labelcommand2 -
		-populatecommand -
		-selectmode -
		-sortcommand -
		-tooltipaddcommand -
		-tooltipdelcommand -
		-yscrollcommand {
		    set data($opt) $val
		}
		-activestyle {
		    #
		    # Configure the "active" tag and save the
		    # properly formatted value of val in data($opt)
		    #
		    variable activeStyles
		    set val [mwutil::fullOpt "active style" $val $activeStyles]
		    set w $data(body)
		    switch $val {
			frame {
			    $w tag configure active \
				   -borderwidth 1 -relief solid -underline ""
			}
			none {
			    $w tag configure active \
				   -borderwidth "" -relief "" -underline ""
			}
			underline {
			    $w tag configure active \
				   -borderwidth "" -relief "" -underline 1
			}
		    }
		    set data($opt) $val
		}
		-arrowcolor -
		-arrowdisabledcolor {
		    #
		    # Save the properly formatted value of val in data($opt)
		    # and set the color of the normal or disabled arrows
		    #
		    if {[string length $val] == 0} {
			set data($opt) ""
		    } else {
			$helpLabel configure -foreground $val
			set data($opt) [$helpLabel cget -foreground]
		    }
		    if {([string compare $opt "-arrowcolor"] == 0 &&
			 !$data(isDisabled)) ||
			([string compare $opt "-arrowdisabledcolor"] == 0 &&
			 $data(isDisabled))} {
			foreach w [info commands $data(hdrTxtFrCanv)*] {
			    fillArrows $w $val $data(-arrowstyle)
			}
		    }
		}
		-arrowstyle {
		    #
		    # Save the properly formatted value of val in data($opt)
		    # and draw the corresponding arrows in the canvas widgets
		    #
		    variable arrowStyles
		    set data($opt) \
			[mwutil::fullOpt "arrow style" $val $arrowStyles]
		    regexp {^(flat|flatAngle|sunken|photo)([0-9]+)x([0-9]+)$} \
			   $data($opt) dummy relief width height
		    set data(arrowWidth) $width
		    set data(arrowHeight) $height
		    foreach w [info commands $data(hdrTxtFrCanv)*] {
			createArrows $w $width $height $relief
			if {$data(isDisabled)} {
			    fillArrows $w $data(-arrowdisabledcolor) $data($opt)
			} else {
			    fillArrows $w $data(-arrowcolor) $data($opt)
			}
		    }
		    if {[llength $data(arrowColList)] > 0} {
			foreach col $data(arrowColList) {
			    raiseArrow $win $col
			    lappend whichWidths l$col
			}
			adjustColumns $win $whichWidths 1
		    }
		}
		-autofinishediting -
		-autoscan -
		-customdragsource -
		-forceeditendcommand -
		-instanttoggle -
		-movablecolumns -
		-movablerows -
		-protecttitlecolumns -
		-resizablecolumns -
		-setfocus {
		    #
		    # Save the boolean value specified by val in data($opt)
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		}
		-columns {
		    #
		    # Set up and adjust the columns, rebuild
		    # the lists of the column fonts and tag
		    # names, and redisplay the items
		    #
		    set selCells [curCellSelection $win]
		    setupColumns $win $val 1
		    adjustColumns $win allCols 1
		    adjustColIndex $win data(anchorCol) 1
		    adjustColIndex $win data(activeCol) 1
		    makeColFontAndTagLists $win
		    redisplay $win 0 $selCells
		    updateViewWhenIdle $win
		}
		-columntitles {
		    set titleCount [llength $val]
		    set colCount $data(colCount)
		    if {$titleCount <= $colCount} {
			#
			# Update the first titleCount column
			# titles and adjust the columns
			#
			set whichWidths {}
			for {set col 0} {$col < $titleCount} {incr col} {
			    set idx [expr {3*$col + 1}]
			    set data(-columns) [lreplace $data(-columns) \
						$idx $idx [lindex $val $col]]
			    lappend whichWidths l$col
			}
			adjustColumns $win $whichWidths 1
		    } else {
			#
			# Update the titles of the current columns,
			# extend the column list, and do nearly the
			# same as in the case of the -columns option
			#
			set columns {}
			set col 0
			foreach {width title alignment} $data(-columns) {
			    lappend columns $width [lindex $val $col] $alignment
			    incr col
			}
			for {} {$col < $titleCount} {incr col} {
			    lappend columns 0 [lindex $val $col] left
			}
			set selCells [curCellSelection $win]
			setupColumns $win $columns 1
			adjustColumns $win allCols 1
			makeColFontAndTagLists $win
			redisplay $win 0 $selCells
			updateViewWhenIdle $win

			#
			# If this option is being set at widget creation time
			# then append "-columns" to the list of command line
			# options processed by the caller proc, to make sure
			# that the columns-related information produced by the
			# setupColumns call above won't be overridden by the
			# default -columns {} option that would otherwise
			# be processed as a non-explicitly specified option
			#
			set callerProc [lindex [info level -1] 0]
			if {[string compare $callerProc \
			     "mwutil::configureWidget"] == 0} {
			    uplevel 1 lappend cmdLineOpts "-columns"
			}
		    }
		}
		-disabledforeground {
		    #
		    # Configure the "disabled" tag in the body text widget and
		    # save the properly formatted value of val in data($opt)
		    #
		    set w $data(body)
		    if {[string length $val] == 0} {
			$w tag configure disabled -fgstipple gray50 \
				-foreground $data(-foreground)
			set data($opt) ""
		    } else {
			$w tag configure disabled -fgstipple "" \
				-foreground $val
			set data($opt) [$w tag cget disabled -foreground]
		    }
		    if {$data(isDisabled)} {
			updateColorsWhenIdle $win
		    }
		}
		-editselectedonly {
		    #
		    # Save the boolean value specified by val in data($opt)
		    # and invoke the motion handler if necessary
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    if {$data(-showeditcursor)} {
			invokeMotionHandler $win
		    }
		}
		-exportselection {
		    #
		    # Save the boolean value specified by val in
		    # data($opt).  In addition, if the selection is
		    # exported and there are any selected rows in the
		    # widget then make win the new owner of the PRIMARY
		    # selection and register a callback to be invoked
		    # when it loses ownership of the PRIMARY selection
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    if {$val &&
			[llength [$data(body) tag nextrange select 1.0]] != 0} {
			selection own -command \
				[list ::tablelist::lostSelection $win] $win
		    }
		}
		-fullseparators -
		-showhorizseparator {
		    #
		    # Save the boolean value specified by val
		    # in data($opt) and adjust the separators
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    adjustSepsWhenIdle $win
		}
		-height {
		    #
		    # Adjust the heights of the body text widget
		    # and of the listbox child, and save the
		    # properly formatted value of val in data($opt)
		    #
		    set val [format "%d" $val]	;# integer check with error msg
		    if {$val <= 0} {
			set viewableRowCount [expr \
			    {$data(itemCount) - $data(nonViewableRowCount)}]
			$data(body) configure $opt $viewableRowCount
			$data(lb) configure $opt $viewableRowCount
		    } else {
			$data(body) configure $opt $val
			$data(lb) configure $opt $val
		    }
		    set data($opt) $val
		}
		-incrarrowtype {
		    #
		    # Save the properly formatted value of val in
		    # data($opt) and raise the corresponding arrows
		    # if the currently mapped canvas widgets
		    #
		    variable arrowTypes
		    set data($opt) \
			[mwutil::fullOpt "arrow type" $val $arrowTypes]
		    foreach col $data(arrowColList) {
			raiseArrow $win $col
		    }
		}
		-listvariable {
		    #
		    # Associate val as list variable with the
		    # given widget and save it in data($opt)
		    #
		    makeListVar $win $val
		    set data($opt) $val
		    if {[string length $val] == 0} {
			set data(hasListVar) 0
		    } else {
			set data(hasListVar) 1
		    }
		}
		-movecolumncursor -
		-movecursor -
		-resizecursor {
		    #
		    # Save the properly formatted value of val in data($opt)
		    #
		    $helpLabel configure -cursor $val
		    set data($opt) [$helpLabel cget -cursor]
		}
		-selectbackground -
		-selectforeground {
		    #
		    # Configure the "select" tag in the body text widget
		    # and save the properly formatted value of val in
		    # data($opt).  Don't use the built-in "sel" tag
		    # because on Windows the selection in a text widget only
		    # becomes visible when the window gets the input focus.
		    #
		    set w $data(body)
		    set optTail [string range $opt 7 end] ;# remove the -select
		    $w tag configure select -$optTail $val
		    set data($opt) [$w tag cget select -$optTail]
		    if {!$data(isDisabled)} {
			updateColorsWhenIdle $win
		    }
		}
		-selecttype {
		    #
		    # Save the properly formatted value of val in data($opt)
		    #
		    variable selectTypes
		    set val [mwutil::fullOpt "selection type" $val $selectTypes]
		    set data($opt) $val
		}
		-selectborderwidth {
		    #
		    # Configure the "select" tag in the body text widget
		    # and save the properly formatted value of val in
		    # data($opt).  Don't use the built-in "sel" tag
		    # because on Windows the selection in a text widget only
		    # becomes visible when the window gets the input focus.
		    # In addition, adjust the line spacing accordingly and
		    # apply the value to the listbox child, too.
		    #
		    set w $data(body)
		    set optTail [string range $opt 7 end] ;# remove the -select
		    $w tag configure select -$optTail $val
		    set data($opt) [$w tag cget select -$optTail]
		    set pixVal [winfo pixels $w $val]
		    if {$pixVal < 0} {
			set pixVal 0
		    }
		    set spacing [winfo pixels $w $data(-spacing)]
		    if {$spacing < 0} {
			set spacing 0
		    }
		    $w configure -spacing1 [expr {$spacing + $pixVal}] \
			-spacing3 [expr {$spacing + $pixVal + !$data(-tight)}]
		    $data(lb) configure $opt $val
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-setgrid {
		    #
		    # Apply the value to the listbox child and save
		    # the properly formatted value of val in data($opt)
		    #
		    $data(lb) configure $opt $val
		    set data($opt) [$data(lb) cget $opt]
		}
		-showarrow {
		    #
		    # Save the boolean value specified by val in
		    # data($opt) and manage or unmanage the
		    # canvases displaying up- or down-arrows
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    makeSortAndArrowColLists $win
		    adjustColumns $win allLabels 1
		}
		-showeditcursor {
		    #
		    # Save the boolean value specified by val in
		    # data($opt) and invoke the motion handler
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    invokeMotionHandler $win
		}
		-showlabels {
		    #
		    # Save the boolean value specified by val in data($opt)
		    # and adjust the height of the header frame
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    adjustHeaderHeight $win
		}
		-showseparators {
		    #
		    # Save the boolean value specified by val in data($opt),
		    # and create or destroy the separators if needed
		    #
		    set oldVal $data($opt)
		    set data($opt) [expr {$val ? 1 : 0}]
		    if {!$oldVal && $data($opt)} {
			createSeps $win
		    } elseif {$oldVal && !$data($opt)} {
			foreach w [winfo children $win] {
			    if {[regexp {^(sep[0-9]+|hsep)$} [winfo name $w]]} {
				destroy $w
			    }
			}
		    }
		}
		-snipstring {
		    #
		    # Save val in data($opt), adjust the columns, and make
		    # sure the items will be redisplayed at idle time
		    #
		    set data($opt) $val
		    adjustColumns $win {} 0
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-spacing {
		    #
		    # Adjust the line spacing and save val in data($opt)
		    #
		    set w $data(body)
		    set pixVal [winfo pixels $w $val]
		    if {$pixVal < 0} {
			set pixVal 0
		    }
		    set selectBd [winfo pixels $w $data(-selectborderwidth)]
		    if {$selectBd < 0} {
			set selectBd 0
		    }
		    $w configure -spacing1 [expr {$pixVal + $selectBd}] \
			-spacing3 [expr {$pixVal + $selectBd + !$data(-tight)}]
		    set data($opt) $val
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-state {
		    #
		    # Apply the value to all labels and their sublabels
		    # (if any), as well as to the edit window (if present),
		    # add/remove the "disabled" tag to/from the contents
		    # of the body text widget, configure the borderwidth
		    # of the "active" and "select" tags, save the
		    # properly formatted value of val in data($opt),
		    # and raise the corresponding arrow in the canvas
		    #
		    variable states
		    set val [mwutil::fullOpt "state" $val $states]
		    catch {
			configLabel $data(hdrFrLbl) $opt $val
			configLabel $data(cornerLbl) $opt $val
			for {set col 0} {$col < $data(colCount)} {incr col} {
			    configLabel $data(hdrTxtFrLbl)$col $opt $val
			}
		    }
		    if {$data(editRow) >= 0} {
			catch {$data(bodyFrEd) configure $opt $val}
		    }
		    set w $data(body)
		    switch $val {
			disabled {
			    $w tag add disabled 1.0 end
			    $w tag configure select -relief flat
			    $w tag configure curRow -relief flat
			    set data(isDisabled) 1
			}
			normal {
			    $w tag remove disabled 1.0 end
			    $w tag configure select -relief raised
			    $w tag configure curRow -relief raised
			    set data(isDisabled) 0
			}
		    }
		    set data($opt) $val
		    foreach col $data(arrowColList) {
			configCanvas $win $col
			raiseArrow $win $col
		    }
		    updateColorsWhenIdle $win
		}
		-stretch {
		    #
		    # Save the properly formatted value of val in
		    # data($opt) and stretch the stretchable columns
		    #
		    if {[string first $val "all"] == 0} {
			set data($opt) all
		    } else {
			set data($opt) $val
			sortStretchableColList $win
		    }
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}
		-stripebackground -
		-stripeforeground {
		    #
		    # Configure the "stripe" tag in the body text
		    # widget, save the properly formatted value of val
		    # in data($opt), and draw the stripes if necessary
		    #
		    set w $data(body)
		    set optTail [string range $opt 7 end] ;# remove the -stripe
		    $w tag configure stripe -$optTail $val
		    set data($opt) [$w tag cget stripe -$optTail]
		    makeStripesWhenIdle $win
		}
		-stripeheight {
		    #
		    # Save the properly formatted value of val in
		    # data($opt) and draw the stripes if necessary
		    #
		    set val [format "%d" $val]	;# integer check with error msg
		    set data($opt) $val
		    makeStripesWhenIdle $win
		}
		-targetcolor {
		    #
		    # Set the color of the row and column gaps, and save
		    # the properly formatted value of val in data($opt)
		    #
		    $data(rowGap) configure -background $val
		    $data(colGap) configure -background $val
		    set data($opt) [$data(rowGap) cget -background]
		}
		-tight {
		    #
		    # Save the boolean value specified by val
		    # in data($opt) and adjust the line spacing
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    set w $data(body)
		    set spacing1 [$w cget -spacing1]
		    $w configure -spacing3 [expr {$spacing1 + !$data($opt)}]
		    updateViewWhenIdle $win
		}
		-titlecolumns {
		    #
		    # Update the value of the -xscrollcommand option, save
		    # the properly formatted value of val in data($opt),
		    # and create or destroy the main separator if needed
		    #
		    set oldVal $data($opt)
		    set val [format "%d" $val]	;# integer check with error msg
		    if {$val < 0} {
			set val 0
		    }
		    xviewSubCmd $win 0
		    set w $data(sep)
		    if {$val == 0} {
			$data(hdrTxt) configure -xscrollcommand \
				      $data(-xscrollcommand)
			if {$oldVal > 0} {
			    destroy $w
			}
		    } else {
			$data(hdrTxt) configure -xscrollcommand ""
			if {$oldVal == 0} {
			    if {$usingTile} {
				ttk::separator $w -style Sep$win.TSeparator \
						   -cursor $data(-cursor) \
						   -orient vertical -takefocus 0
			    } else {
				tk::frame $w -background $data(-foreground) \
					     -borderwidth 1 -container 0 \
					     -cursor $data(-cursor) \
					     -highlightthickness 0 \
					     -relief sunken -takefocus 0 \
					     -width 2
			    }
			    bindtags $w [lreplace [bindtags $w] 1 1 \
					 $data(bodyTag) TablelistBody]
			}
			adjustSepsWhenIdle $win
		    }
		    set data($opt) $val
		    xviewSubCmd $win 0
		    updateHScrlbarWhenIdle $win
		}
		-treecolumn {
		    #
		    # Save the properly formatted value of val in
		    # data($opt), its adjusted value in data(treeCol),
		    # and move the tree images into the new tree column
		    #
		    set oldTreeCol $data(treeCol)
		    set newTreeCol [colIndex $win $val 0]
		    set data($opt) $newTreeCol
		    adjustColIndex $win newTreeCol
		    set data(treeCol) $newTreeCol
		    if {$data(colCount) != 0} {
			set data($opt) $newTreeCol
		    }
		    if {$newTreeCol != $oldTreeCol} {
			for {set row 0} {$row < $data(itemCount)} {incr row} {
			    doCellConfig $row $newTreeCol $win -indent \
				[doCellCget $row $oldTreeCol $win -indent]
			    doCellConfig $row $oldTreeCol $win -indent ""
			}
		    }
		}
		-treestyle {
		    #
		    # Update the tree images and save the properly
		    # formatted value of val in data($opt)
		    #
		    variable treeStyles
		    set newStyle [mwutil::fullOpt "tree style" $val $treeStyles]
		    set oldStyle $data($opt)
		    set treeCol $data(treeCol)
		    if {[string compare $newStyle $oldStyle] != 0} {
			${newStyle}TreeImgs 
			variable maxIndentDepths
			if {![info exists maxIndentDepths($newStyle)]} {
			    set maxIndentDepths($newStyle) 0
			}
			if {$data(colCount) != 0} {
			    for {set row 0} {$row < $data(itemCount)} \
				{incr row} {
				set oldImg \
				    [doCellCget $row $treeCol $win -indent]
				set newImg [strMap \
				    [list $oldStyle $newStyle "Sel" ""] $oldImg]
				if {[regexp {^.+Img([0-9]+)$} $newImg \
				     dummy depth]} {
				    if {$depth > $maxIndentDepths($newStyle)} {
					createTreeImgs $newStyle $depth
					set maxIndentDepths($newStyle) $depth
				    }
				    doCellConfig $row $treeCol $win \
						 -indent $newImg
				}
			    }
			}
		    }
		    set data($opt) $newStyle
		    switch -glob $newStyle {
			baghira -
			klearlooks -
			oxygen? -
			phase -
			plastik -
			vista* -
			winnative -
			winxp*		{ set data(protectIndents) 1 }
			default		{ set data(protectIndents) 0 }
		    }
		    set selCells [curCellSelection $win 1]
		    foreach {key col} $selCells {
			set row [keyToRow $win $key]
			cellSelection $win set $row $col $row $col
		    }
		    if {$data(ownsFocus) && ![info exists data(dispId)]} {
			addActiveTag $win
		    }
		}
		-width {
		    #
		    # Adjust the widths of the body text widget,
		    # header frame, and listbox child, and save the
		    # properly formatted value of val in data($opt)
		    #
		    set val [format "%d" $val]	;# integer check with error msg
		    $data(body) configure $opt $val
		    if {$val <= 0} {
			$data(hdr) configure $opt $data(hdrPixels)
			$data(lb) configure $opt \
				  [expr {$data(hdrPixels) / $data(charWidth)}]
		    } else {
			$data(hdr) configure $opt 0
			$data(lb) configure $opt $val
		    }
		    set data($opt) $val
		}
		-xscrollcommand {
		    #
		    # Save val in data($opt), and apply it to the header text
		    # widget if (and only if) no title columns are being used
		    #
		    set data($opt) $val
		    if {$data(-titlecolumns) == 0} {
			$data(hdrTxt) configure $opt $val
		    } else {
			$data(hdrTxt) configure $opt ""
		    }
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doCget
#
# Returns the value of the configuration option opt for the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::doCget {win opt} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $opt "-columntitles"] == 0} {
	set colTitles {}
	foreach {width title alignment} $data(-columns) {
	    lappend colTitles $title
	}
	return $colTitles
    } else {
	return $data($opt)
    }
}

#------------------------------------------------------------------------------
# tablelist::doColConfig
#
# Applies the value val of the column configuration option opt to the col'th
# column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doColConfig {col win opt val} {
    variable canElide
    upvar ::tablelist::ns${win}::data data

    switch -- $opt {
	-align {
	    #
	    # Set up and adjust the columns, and make sure the
	    # given column will be redisplayed at idle time
	    #
	    set idx [expr {3*$col + 2}]
	    setupColumns $win [lreplace $data(-columns) $idx $idx $val] 0
	    adjustColumns $win {} 0
	    redisplayColWhenIdle $win $col
	}

	-background -
	-foreground {
	    set w $data(body)
	    set name $col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in the body text widget
		#
		set tag col$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-changesnipside -
	-wrap {
	    #
	    # Save the boolean value specified by val in data($col$opt) and
	    # make sure the given column will be redisplayed at idle time
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    if {[lindex $data(-columns) [expr {3*$col}]] != 0} {
		redisplayColWhenIdle $win $col
		updateViewWhenIdle $win
	    }
	}

	-changetitlesnipside {
	    #
	    # Save the boolean value specified by val in
	    # data($col$opt) and adjust the col'th label
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    if {$pixels != 0} {	
		incr pixels $data($col-delta)
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    adjustLabel $win $col $pixels $alignment
	}

	-editable {
	    #
	    # Save the boolean value specified by val in data($col$opt)
	    # and invoke the motion handler if necessary
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    if {$data(-showeditcursor)} {
		invokeMotionHandler $win
	    }
	}

	-editwindow {
	    variable editWin
	    if {[info exists editWin($val-creationCmd)]} {
		set data($col$opt) $val
	    } else {
		return -code error "name \"$val\" is not registered\
				    for interactive cell editing"
	    }
	}

	-font {
	    set w $data(body)
	    set name $col$opt

	    if {[info exists data($name)] &&
		(!$data($col-hide) || $canElide)} {
		#
		# Remove the tag col$opt-$data($name)
		# from the elements of the given column
		#
		set tag col$opt-$data($name)
		for {set line 1} {$line <= $data(itemCount)} {incr line} {
		    findTabs $win $line $col $col tabIdx1 tabIdx2
		    $w tag remove $tag $tabIdx1 $tabIdx2+1c
		}
	    }

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in the body text widget
		#
		set tag col$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag

		if {!$data($col-hide) || $canElide} {
		    #
		    # Apply the tag to the elements of the given column
		    #
		    for {set line 1} {$line <= $data(itemCount)} {incr line} {
			findTabs $win $line $col $col tabIdx1 tabIdx2
			$w tag add $tag $tabIdx1 $tabIdx2+1c
		    }
		}

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    #
	    # Rebuild the lists of the column fonts and tag names
	    #
	    makeColFontAndTagLists $win

	    #
	    # Adjust the columns, and make sure the specified
	    # column will be redisplayed at idle time
	    #
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win

	    if {$col == $data(editCol)} {
		#
		# Configure the edit window
		#
		setEditWinFont $win
	    }
	}

	-formatcommand {
	    if {[string length $val] == 0} {
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
		set fmtCmdFlag 0
	    } else {
		set data($col$opt) $val
		set fmtCmdFlag 1
	    }

	    #
	    # Update the corresponding element of the list data(fmtCmdFlagList)
	    #
	    set data(fmtCmdFlagList) \
		[lreplace $data(fmtCmdFlagList) $col $col $fmtCmdFlag]
	    set data(hasFmtCmds) \
		[expr {[lsearch -exact $data(fmtCmdFlagList) 1] >= 0}]

	    #
	    # Adjust the columns and make sure the specified
	    # column will be redisplayed at idle time
	    #
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win
	}

	-hide {
	    #
	    # Save the boolean value specified by val in data($col$opt),
	    # adjust the columns, and redisplay the items
	    #
	    set oldVal $data($col$opt)
	    set newVal [expr {$val ? 1 : 0}]
	    if {$newVal != $oldVal} {
		if {!$canElide} {
		    set selCells [curCellSelection $win]
		}
		set data($col$opt) $newVal
		if {$newVal} {				;# hiding the column
		    incr data(hiddenColCount)
		    adjustColIndex $win data(anchorCol) 1
		    adjustColIndex $win data(activeCol) 1
		    if {$col == $data(editCol)} {
			doCancelEditing $win
		    }
		} else {
		    incr data(hiddenColCount) -1
		}
		makeColFontAndTagLists $win
		adjustColumns $win $col 1
		if {!$canElide} {
		    redisplay $win 0 $selCells
		    if {!$newVal &&
			[string compare $data(-selecttype) "row"] == 0} {
			foreach row [curSelection $win] {
			    rowSelection $win set $row $row
			}
		    }
		}
		updateViewWhenIdle $win

		genVirtualEvent $win <<TablelistColHiddenStateChanged>> $col
	    }
	}

	-labelalign {
	    if {[string length $val] == 0} {
		#
		# Unset data($col$opt)
		#
		set alignment [lindex $data(colList) [expr {2*$col + 1}]]
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Save the properly formatted value of val in data($col$opt)
		#
		variable alignments
		set val [mwutil::fullOpt "label alignment" $val $alignments]
		set alignment $val
		set data($col$opt) $val
	    }

	    #
	    # Adjust the col'th label
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    if {$pixels != 0} {	
		incr pixels $data($col-delta)
	    }
	    adjustLabel $win $col $pixels $alignment
	}

	-labelbackground -
	-labelforeground {
	    set w $data(hdrTxtFrLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget
		# configuration option to the col'th label and
		# its sublabels (if any), and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and
		# its sublabels (if any), and save the properly
		# formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		variable helpLabel
		$helpLabel configure -$optTail $val
		set data($col$opt) [$helpLabel cget -$optTail]
	    }

	    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
		configCanvas $win $col
	    }
	}

	-labelborderwidth {
	    set w $data(hdrTxtFrLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget configuration
		# option to the col'th label and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and save the
		# properly formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		set data($col$opt) [$w cget -$optTail]
	    }

	    #
	    # Adjust the columns (including the height of the header frame)
	    #
	    adjustColumns $win l$col 1
	}

	-labelcommand -
	-labelcommand2 -
	-name -
	-sortcommand {
	    if {[string length $val] == 0} {
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		set data($col$opt) $val
	    }
	}

	-labelfont {
	    set w $data(hdrTxtFrLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget
		# configuration option to the col'th label and
		# its sublabels (if any), and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and
		# its sublabels (if any), and save the properly
		# formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		set data($col$opt) [$w cget -$optTail]
	    }

	    #
	    # Adjust the columns (including the height of the header frame)
	    #
	    adjustColumns $win l$col 1
	}

	-labelheight -
	-labelpady {
	    set w $data(hdrTxtFrLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget configuration
		# option to the col'th label and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and save the
		# properly formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		variable usingTile
		if {$usingTile} {
		    set data($col$opt) $val
		} else {
		    set data($col$opt) [$w cget -$optTail]
		}
	    }

	    #
	    # Adjust the height of the header frame
	    #
	    adjustHeaderHeight $win
	}

	-labelimage {
	    set w $data(hdrTxtFrLbl)$col
	    if {[string length $val] == 0} {
		foreach l [getSublabels $w] {
		    destroy $l
		}
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		if {![winfo exists $w-il]} {
		    variable configSpecs
		    variable configOpts
		    foreach l [list $w-il $w-tl] {	;# image and text labels
			#
			# Create the label $l
			#
			tk::label $l -borderwidth 0 -height 0 \
				     -highlightthickness 0 -padx 0 \
				     -pady 0 -takefocus 0 -width 0

			#
			# Apply to it the current configuration options
			#
			foreach opt2 $configOpts {
			    if {[string compare \
				 [lindex $configSpecs($opt2) 2] "c"] == 0} {
				$l configure $opt2 $data($opt2)
			    }
			}
			if {[string compare [winfo class $w] "TLabel"] == 0} {
			    variable themeDefaults
			    $l configure -background \
					 $themeDefaults(-labelbackground)
			} else {
			    $l configure -background [$w cget -background]
			    $l configure -foreground [$w cget -foreground]
			}
			$l configure -font [$w cget -font]
			foreach opt2 {-activebackground -activeforeground
				      -disabledforeground -state} {
			    catch {$l configure $opt2 [$w cget $opt2]}
			}

			#
			# Replace the binding tag Label with $w,
			# $data(labelTag), and TablelistSubLabel in
			# the list of binding tags of the label $l
			#
			bindtags $l [lreplace [bindtags $l] 1 1 \
				     $w $data(labelTag) TablelistSubLabel]
		    }
		}

		#
		# Display the specified image in the label
		# $w-il and save val in data($col$opt)
		#
		$w-il configure -image $val
		set data($col$opt) $val
	    }

	    #
	    # Adjust the columns (including the height of the header frame)
	    #
	    adjustColumns $win l$col 1
	}

	-labelrelief {
	    set w $data(hdrTxtFrLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget configuration
		# option to the col'th label and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and save the
		# properly formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		set data($col$opt) [$w cget -$optTail]
	    }
	}

	-maxwidth {
	    #
	    # Save the properly formatted value of val in
	    # data($col$opt), adjust the columns, and make sure
	    # the specified column will be redisplayed at idle time
	    #
	    set val [format "%d" $val]	;# integer check with error message
	    set data($col$opt) $val
	    if {$val > 0} {		;# convention: max. width in characters
		set pixels [charsToPixels $win $data(-font) $val]
	    } elseif {$val < 0} {	;# convention: max. width in pixels
		set pixels [expr {(-1)*$val}]
	    } else {			;# convention: no max. width
		set pixels 0
	    }
	    set data($col-maxPixels) $pixels
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win
	}

	-resizable {
	    #
	    # Save the boolean value specified by val in data($col$opt)
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	}

	-selectbackground -
	-selectforeground {
	    set w $data(body)
	    set name $col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in the body text widget
		#
		set tag col$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -select
		$w tag configure $tag -$optTail $val
		$w tag raise $tag select

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-showarrow {
	    #
	    # Save the boolean value specified by val in data($col$opt) and
	    # manage or unmanage the canvas displaying an up- or down-arrow
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    makeSortAndArrowColLists $win
	    adjustColumns $win l$col 1
	}

	-showlinenumbers {
	    #
	    # Save the boolean value specified by val in
	    # data($col$opt), and make sure the line numbers
	    # will be redisplayed at idle time if needed
	    #
	    set val [expr {$val ? 1 : 0}]
	    if {!$data($col$opt) && $val} {
		showLineNumbersWhenIdle $win
	    }
	    set data($col$opt) $val
	}

	-sortmode {
	    #
	    # Save the properly formatted value of val in data($col$opt)
	    #
	    variable sortModes
	    set data($col$opt) [mwutil::fullOpt "sort mode" $val $sortModes]
	}

	-stretchable {
	    set flag [expr {$val ? 1 : 0}]
	    if {$flag} {
		if {[string compare $data(-stretch) "all"] != 0 &&
		    [lsearch -exact $data(-stretch) $col] < 0} {
		    #
		    # col was not found in data(-stretch): add it to the list
		    #
		    lappend data(-stretch) $col
		    sortStretchableColList $win
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}
	    } elseif {[string compare $data(-stretch) "all"] == 0} {
		#
		# Replace the value "all" of data(-stretch) with
		# the list of all column indices different from col
		#
		set data(-stretch) {}
		for {set n 0} {$n < $data(colCount)} {incr n} {
		    if {$n != $col} {
			lappend data(-stretch) $n
		    }
		}
		set data(forceAdjust) 1
		stretchColumnsWhenIdle $win
	    } else {
		#
		# If col is contained in data(-stretch)
		# then remove it from the list
		#
		if {[set n [lsearch -exact $data(-stretch) $col]] >= 0} {
		    set data(-stretch) [lreplace $data(-stretch) $n $n]
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}

		#
		# If col indicates the last column and data(-stretch)
		# contains "end" then remove "end" from the list
		#
		if {$col == $data(lastCol) &&
		    [string compare [lindex $data(-stretch) end] "end"] == 0} {
		    set data(-stretch) [lreplace $data(-stretch) end end]
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}
	    }
	}

	-stripebackground -
	-stripeforeground {
	    set w $data(body)
	    set name $col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in the body text widget
		#
		set tag col$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -stripe
		$w tag configure $tag -$optTail $val
		$w tag raise $tag stripe

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-text {
	    if {$data(isDisabled) || $data($col-showlinenumbers)} {
		return ""
	    }

	    #
	    # Replace the column's contents in the internal list
	    #
	    set newItemList {}
	    set row 0
	    foreach item $data(itemList) text [lrange $val 0 $data(lastRow)] {
		set item [lreplace $item $col $col $text]
		lappend newItemList $item
	    }
	    set data(itemList) $newItemList

	    #
	    # Update the list variable if present
	    #
	    condUpdateListVar $win

	    #
	    # Adjust the columns and make sure the specified
	    # column will be redisplayed at idle time
	    #
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win
	}

	-title {
	    #
	    # Save the given value in the corresponding
	    # element of data(-columns) and adjust the columns
	    #
	    set idx [expr {3*$col + 1}]
	    set data(-columns) [lreplace $data(-columns) $idx $idx $val]
	    adjustColumns $win l$col 1
	}

	-valign {
	    #
	    # Save the properly formatted value of val in data($col$opt) and
	    # make sure the given column will be redisplayed at idle time
	    #
	    variable valignments
	    set val [mwutil::fullOpt "vertical alignment" $val $valignments]
	    if {[string compare $val $data($col$opt)] != 0} {
		set data($col$opt) $val
		redisplayColWhenIdle $win $col
	    }
	}

	-width {
	    #
	    # Set up and adjust the columns, and make sure the
	    # given column will be redisplayed at idle time
	    #
	    set idx [expr {3*$col}]
	    if {$val != [lindex $data(-columns) $idx]} {
		setupColumns $win [lreplace $data(-columns) $idx $idx $val] 0
		redisplayColWhenIdle $win $col	;# here before adjustColumns!
		adjustColumns $win $col 1
		updateViewWhenIdle $win
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doColCget
#
# Returns the value of the column configuration option opt for the col'th
# column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doColCget {col win opt} {
    upvar ::tablelist::ns${win}::data data

    switch -- $opt {
	-align {
	    return [lindex $data(-columns) [expr {3*$col + 2}]]
	}

	-stretchable {
	    return [expr {
		[string compare $data(-stretch) "all"] == 0 ||
		[lsearch -exact $data(-stretch) $col] >= 0 ||
		($col == $data(lastCol) && \
		 [string compare [lindex $data(-stretch) end] "end"] == 0)
	    }]
	}

	-text {
	    set result {}
	    foreach item $data(itemList) {
		lappend result [lindex $item $col]
	    }
	    return $result
	}

	-title {
	    return [lindex $data(-columns) [expr {3*$col + 1}]]
	}

	-width {
	    return [lindex $data(-columns) [expr {3*$col}]]
	}

	default {
	    if {[info exists data($col$opt)]} {
		return $data($col$opt)
	    } else {
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doRowConfig
#
# Applies the value val of the row configuration option opt to the row'th row
# of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doRowConfig {row win opt val} {
    variable canElide
    variable elide
    variable snipSides
    upvar ::tablelist::ns${win}::data data

    set w $data(body)

    switch -- $opt {
	-background -
	-foreground {
	    set key [lindex $data(keyList) $row]
	    set name $key$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag row$opt-$val in the body text widget
		#
		set tag row$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag active

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-elide {
	    set val [expr {$val ? 1 : 0}]
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key$opt
	    set line [expr {$row + 1}]
	    set viewChanged 0

	    if {$val} {					;# eliding the row
		if {![info exists data($name)]} {
		    set data($name) 1
		    $w tag add elidedRow $line.0 $line.end+1c

		    if {![info exists data($key-hide)]} {
			incr data(nonViewableRowCount)
			set viewChanged 1

			if {$row == $data(editRow)} {
			    doCancelEditing $win
			}
		    }
		}
	    } else {					;# uneliding the row
		if {[info exists data($name)]} {
		    unset data($name)
		    $w tag remove elidedRow $line.0 $line.end+1c

		    if {![info exists data($key-hide)]} {
			incr data(nonViewableRowCount) -1
			set viewChanged 1
		    }
		}
	    }

	    if {$viewChanged} {
		#
		# Adjust the heights of the body text widget
		# and of the listbox child, if necessary
		#
		if {$data(-height) <= 0} {
		    set viewableRowCount \
			[expr {$data(itemCount) - $data(nonViewableRowCount)}]
		    $w configure -height $viewableRowCount
		    $data(lb) configure -height $viewableRowCount
		}

		#
		# Build the list of those dynamic-width columns
		# whose widths are affected by (un)eliding the row
		#
		set colWidthsChanged 0
		set colIdxList {}
		set displayedItem [lrange $item 0 $data(lastCol)]
		if {$data(hasFmtCmds)} {
		    set displayedItem [formatItem $win $key $row $displayedItem]
		}
		if {[string match "*\t*" $displayedItem]} {
		    set displayedItem [mapTabs $displayedItem]
		}
		set col 0
		foreach text $displayedItem {pixels alignment} $data(colList) {
		    if {($data($col-hide) && !$canElide) || $pixels != 0} {
			incr col
			continue
		    }

		    getAuxData $win $key $col auxType auxWidth
		    getIndentData $win $key $col indentWidth
		    set cellFont [getCellFont $win $key $col]
		    set elemWidth [getElemWidth $win $text $auxWidth \
				   $indentWidth $cellFont]
		    if {$val} {				;# eliding the row
			if {$elemWidth == $data($col-elemWidth) &&
			    [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    } else {				;# uneliding the row
			if {$elemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$elemWidth > $data($col-elemWidth)} {
			    set data($col-elemWidth) $elemWidth
			    set data($col-widestCount) 1
			    if {$elemWidth > $data($col-reqPixels)} {
				set data($col-reqPixels) $elemWidth
				set colWidthsChanged 1
			    }
			}
		    }

		    incr col
		}

		#
		# Invalidate the list of row indices indicating the
		# viewable rows and adjust the columns if necessary
		#
		set data(viewableRowList) {-1}
		if {$colWidthsChanged} {
		    adjustColumns $win $colIdxList 1
		}
	    }
	}

	-font {
	    #
	    # Save the current cell fonts in a temporary array
	    #
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set oldCellFonts($col) [getCellFont $win $key $col]
	    }

	    set name $key$opt
	    if {[info exists data($name)]} {
		#
		# Remove the tag row$opt-$data($name) from the given row
		#
		set line [expr {$row + 1}]
		$w tag remove row$opt-$data($name) $line.0 $line.end
	    }

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    incr data(rowTagRefCount) -1
		}
	    } else {
		#
		# Configure the tag row$opt-$val in the body
		# text widget and apply it to the given row
		#
		set tag row$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag active
		set line [expr {$row + 1}]
		$w tag add $tag $line.0 $line.end

		#
		# Save val in data($name)
		#
		if {![info exists data($name)]} {
		    incr data(rowTagRefCount)
		}
		set data($name) $val
	    }

	    set displayedItem [lrange $item 0 $data(lastCol)]
	    if {$data(hasFmtCmds)} {
		set displayedItem [formatItem $win $key $row $displayedItem]
	    }
	    if {[string match "*\t*" $displayedItem]} {
		set displayedItem [mapTabs $displayedItem]
	    }
	    set colWidthsChanged 0
	    set colIdxList {}
	    set line [expr {$row + 1}]
	    set textIdx1 $line.1
	    set col 0
	    foreach text $displayedItem {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Adjust the cell text and the image or window width
		#
		set multiline [string match "*\n*" $text]
		set cellFont [getCellFont $win $key $col]
		set workPixels $pixels
		if {$pixels == 0} {		;# convention: dynamic width
		    set textSav $text
		    getAuxData $win $key $col auxType auxWidthSav
		    getIndentData $win $key $col indentWidthSav

		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set workPixels $data($col-maxPixels)
			}
		    }
		}
		set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
		set indent [getIndentData $win $key $col indentWidth]
		set maxTextWidth $workPixels
		if {$workPixels != 0} {
		    incr workPixels $data($col-delta)
		    set maxTextWidth \
			[getMaxTextWidth $workPixels $auxWidth $indentWidth]

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $maxTextWidth} {
			    set multiline 1
			}
		    }
		}
		set snipSide $snipSides($alignment,$data($col-changesnipside))
		if {$multiline} {
		    set list [split $text "\n"]
		    if {$data($col-wrap)} {
			set snipSide ""
		    }
		    adjustMlElem $win list auxWidth indentWidth $cellFont \
				 $workPixels $snipSide $data(-snipstring)
		    set msgScript [list ::tablelist::displayText $win $key \
				   $col [join $list "\n"] $cellFont \
				   $maxTextWidth $alignment]
		} else {
		    adjustElem $win text auxWidth indentWidth $cellFont \
			       $workPixels $snipSide $data(-snipstring)
		}

		if {$row == $data(editRow) && $col == $data(editCol)} {
		    #
		    # Configure the edit window
		    #
		    setEditWinFont $win
		} else {
		    #
		    # Update the text widget's contents between the two tabs
		    #
		    set textIdx2 [$w search $elide "\t" $textIdx1 $line.end]
		    if {$multiline} {
			updateMlCell $w $textIdx1 $textIdx2 $msgScript $aux \
				     $auxType $auxWidth $indent $indentWidth \
				     $alignment [getVAlignment $win $key $col]
		    } else {
			updateCell $w $textIdx1 $textIdx2 $text $aux \
				   $auxType $auxWidth $indent $indentWidth \
				   $alignment [getVAlignment $win $key $col]
		    }
		}

		if {$pixels == 0 && ![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    #
		    # Check whether the width of the current column has changed
		    #
		    set text $textSav
		    set auxWidth $auxWidthSav
		    set indentWidth $indentWidthSav
		    set newElemWidth [getElemWidth $win $text $auxWidth \
				      $indentWidth $cellFont]
		    if {$newElemWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $newElemWidth
			set data($col-widestCount) 1
			if {$newElemWidth > $data($col-reqPixels)} {
			    set data($col-reqPixels) $newElemWidth
			    set colWidthsChanged 1
			}
		    } else {
			set oldElemWidth [getElemWidth $win $text $auxWidth \
					  $indentWidth $oldCellFonts($col)]
			if {$oldElemWidth < $data($col-elemWidth) &&
			    $newElemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$oldElemWidth == $data($col-elemWidth) &&
				  $newElemWidth < $oldElemWidth &&
				  [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    }
		}

		set textIdx1 [$w search $elide "\t" $textIdx1 $line.end]+2c
		incr col
	    }

	    #
	    # Adjust the columns if necessary and schedule
	    # some operations for execution at idle time
	    #
	    if {$colWidthsChanged} {
		adjustColumns $win $colIdxList 1
	    }
	    updateViewWhenIdle $win
	}

	-hide {
	    set val [expr {$val ? 1 : 0}]
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key$opt
	    set line [expr {$row + 1}]
	    set viewChanged 0
	    set callerProc [lindex [info level -1] 0]

	    if {$val} {					;# hiding the row
		if {![info exists data($name)]} {
		    set data($name) 1
		    $w tag add hiddenRow $line.0 $line.end+1c

		    if {![info exists data($key-elide)]} {
			incr data(nonViewableRowCount)
			set viewChanged 1

			#
			# Elide the descendants of this item
			#
			set fromRow [expr {$row + 1}]
			set toRow [nodeRow $win $key end]
			for {set _row $fromRow} {$_row < $toRow} {incr _row} {
			    doRowConfig $_row $win -elide 1
			}

			if {[string match "*configureWidget" $callerProc]} {
			    adjustRowIndex $win data(anchorRow) 1

			    set activeRow $data(activeRow)
			    adjustRowIndex $win activeRow 1
			    set data(activeRow) $activeRow
			}

			if {$row == $data(editRow)} {
			    doCancelEditing $win
			}
		    }
		}
	    } else {					;# unhiding the row
		if {[info exists data($name)]} {
		    unset data($name)
		    $w tag remove hiddenRow $line.0 $line.end+1c

		    if {![info exists data($key-elide)]} {
			incr data(nonViewableRowCount) -1
			set viewChanged 1

			if {[info exists data($key,$data(treeCol)-indent)] &&
			    [string match "*expanded*" \
			     $data($key,$data(treeCol)-indent)]} {
			    expandSubCmd $win [list $row -partly]
			}
		    }
		}
	    }

	    if {$viewChanged} {
		#
		# Adjust the heights of the body text widget
		# and of the listbox child, if necessary
		#
		if {$data(-height) <= 0} {
		    set viewableRowCount \
			[expr {$data(itemCount) - $data(nonViewableRowCount)}]
		    $w configure -height $viewableRowCount
		    $data(lb) configure -height $viewableRowCount
		}

		#
		# Build the list of those dynamic-width columns
		# whose widths are affected by (un)hiding the row
		#
		set colWidthsChanged 0
		set colIdxList {}
		set displayedItem [lrange $item 0 $data(lastCol)]
		if {$data(hasFmtCmds)} {
		    set displayedItem [formatItem $win $key $row $displayedItem]
		}
		if {[string match "*\t*" $displayedItem]} {
		    set displayedItem [mapTabs $displayedItem]
		}
		set col 0
		foreach text $displayedItem {pixels alignment} $data(colList) {
		    if {($data($col-hide) && !$canElide) || $pixels != 0} {
			incr col
			continue
		    }

		    getAuxData $win $key $col auxType auxWidth
		    getIndentData $win $key $col indentWidth
		    set cellFont [getCellFont $win $key $col]
		    set elemWidth [getElemWidth $win $text $auxWidth \
				   $indentWidth $cellFont]
		    if {$val} {				;# hiding the row
			if {$elemWidth == $data($col-elemWidth) &&
			    [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    } else {				;# unhiding the row
			if {$elemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$elemWidth > $data($col-elemWidth)} {
			    set data($col-elemWidth) $elemWidth
			    set data($col-widestCount) 1
			    if {$elemWidth > $data($col-reqPixels)} {
				set data($col-reqPixels) $elemWidth
				set colWidthsChanged 1
			    }
			}
		    }

		    incr col
		}

		#
		# Invalidate the list of row indices indicating the
		# viewable rows and adjust the columns if necessary
		#
		set data(viewableRowList) {-1}
		if {$colWidthsChanged} {
		    adjustColumns $win $colIdxList 1
		}

		#
		# Schedule some operations for execution at idle time
		# and generate a virtual event only if the caller proc
		# is configureWidget, in order to make sure that only
		# one event per caller proc invocation will be generated
		#
		if {[string match "*configureWidget" $callerProc]} {
		    makeStripesWhenIdle $win
		    showLineNumbersWhenIdle $win
		    updateViewWhenIdle $win

		    genVirtualEvent $win <<TablelistRowHiddenStateChanged>> $row
		}
	    }
	}

	-name {
	    set key [lindex $data(keyList) $row]
	    if {[string length $val] == 0} {
		if {[info exists data($key$opt)]} {
		    unset data($key$opt)
		}
	    } else {
		set data($key$opt) $val
	    }
	}

	-selectable {
	    set val [expr {$val ? 1 : 0}]
	    set key [lindex $data(keyList) $row]

	    if {$val} {
		if {[info exists data($key$opt)]} {
		    unset data($key$opt)
		}
	    } else {
		#
		# Set data($key$opt) to 0 and deselect the row
		#
		set data($key$opt) 0
		rowSelection $win clear $row $row
	    }
	}

	-selectbackground -
	-selectforeground {
	    set key [lindex $data(keyList) $row]
	    set name $key$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag row$opt-$val in the body text widget
		#
		set tag row$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -select
		$w tag configure $tag -$optTail $val
		$w tag lower $tag active

		#
		# Save val in data($name)
		#
		set data($name) [$w tag cget $tag -$optTail]
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-text {
	    if {$data(isDisabled)} {
		return ""
	    }

	    set colWidthsChanged 0
	    set colIdxList {}
	    set oldItem [lindex $data(itemList) $row]
	    set key [lindex $oldItem end]
	    set newItem [adjustItem $val $data(colCount)]
	    if {$data(hasFmtCmds)} {
		set displayedItem [formatItem $win $key $row $newItem]
	    } else {
		set displayedItem $newItem
	    }
	    if {[string match "*\t*" $displayedItem]} {
		set displayedItem [mapTabs $displayedItem]
	    }
	    set line [expr {$row + 1}]
	    set textIdx1 $line.1
	    set col 0
	    foreach text $displayedItem {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Adjust the cell text and the image or window width
		#
		set multiline [string match "*\n*" $text]
		set cellFont [getCellFont $win $key $col]
		set workPixels $pixels
		if {$pixels == 0} {		;# convention: dynamic width
		    set textSav $text
		    getAuxData $win $key $col auxType auxWidthSav
		    getIndentData $win $key $col indentWidthSav

		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set workPixels $data($col-maxPixels)
			}
		    }
		}
		set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
		set indent [getIndentData $win $key $col indentWidth]
		set maxTextWidth $workPixels
		if {$workPixels != 0} {
		    incr workPixels $data($col-delta)
		    set maxTextWidth \
			[getMaxTextWidth $workPixels $auxWidth $indentWidth]

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $maxTextWidth} {
			    set multiline 1
			}
		    }
		}
		set snipSide $snipSides($alignment,$data($col-changesnipside))
		if {$multiline} {
		    set list [split $text "\n"]
		    if {$data($col-wrap)} {
			set snipSide ""
		    }
		    adjustMlElem $win list auxWidth indentWidth $cellFont \
				 $workPixels $snipSide $data(-snipstring)
		    set msgScript [list ::tablelist::displayText $win $key \
				   $col [join $list "\n"] $cellFont \
				   $maxTextWidth $alignment]
		} else {
		    adjustElem $win text auxWidth indentWidth $cellFont \
			       $workPixels $snipSide $data(-snipstring)
		}

		if {$row != $data(editRow) || $col != $data(editCol)} {
		    #
		    # Update the text widget's contents between the two tabs
		    #
		    set textIdx2 [$w search $elide "\t" $textIdx1 $line.end]
		    if {$multiline} {
			updateMlCell $w $textIdx1 $textIdx2 $msgScript $aux \
				     $auxType $auxWidth $indent $indentWidth \
				     $alignment [getVAlignment $win $key $col]
		    } else {
			updateCell $w $textIdx1 $textIdx2 $text $aux \
				   $auxType $auxWidth $indent $indentWidth \
				   $alignment [getVAlignment $win $key $col]
		    }
		}

		if {$pixels == 0 && ![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    #
		    # Check whether the width of the current column has changed
		    #
		    set text $textSav
		    set auxWidth $auxWidthSav
		    set indentWidth $indentWidthSav
		    set newElemWidth [getElemWidth $win $text $auxWidth \
				      $indentWidth $cellFont]
		    if {$newElemWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $newElemWidth
			set data($col-widestCount) 1
			if {$newElemWidth > $data($col-reqPixels)} {
			    set data($col-reqPixels) $newElemWidth
			    set colWidthsChanged 1
			}
		    } else {
			set oldText [lindex $oldItem $col]
			if {[lindex $data(fmtCmdFlagList) $col]} {
			    set oldText \
				[formatElem $win $key $row $col $oldText]
			}
			if {[string match "*\t*" $oldText]} {
			    set oldText [mapTabs $oldText]
			}
			set oldElemWidth [getElemWidth $win $oldText $auxWidth \
					  $indentWidth $cellFont]
			if {$oldElemWidth < $data($col-elemWidth) &&
			    $newElemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$oldElemWidth == $data($col-elemWidth) &&
				  $newElemWidth < $oldElemWidth &&
				  [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    }
		}

		set textIdx1 [$w search $elide "\t" $textIdx1 $line.end]+2c
		incr col
	    }

	    #
	    # Replace the row contents in the list variable if present
	    #
	    if {$data(hasListVar)} {
		upvar #0 $data(-listvariable) var
		trace vdelete var wu $data(listVarTraceCmd)
		set var [lreplace $var $row $row $newItem]
		trace variable var wu $data(listVarTraceCmd)
	    }

	    #
	    # Replace the row contents in the internal list
	    #
	    lappend newItem $key
	    set data(itemList) [lreplace $data(itemList) $row $row $newItem]

	    #
	    # Adjust the columns if necessary and schedule
	    # some operations for execution at idle time
	    #
	    if {$colWidthsChanged} {
		adjustColumns $win $colIdxList 1
	    }
	    showLineNumbersWhenIdle $win
	    updateViewWhenIdle $win
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doRowCget
#
# Returns the value of the row configuration option opt for the row'th row of
# the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doRowCget {row win opt} {
    upvar ::tablelist::ns${win}::data data
    set item [lindex $data(itemList) $row]

    switch -- $opt {
	-text {
	    return [lrange $item 0 $data(lastCol)]
	}

	-elide -
	-hide {
	    set key [lindex $item end]
	    if {[info exists data($key$opt)]} {
		return $data($key$opt)
	    } else {
		return 0
	    }
	}

	-selectable {
	    set key [lindex $item end]
	    if {[info exists data($key$opt)]} {
		return $data($key$opt)
	    } else {
		return 1
	    }
	}

	default {
	    set key [lindex $item end]
	    if {[info exists data($key$opt)]} {
		return $data($key$opt)
	    } else {
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doCellConfig
#
# Applies the value val of the cell configuration option opt to the cell
# row,col of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doCellConfig {row col win opt val} {
    variable canElide
    variable snipSides
    upvar ::tablelist::ns${win}::data data

    set w $data(body)

    switch -- $opt {
	-background -
	-foreground {
	    set key [lindex $data(keyList) $row]
	    set name $key,$col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag cell$opt-$val in the body text widget
		#
		set tag cell$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag disabled

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-editable {
	    #
	    # Save the boolean value specified by val in data($key,$col$opt)
	    # and invoke the motion handler if necessary
	    #
	    set key [lindex $data(keyList) $row]
	    set data($key,$col$opt) [expr {$val ? 1 : 0}]
	    if {$data(-showeditcursor)} {
		invokeMotionHandler $win
	    }
	}

	-editwindow {
	    variable editWin
	    if {[info exists editWin($val-creationCmd)]} {
		set key [lindex $data(keyList) $row]
		set data($key,$col$opt) $val
	    } else {
		return -code error "name \"$val\" is not registered\
				    for interactive cell editing"
	    }
	}

	-font {
	    #
	    # Save the current cell font
	    #
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    set oldCellFont [getCellFont $win $key $col]

	    if {[info exists data($name)] &&
		(!$data($col-hide) || $canElide)} {
		#
		# Remove the tag cell$opt-$data($name) from the given cell
		#
		findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		$w tag remove cell$opt-$data($name) $tabIdx1 $tabIdx2+1c
	    }

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    incr data(cellTagRefCount) -1
		}
	    } else {
		#
		# Configure the tag cell$opt-$val in the body text widget
		#
		set tag cell$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag disabled

		if {!$data($col-hide) || $canElide} {
		    #
		    # Apply the tag to the given cell
		    #
		    findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		    $w tag add $tag $tabIdx1 $tabIdx2+1c
		}

		#
		# Save val in data($name)
		#
		if {![info exists data($name)]} {
		    incr data(cellTagRefCount)
		}
		set data($name) $val
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {!$data($col-hide)} {
		if {$row == $data(editRow) && $col == $data(editCol)} {
		    #
		    # Configure the edit window
		    #
		    setEditWinFont $win
		} else {
		    #
		    # Update the text widget's contents between the two tabs
		    #
		    findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		    if {$multiline} {
			updateMlCell $w $tabIdx1+1c $tabIdx2 $msgScript $aux \
				     $auxType $auxWidth $indent $indentWidth \
				     $alignment [getVAlignment $win $key $col]
		    } else {
			updateCell $w $tabIdx1+1c $tabIdx2 $text $aux \
				   $auxType $auxWidth $indent $indentWidth \
				   $alignment [getVAlignment $win $key $col]
		    }
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $text $auxWidth \
				      $indentWidth $oldCellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-image {
	    if {$data(isDisabled)} {
		return ""
	    }

	    #
	    # Save the old image or window width
	    #
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    getAuxData $win $key $col oldAuxType oldAuxWidth

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    set imgLabel $w.img_$key,$col
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    incr data(imgCount) -1
		    destroy $imgLabel
		}
	    } else {
		if {![info exists data($name)]} {
		    incr data(imgCount)
		}
		if {[winfo exists $imgLabel] &&
		    [string compare $val $data($name)] != 0} {
		    destroy $imgLabel
		}
		set data($name) $val
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set oldText $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) &&
		!($row == $data(editRow) && $col == $data(editCol))} {
		#
		# Delete the old cell contents between the two tabs,
		# and insert the text and the auxiliary object
		#
		findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1c $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1c $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $oldText $oldAuxWidth \
				      $indentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-indent {
	    if {$data(isDisabled)} {
		return ""
	    }

	    #
	    # Save the old indentation width
	    #
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    getIndentData $win $key $col oldIndentWidth

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    set indentLabel $w.ind_$key,$col
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    incr data(indentCount) -1
		    destroy $indentLabel
		}
	    } else {
		if {![info exists data($name)]} {
		    incr data(indentCount)
		}
		if {[winfo exists $indentLabel] &&
		    [string compare $val $data($name)] != 0} {
		    destroy $indentLabel
		}
		set data($name) $val
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set oldText $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) &&
		!($row == $data(editRow) && $col == $data(editCol))} {
		#
		# Delete the old cell contents between the two tabs,
		# and insert the text and the auxiliary object
		#
		findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1c $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1c $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $oldText $auxWidth \
				      $oldIndentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-selectbackground -
	-selectforeground {
	    set key [lindex $data(keyList) $row]
	    set name $key,$col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag cell$opt-$val in the body text widget
		#
		set tag cell$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -select
		$w tag configure $tag -$optTail $val
		$w tag lower $tag disabled

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-stretchwindow {
	    #
	    # Save the boolean value specified by val in data($key,$col$opt)
	    #
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    if {$val} {
		set data($name) 1
	    } elseif {[info exists data($name)]} {
		unset data($name)
	    }

	    if {($data($col-hide) && !$canElide) ||
		($row == $data(editRow) && $col == $data(editCol))} {
		return ""
	    }

	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $pixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $pixels
	    if {$pixels != 0} {
		incr pixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $pixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    if {$auxType < 2} {			;# no window
		return ""
	    }

	    #
	    # Adjust the cell text and the window width
	    #
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $pixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key $row \
			       [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $pixels $snipSide $data(-snipstring)
	    }

	    #
	    # Update the text widget's contents between the two tabs
	    #
	    findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
	    if {$multiline} {
		updateMlCell $w $tabIdx1+1c $tabIdx2 $msgScript $aux \
			     $auxType $auxWidth $indent $indentWidth \
			     $alignment [getVAlignment $win $key $col]
	    } else {
		updateCell $w $tabIdx1+1c $tabIdx2 $text $aux \
			   $auxType $auxWidth $indent $indentWidth \
			   $alignment [getVAlignment $win $key $col]
	    }
	}

	-text {
	    if {$data(isDisabled)} {
		return ""
	    }

	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text $val
	    set oldItem [lindex $data(itemList) $row]
	    set key [lindex $oldItem end]
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    if {$fmtCmdFlag} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set textSav $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) &&
		!($row == $data(editRow) && $col == $data(editCol))} {
		#
		# Update the text widget's contents between the two tabs
		#
		findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1c $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1c $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Replace the cell contents in the internal list
	    #
	    set newItem [lreplace $oldItem $col $col $val]
	    set data(itemList) [lreplace $data(itemList) $row $row $newItem]

	    #
	    # Replace the cell contents in the list variable if present
	    #
	    if {$data(hasListVar)} {
		upvar #0 $data(-listvariable) var
		trace vdelete var wu $data(listVarTraceCmd)
		set var [lreplace $var $row $row \
			 [lrange $newItem 0 $data(lastCol)]]
		trace variable var wu $data(listVarTraceCmd)
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldText [lindex $oldItem $col]
		    if {$fmtCmdFlag} {
			set oldText [formatElem $win $key $row $col $oldText]
		    }
		    if {[string match "*\t*" $oldText]} {
			set oldText [mapTabs $oldText]
		    }
		    set oldElemWidth [getElemWidth $win $oldText $auxWidth \
				      $indentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    showLineNumbersWhenIdle $win
	    updateViewWhenIdle $win
	}

	-valign {
	    #
	    # Save the properly formatted value of val in
	    # data($key,$col$opt) and redisplay the cell
	    #
	    variable valignments
	    set val [mwutil::fullOpt "vertical alignment" $val $valignments]
	    set key [lindex $data(keyList) $row]
	    set data($key,$col$opt) $val
	    redisplayCol $win $col $row $row
	}

	-window {
	    if {$data(isDisabled)} {
		return ""
	    }

	    #
	    # Save the old image or window width
	    #
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    getAuxData $win $key $col oldAuxType oldAuxWidth
	    getIndentData $win $key $col oldIndentWidth

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    set aux $w.frm_$key,$col
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    unset data($key,$col-reqWidth)
		    unset data($key,$col-reqHeight)

		    #
		    # If the cell index is contained in the list
		    # data(cellsToReconfig) then remove it from the list
		    #
		    set n [lsearch -exact $data(cellsToReconfig) $row,$col]
		    if {$n >= 0} {
			set data(cellsToReconfig) \
			    [lreplace $data(cellsToReconfig) $n $n]
		    }
		    incr data(winCount) -1
		    destroy $aux
		}
	    } else {
		if {![info exists data($name)]} {
		    incr data(winCount)
		}
		if {[info exists data($name)] &&
		    [string compare $val $data($name)] != 0} {
		    destroy $aux
		}
		if {![winfo exists $aux]} {
		    #
		    # Create the frame and evaluate the specified script
		    # that creates a child widget within the frame
		    #
		    tk::frame $aux -borderwidth 0 -class TablelistWindow \
				   -container 0 -highlightthickness 0 \
				   -relief flat -takefocus 0
		    catch {$aux configure -padx 0 -pady 0}
		    bindtags $aux [linsert [bindtags $aux] 1 \
				   $data(bodyTag) TablelistBody]
		    uplevel #0 $val [list $win $row $col $aux.w]
		}
		set data($name) $val
		set data($key,$col-reqWidth) [winfo reqwidth $aux.w]
		set data($key,$col-reqHeight) [winfo reqheight $aux.w]
		$aux configure -height $data($key,$col-reqHeight)

		#
		# Add the cell index to the list data(cellsToReconfig) if
		# the window's requested width or height is not yet known
		#
		if {($data($key,$col-reqWidth) == 1 ||
		     $data($key,$col-reqHeight) == 1) &&
		    [lsearch -exact $data(cellsToReconfig) $row,$col] < 0} {
		    lappend data(cellsToReconfig) $row,$col
		    if {![info exists data(reconfigId)]} {
			set data(reconfigId) \
			    [after idle [list tablelist::reconfigWindows $win]]
		    }
		}
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set oldText $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) &&
		!($row == $data(editRow) && $col == $data(editCol))} {
		#
		# Delete the old cell contents between the two tabs,
		# and insert the text and the auxiliary object
		#
		findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1c $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1c $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $oldText $oldAuxWidth \
				      $oldIndentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-windowdestroy -
	-windowupdate {
	    set key [lindex $data(keyList) $row]
	    set name $key,$col$opt

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		set data($name) $val
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doCellCget
#
# Returns the value of the cell configuration option opt for the cell row,col
# of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doCellCget {row col win opt} {
    switch -- $opt {
	-editable {
	    return [isCellEditable $win $row $col]
	}

	-editwindow {
	    return [getEditWindow $win $row $col 0]
	}

	-stretchwindow {
	    upvar ::tablelist::ns${win}::data data
	    set key [lindex $data(keyList) $row]
	    if {[info exists data($key,$col$opt)]} {
		return $data($key,$col$opt)
	    } else {
		return 0
	    }
	}

	-text {
	    upvar ::tablelist::ns${win}::data data
	    return [lindex [lindex $data(itemList) $row] $col]
	}

	-valign {
	    upvar ::tablelist::ns${win}::data data
	    set key [lindex $data(keyList) $row]
	    return [getVAlignment $win $key $col]
	}

	default {
	    upvar ::tablelist::ns${win}::data data
	    set key [lindex $data(keyList) $row]
	    if {[info exists data($key,$col$opt)]} {
		return $data($key,$col$opt)
	    } else {
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::makeListVar
#
# Arranges for the global variable specified by varName to become the list
# variable associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeListVar {win varName} {
    upvar ::tablelist::ns${win}::data data
    if {[string length $varName] == 0} {
	#
	# If there is an old list variable associated with the
	# widget then remove the trace set on this variable
	#
	if {$data(hasListVar)} {
	    synchronize $win
	    upvar #0 $data(-listvariable) var
	    trace vdelete var wu $data(listVarTraceCmd)
	}
	return ""
    }

    #
    # The list variable may be an array element but must not be an array
    #
    if {![regexp {^(.*)\((.*)\)$} $varName dummy name1 name2]} {
	if {[array exists $varName]} {
	    return -code error "variable \"$varName\" is array"
	}
	set name1 $varName
	set name2 ""
    }

    #
    # If there is an old list variable associated with the
    # widget then remove the trace set on this variable
    #
    if {$data(hasListVar)} {
	synchronize $win
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
    }

    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)]
	}
    }

    #
    # Set a trace on the new list variable
    #
    trace variable var wu $data(listVarTraceCmd)
}

#------------------------------------------------------------------------------
# tablelist::isRowViewable
#
# Checks whether the given row of the tablelist widget win is viewable.
#------------------------------------------------------------------------------
proc tablelist::isRowViewable {win row} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [expr {![info exists data($key-elide)] &&
		  ![info exists data($key-hide)]}]
}

#------------------------------------------------------------------------------
# tablelist::getCellFont
#
# Returns the font to be used in the tablelist cell specified by win, key, and
# col.
#------------------------------------------------------------------------------
proc tablelist::getCellFont {win key col} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data($key,$col-font)]} {
	return $data($key,$col-font)
    } elseif {[info exists data($key-font)]} {
	return $data($key-font)
    } else {
	return [lindex $data(colFontList) $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::reconfigWindows
#
# Invoked as an after idle callback, this procedure forces any geometry manager
# calculations to be completed and then applies the -window option a second
# time to those cells whose embedded windows' requested widths or heights were
# still unknown.
#------------------------------------------------------------------------------
proc tablelist::reconfigWindows win {
    #
    # Force any geometry manager calculations to be completed first
    #
    update idletasks
    if {![array exists ::tablelist::ns${win}::data]} {
	return ""
    }

    #
    # Reconfigure the cells specified in the list data(cellsToReconfig)
    #
    upvar ::tablelist::ns${win}::data data
    foreach cellIdx $data(cellsToReconfig) {
	foreach {row col} [split $cellIdx ","] {}
	set key [lindex $data(keyList) $row]
	if {[info exists data($key,$col-window)]} {
	    doCellConfig $row $col $win -window $data($key,$col-window)
	}
    }

    unset data(reconfigId)
    set data(cellsToReconfig) {}
}

#------------------------------------------------------------------------------
# tablelist::isCellEditable
#
# Checks whether the given cell of the tablelist widget win is editable.
#------------------------------------------------------------------------------
proc tablelist::isCellEditable {win row col} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    if {[info exists data($key,$col-editable)]} {
	return $data($key,$col-editable)
    } else {
	return $data($col-editable)
    }
}

#------------------------------------------------------------------------------
# tablelist::getEditWindow
#
# Returns the value of the -editwindow option at cell or column level for the
# given cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getEditWindow {win row col {skipLeadingColons 1}} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    if {[info exists data($key,$col-editwindow)]} {
	set name $data($key,$col-editwindow)
    } elseif {[info exists data($col-editwindow)]} {
	set name $data($col-editwindow)
    } else {
	return "entry"
    }

    if {[regexp {^::ttk::(entry|spinbox|combobox|checkbutton|menubutton)$} \
	 $name] && $skipLeadingColons} {
	set name [string range $name 2 end]
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::getVAlignment
#
# Returns the value of the -valign option at cell or column level for the given
# cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getVAlignment {win key col} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data($key,$col-valign)]} {
	return $data($key,$col-valign)
    } else {
	return $data($col-valign)
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistEdit.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
#==============================================================================
# Contains the implementation of interactive cell editing in tablelist widgets.
#
# Structure of the module:
#   - Namespace initialization
#   - Public procedures related to interactive cell editing
#   - Private procedures implementing the interactive cell editing
#   - Private procedures used in bindings related to interactive cell editing
#
# Copyright (c) 2003-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Namespace initialization
# ========================
#

namespace eval tablelist {
    #
    # Register the Tk core widgets entry, text, checkbutton,
    # menubutton, and spinbox for interactive cell editing
    #
    proc addTkCoreWidgets {} {
	variable editWin

	set name entry
	array set editWin [list \
	    $name-creationCmd	"$name %W -width 0" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	0 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right} \
	]

	set name text
	array set editWin [list \
	    $name-creationCmd	"$name %W -padx 2 -pady 2 -wrap none" \
	    $name-putValueCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	    $name-getValueCmd	"%W get 1.0 end-1c" \
	    $name-putTextCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	    $name-getTextCmd	"%W get 1.0 end-1c" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	0 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down Prior Next
				 Control-Home Control-End Meta-b Meta-f
				 Control-p Control-n Meta-less Meta-greater} \
	]

	set name checkbutton
	array set editWin [list \
	    $name-creationCmd	"createCheckbutton %W" \
	    $name-putValueCmd	{set [%W cget -variable] %T} \
	    $name-getValueCmd	{set [%W cget -variable]} \
	    $name-putTextCmd	{set [%W cget -variable] %T} \
	    $name-getTextCmd	{set [%W cget -variable]} \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"%W invoke" \
	    $name-fontOpt	"" \
	    $name-useFormat	0 \
	    $name-useReqWidth	1 \
	    $name-usePadX	0 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	set name menubutton
	array set editWin [list \
	    $name-creationCmd	"createMenubutton %W" \
	    $name-putValueCmd	{set [%W cget -textvariable] %T} \
	    $name-getValueCmd	"%W cget -text" \
	    $name-putTextCmd	{set [%W cget -textvariable] %T} \
	    $name-getTextCmd	"%W cget -text" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"event generate %W <Button-1>" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	if {$::tk_version < 8.4} {
	    return ""
	}

	set name spinbox
	array set editWin [list \
	    $name-creationCmd	"$name %W -width 0" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down} \
	]
    }
    addTkCoreWidgets 

    #
    # Register the tile widgets ttk::entry, ttk::spinbox, ttk::combobox,
    # ttk::checkbutton, and ttk::menubutton for interactive cell editing
    #
    proc addTileWidgets {} {
	variable editWin

	set name ttk::entry
	array set editWin [list \
	    $name-creationCmd	"createTileEntry %W" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	0 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right} \
	]

	set name ttk::spinbox
	array set editWin [list \
	    $name-creationCmd	"createTileSpinbox %W" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down} \
	]

	set name ttk::combobox
	array set editWin [list \
	    $name-creationCmd	"createTileCombobox %W" \
	    $name-putValueCmd	"%W set %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W set %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"event generate %W <Button-1>" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down} \
	]

	set name ttk::checkbutton
	array set editWin [list \
	    $name-creationCmd	"createTileCheckbutton %W" \
	    $name-putValueCmd	{set [%W cget -variable] %T} \
	    $name-getValueCmd	{set [%W cget -variable]} \
	    $name-putTextCmd	{set [%W cget -variable] %T} \
	    $name-getTextCmd	{set [%W cget -variable]} \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	{%W instate !pressed {%W invoke}} \
	    $name-fontOpt	"" \
	    $name-useFormat	0 \
	    $name-useReqWidth	1 \
	    $name-usePadX	0 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	set name ttk::menubutton
	array set editWin [list \
	    $name-creationCmd	"createTileMenubutton %W" \
	    $name-putValueCmd	{set [%W cget -textvariable] %T} \
	    $name-getValueCmd	"%W cget -text" \
	    $name-putTextCmd	{set [%W cget -textvariable] %T} \
	    $name-getTextCmd	"%W cget -text" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"event generate %W <Button-1>" \
	    $name-fontOpt	"" \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	foreach {name value} [array get editWin ttk::*-creationCmd] {
	    set editWin(::$name) $value
	}
    }
    if {$::tk_version >= 8.4 && [llength [package versions tile]] > 0} {
	addTileWidgets 
    }
}

#
# Public procedures related to interactive cell editing
# =====================================================
#

#------------------------------------------------------------------------------
# tablelist::addBWidgetEntry
#
# Registers the Entry widget from the BWidget package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addBWidgetEntry {{name Entry}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"Entry %W -width 0" \
	$name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		0 \
	$name-isEntryLike	1 \
	$name-focusWin		%W \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addBWidgetSpinBox
#
# Registers the SpinBox widget from the BWidget package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addBWidgetSpinBox {{name SpinBox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"SpinBox %W -editable 1 -width 0" \
	$name-putValueCmd	"%W configure -text %T" \
	$name-getValueCmd	"%W cget -text" \
	$name-putTextCmd	"%W configure -text %T" \
	$name-getTextCmd	"%W cget -text" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.e \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addBWidgetComboBox
#
# Registers the ComboBox widget from the BWidget package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addBWidgetComboBox {{name ComboBox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"createBWidgetComboBox %W" \
	$name-putValueCmd	"%W configure -text %T" \
	$name-getValueCmd	"%W cget -text" \
	$name-putTextCmd	"%W configure -text %T" \
	$name-getTextCmd	"%W cget -text" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"%W.a invoke" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.e \
	$name-reservedKeys	{Left Right Up Down} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrEntryfield
#
# Registers the entryfield widget from the Iwidgets package for interactive
# cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrEntryfield {{name entryfield}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::entryfield %W -width 0" \
	$name-putValueCmd	"%W clear; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		0 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrDateTimeWidget
#
# Registers the datefield, dateentry, timefield, or timeentry widget from the
# Iwidgets package, with or without the -clicks option for its get subcommand,
# for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrDateTimeWidget {widgetType args} {
    if {![regexp {^(datefield|dateentry|timefield|timeentry)$} $widgetType]} {
	return -code error \
	       "bad widget type \"$widgetType\": must be\
		datefield, dateentry, timefield, or timeentry"
    }

    switch [llength $args] {
	0 {
	    set useClicks 0
	    set name $widgetType
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-seconds"] == 0} {
		set useClicks 1
		set name $widgetType
	    } else {
		set useClicks 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-seconds"] != 0} {
		return -code error "bad option \"$arg0\": must be -seconds"
	    }

	    set useClicks 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addIncrDateTimeWidget\
		    datefield|dateentry|timefield|timeentry ?-seconds? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::$widgetType %W" \
	$name-putValueCmd	"%W show %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W show %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useReqWidth	1 \
	$name-usePadX		[string match "*entry" $widgetType] \
	$name-useFormat		1 \
	$name-isEntryLike	1 \
	$name-reservedKeys	{Left Right Up Down} \
    ]
    if {$useClicks} {
	lappend editWin($name-getValueCmd) -clicks
	set editWin($name-useFormat) 0
    }
    if {[string match "date*" $widgetType]} {
	set editWin($name-focusWin) {[%W component date]}
    } else {
	set editWin($name-focusWin) {[%W component time]}
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrSpinner
#
# Registers the spinner widget from the Iwidgets package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrSpinner {{name spinner}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::spinner %W -width 0" \
	$name-putValueCmd	"%W clear; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrSpinint
#
# Registers the spinint widget from the Iwidgets package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrSpinint {{name spinint}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::spinint %W -width 0" \
	$name-putValueCmd	"%W clear; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrCombobox
#
# Registers the combobox widget from the Iwidgets package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrCombobox {{name combobox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"createIncrCombobox %W" \
	$name-putValueCmd	"%W clear entry; %W insert entry 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear entry; %W insert entry 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	{eval [list %W insert list end] %L} \
	$name-getListCmd	"%W component list get 0 end" \
	$name-selectCmd		"%W selection set %I" \
	$name-invokeCmd		"%W invoke" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right Up Down Control-p Control-n} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addCtext
#
# Registers the ctext widget for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addCtext {{name ctext}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"ctext %W -padx 2 -pady 2 -wrap none" \
	$name-putValueCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	$name-getValueCmd	"%W get 1.0 end-1c" \
	$name-putTextCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	$name-getTextCmd	"%W get 1.0 end-1c" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		0 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.t \
	$name-reservedKeys	{Left Right Up Down Prior Next
				 Control-Home Control-End Meta-b Meta-f
				 Control-p Control-n Meta-less Meta-greater} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addOakleyCombobox
#
# Registers Bryan Oakley's combobox widget for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addOakleyCombobox {{name combobox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"createOakleyCombobox %W" \
	$name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	{eval [list %W list insert end] %L} \
	$name-getListCmd	"%W list get 0 end" \
	$name-selectCmd		"%W select %I" \
	$name-invokeCmd		"%W open" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.entry \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    #
    # Patch the ::combobox::UpdateVisualAttributes procedure to make sure it
    # won't change the background and trough colors of the vertical scrollbar
    #
    catch {combobox::combobox}	;# enforces the evaluation of "combobox.tcl"
    if {[catch {rename ::combobox::UpdateVisualAttributes \
		::combobox::_UpdateVisualAttributes}] == 0} {
	proc ::combobox::UpdateVisualAttributes w {
	    set vsbBackground [$w.top.vsb cget -background]
	    set vsbTroughColor [$w.top.vsb cget -troughcolor]

	    ::combobox::_UpdateVisualAttributes $w

	    $w.top.vsb configure -background $vsbBackground
	    $w.top.vsb configure -troughcolor $vsbTroughColor
	}
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addDateMentry
#
# Registers the widget created by the mentry::dateMentry command from the
# Mentry package, with a given format and separator and with or without the
# "-gmt 1" option for the mentry::putClockVal and mentry::getClockVal commands,
# for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addDateMentry {fmt sep args} {
    #
    # Parse the fmt argument
    #
    if {![regexp {^([dmyY])([dmyY])([dmyY])$} $fmt dummy \
		 fields(0) fields(1) fields(2)]} {
	return -code error \
	       "bad format \"$fmt\": must be a string of length 3,\
		consisting of the letters d, m, and y or Y"
    }

    #
    # Check whether all the three date components are represented in fmt
    #
    for {set n 0} {$n < 3} {incr n} {
	set lfields($n) [string tolower $fields($n)]
    }
    if {[string compare $lfields(0) $lfields(1)] == 0 ||
	[string compare $lfields(0) $lfields(2)] == 0 ||
	[string compare $lfields(1) $lfields(2)] == 0} {
	return -code error \
	       "bad format \"$fmt\": must have unique components for the\
		day, month, and year"
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useGMT 0
	    set name dateMentry
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-gmt"] == 0} {
		set useGMT 1
		set name dateMentry
	    } else {
		set useGMT 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-gmt"] != 0} {
		return -code error "bad option \"$arg0\": must be -gmt"
	    }

	    set useGMT 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addDateMentry format separator ?-gmt? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::dateMentry %W $fmt $sep] \
	$name-putValueCmd	"mentry::putClockVal %T %W -gmt $useGMT" \
	$name-getValueCmd	"mentry::getClockVal %W -gmt $useGMT" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addTimeMentry
#
# Registers the widget created by the mentry::timeMentry command from the
# Mentry package, with a given format and separator and with or without the
# "-gmt 1" option for the mentry::putClockVal and mentry::getClockVal commands,
# for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addTimeMentry {fmt sep args} {
    #
    # Parse the fmt argument
    #
    if {![regexp {^(H|I)(M)(S?)$} $fmt dummy fields(0) fields(1) fields(2)]} {
	return -code error \
	       "bad format \"$fmt\": must be a string of length 2 or 3\
		starting with H or I, followed by M and optionally by S"
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useGMT 0
	    set name timeMentry
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-gmt"] == 0} {
		set useGMT 1
		set name timeMentry
	    } else {
		set useGMT 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-gmt"] != 0} {
		return -code error "bad option \"$arg0\": must be -gmt"
	    }

	    set useGMT 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addTimeMentry format separator ?-gmt? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::timeMentry %W $fmt $sep] \
	$name-putValueCmd	"mentry::putClockVal %T %W -gmt $useGMT" \
	$name-getValueCmd	"mentry::getClockVal %W -gmt $useGMT" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addDateTimeMentry
#
# Registers the widget created by the mentry::dateTimeMentry command from the
# Mentry package, with a given format and given separators and with or without
# the "-gmt 1" option for the mentry::putClockVal and mentry::getClockVal
# commands, for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addDateTimeMentry {fmt dateSep timeSep args} {
    #
    # Parse the fmt argument
    #
    if {![regexp {^([dmyY])([dmyY])([dmyY])(H|I)(M)(S?)$} $fmt dummy \
		 fields(0) fields(1) fields(2) fields(3) fields(4) fields(5)]} {
	return -code error \
	       "bad format \"$fmt\": must be a string of length 5 or 6,\
		with the first 3 characters consisting of the letters d, m,\
		and y or Y, followed by H or I, then M, and optionally by S"
    }

    #
    # Check whether all the three date components are represented in fmt
    #
    for {set n 0} {$n < 3} {incr n} {
	set lfields($n) [string tolower $fields($n)]
    }
    if {[string compare $lfields(0) $lfields(1)] == 0 ||
	[string compare $lfields(0) $lfields(2)] == 0 ||
	[string compare $lfields(1) $lfields(2)] == 0} {
	return -code error \
	       "bad format \"$fmt\": must have unique components for the\
		day, month, and year"
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useGMT 0
	    set name dateTimeMentry
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-gmt"] == 0} {
		set useGMT 1
		set name dateTimeMentry
	    } else {
		set useGMT 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-gmt"] != 0} {
		return -code error "bad option \"$arg0\": must be -gmt"
	    }

	    set useGMT 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addDateTimeMentry format dateSeparator\
				  timeSeparator ?-gmt? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::dateTimeMentry %W $fmt \
				      $dateSep $timeSep] \
	$name-putValueCmd	"mentry::putClockVal %T %W -gmt $useGMT" \
	$name-getValueCmd	"mentry::getClockVal %W -gmt $useGMT" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addFixedPointMentry
#
# Registers the widget created by the mentry::fixedPointMentry command from the
# Mentry package, with a given number of characters before and a given number
# of digits after the decimal point, with or without the -comma option, for
# interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addFixedPointMentry {cnt1 cnt2 args} {
    #
    # Check the arguments cnt1 and cnt2
    #
    if {![isInteger $cnt1] || $cnt1 <= 0} {
	return -code error "expected positive integer but got \"$cnt1\""
    }
    if {![isInteger $cnt2] || $cnt2 <= 0} {
	return -code error "expected positive integer but got \"$cnt2\""
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useComma 0
	    set name fixedPointMentry_$cnt1.$cnt2
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-comma"] == 0} {
		set useComma 1
		set name fixedPointMentry_$cnt1,$cnt2
	    } else {
		set useComma 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-comma"] != 0} {
		return -code error "bad option \"$arg0\": must be -comma"
	    }

	    set useComma 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addFixedPointMentry count1 count2\
				  ?-comma? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::fixedPointMentry %W $cnt1 $cnt2] \
	$name-putValueCmd	"mentry::putReal %T %W" \
	$name-getValueCmd	"mentry::getReal %W" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right} \
    ]
    if {$useComma} {
	lappend editWin($name-creationCmd) -comma
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIPAddrMentry
#
# Registers the widget created by the mentry::ipAddrMentry command from the
# Mentry package for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIPAddrMentry {{name ipAddrMentry}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"mentry::ipAddrMentry %W" \
	$name-putValueCmd	"mentry::putIPAddr %T %W" \
	$name-getValueCmd	"mentry::getIPAddr %W" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIPv6AddrMentry
#
# Registers the widget created by the mentry::ipv6AddrMentry command from the
# Mentry package for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIPv6AddrMentry {{name ipv6AddrMentry}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"mentry::ipv6AddrMentry %W" \
	$name-putValueCmd	"mentry::putIPv6Addr %T %W" \
	$name-getValueCmd	"mentry::getIPv6Addr %W" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#
# Private procedures implementing the interactive cell editing
# ============================================================
#

#------------------------------------------------------------------------------
# tablelist::checkEditWinName
#
# Generates an error if the given edit window name is one of "entry", "text",
# "spinbox", "checkbutton", "menubutton", "ttk::entry", "ttk::spinbox",
# "ttk::combobox", "ttk::checkbutton", or "ttk::menubutton".
#------------------------------------------------------------------------------
proc tablelist::checkEditWinName name {
    if {[regexp {^(entry|text|spinbox|checkbutton|menubutton)$} $name]} {
	return -code error \
	       "edit window name \"$name\" is reserved for Tk $name widgets"
    }

    if {[regexp {^(::)?ttk::(entry|spinbox|combobox|checkbutton|menubutton)$} \
	 $name]} {
	return -code error \
	       "edit window name \"$name\" is reserved for tile $name widgets"
    }
}

#------------------------------------------------------------------------------
# tablelist::createCheckbutton
#
# Creates a checkbutton widget with the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createCheckbutton {w args} {
    variable winSys
    switch $winSys {
	x11 {
	    variable checkedImg
	    variable uncheckedImg
	    if {![info exists checkedImg]} {
		createCheckbuttonImgs 
	    }

	    checkbutton $w -borderwidth 2 -indicatoron 0 -image $uncheckedImg \
			   -selectimage $checkedImg
	    if {$::tk_version >= 8.4} {
		$w configure -offrelief sunken
	    }
	    pack $w
	}

	win32 {
	    checkbutton $w -borderwidth 0 -font {"MS Sans Serif" 8} \
			   -padx 0 -pady 0
	    [winfo parent $w] configure -width 13 -height 13
	    switch [winfo reqheight $w] {
		17	{ set y -1 }
		20	{ set y -3 }
		25	{ set y -5 }
		30 -
		31	{ set y -8 }
		default	{ set y -1 }
	    }
	    place $w -x -1 -y $y
	}

	classic {
	    checkbutton $w -borderwidth 0 -font "system" -padx 0 -pady 0
	    [winfo parent $w] configure -width 16 -height 14
	    place $w -x 0 -y -1
	}

	aqua {
	    checkbutton $w -borderwidth 0 -font "system" -padx 0 -pady 0
	    [winfo parent $w] configure -width 16 -height 16
	    place $w -x -4 -y -3
	}
    }

    foreach {opt val} $args {
	switch -- $opt {
	    -state  { $w configure $opt $val }
	    default {}
	}
    }

    set win [getTablelistPath $w]
    $w configure -variable ::tablelist::ns${win}::data(editText)
}

#------------------------------------------------------------------------------
# tablelist::createMenubutton
#
# Creates a menubutton widget with the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createMenubutton {w args} {
    set win [getTablelistPath $w]
    menubutton $w -anchor w -indicatoron 1 -justify left -padx 2 -pady 2 \
	-relief raised -textvariable ::tablelist::ns${win}::data(editText)

    foreach {opt val} $args {
	$w configure $opt $val
    }

    variable winSys
    upvar ::tablelist::ns${win}::data data
    if {[string compare $winSys "aqua"] == 0} {
	catch {
	    set data(useCustomMDEFSav) $::tk::mac::useCustomMDEF
	    set ::tk::mac::useCustomMDEF 1
	}
    }

    set menu $w.menu
    menu $menu -tearoff 0 -postcommand [list tablelist::postMenuCmd $w]
    foreach event {<Map> <Unmap>} {
	bind $menu $event {
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }
    if {[string compare $winSys "x11"] == 0} {
	$menu configure -background $data(-background) \
			-foreground $data(-foreground) \
			-activebackground $data(-selectbackground) \
			-activeforeground $data(-selectforeground) \
			-activeborderwidth $data(-selectborderwidth)
    }

    $w configure -menu $menu
}

#------------------------------------------------------------------------------
# tablelist::postMenuCmd
#
# Activates the radiobutton entry of the menu associated with the menubutton
# widget having the given path name whose -value option was set to the
# menubutton's text.
#------------------------------------------------------------------------------
proc tablelist::postMenuCmd w {
    set menu [$w cget -menu]
    variable winSys
    if {[string compare $winSys "x11"] == 0} {
	set last [$menu index last]
	if {[string compare $last "none"] != 0} {
	    set text [$w cget -text]
	    for {set idx 0} {$idx <= $last} {incr idx} {
		if {[string compare [$menu type $idx] "radiobutton"] == 0 &&
		    [string compare [$menu entrycget $idx -value] $text] == 0} {
		    $menu activate $idx
		}
	    }
	}
    } else {
	if {[catch {set ::tk::Priv(postedMb) ""}] != 0} {
	    set ::tkPriv(postedMb) ""
	}

	if {[string compare [winfo class $w] "TMenubutton"] == 0} {
	    if {[catch {set ::tk::Priv(popup) $menu}] != 0} {
		set ::tkPriv(popup) $menu
	    }
	}

	if {[string compare $winSys "aqua"] == 0} {
	    set win [getTablelistPath $w]
	    upvar ::tablelist::ns${win}::data data
	    if {[string compare [$data(body) cget -cursor] $data(-cursor)]
		!= 0} {
		$data(body) configure -cursor $data(-cursor)
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileEntry
#
# Creates a tile entry widget with the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileEntry {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    #
    # The style of the tile entry widget should have -borderwidth
    # 2 and -padding 1.  For those themes that don't honor the
    # -borderwidth 2 setting, set the padding to another value.
    #
    set win [getTablelistPath $w]
    switch -- [getCurrentTheme] {
	aqua {
	    set padding {0 0 0 -1}
	}

	tileqt {
	    set padding 3
	}

	xpnative {
	    switch [winfo rgb . SystemHighlight] {
		"12593 27242 50629" -
		"37779 41120 28784" -
		"45746 46260 49087" -
		"13107 39321 65535"	{ set padding 2 }
		default			{ set padding 1 }
	    }
	}

	default {
	    set padding 1
	}
    }
    styleConfig Tablelist.TEntry -borderwidth 2 -highlightthickness 0 \
				 -padding $padding

    ttk::entry $w -style Tablelist.TEntry

    foreach {opt val} $args {
	$w configure $opt $val
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileSpinbox
#
# Creates a tile spinbox widget with the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileSpinbox {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.8.3
    }
    createTileAliases 

    #
    # The style of the tile entry widget should have -borderwidth
    # 2 and -padding 1.  For those themes that don't honor the
    # -borderwidth 2 setting, set the padding to another value.
    #
    set win [getTablelistPath $w]
    switch -- [getCurrentTheme] {
	aqua {
	    set padding {0 0 0 -1}
	}

	tileqt {
	    set padding 3
	}

	vista {
	    switch [winfo rgb . SystemHighlight] {
		"13107 39321 65535"	{ set padding 0 }
		default			{ set padding 1 }
	    }
	}

	xpnative {
	    switch [winfo rgb . SystemHighlight] {
		"12593 27242 50629" -
		"37779 41120 28784" -
		"45746 46260 49087" -
		"13107 39321 65535"	{ set padding 2 }
		default			{ set padding 1 }
	    }
	}

	default {
	    set padding 1
	}
    }
    styleConfig Tablelist.TSpinbox -borderwidth 2 -highlightthickness 0 \
				   -padding $padding

    ttk::spinbox $w -style Tablelist.TSpinbox

    foreach {opt val} $args {
	$w configure $opt $val
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileCombobox
#
# Creates a tile combobox widget with the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileCombobox {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    set win [getTablelistPath $w]
    if {[string compare [getCurrentTheme] "aqua"] == 0} {
	styleConfig Tablelist.TCombobox -borderwidth 2 -padding {0 0 0 -1}
    } else {
	styleConfig Tablelist.TCombobox -borderwidth 2 -padding 1
    }

    ttk::combobox $w -style Tablelist.TCombobox

    foreach {opt val} $args {
	$w configure $opt $val
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileCheckbutton
#
# Creates a tile checkbutton widget with the given path name for interactive
# cell editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileCheckbutton {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    #
    # Define the checkbutton layout; use catch to suppress
    # the error message in case the layout already exists
    #
    set currentTheme [getCurrentTheme]
    if {[string compare $currentTheme "aqua"] == 0} {
	catch {style layout Tablelist.TCheckbutton { Checkbutton.button }}
    } else {
	catch {style layout Tablelist.TCheckbutton { Checkbutton.indicator }}
	styleConfig Tablelist.TCheckbutton -indicatormargin 0
    }

    set win [getTablelistPath $w]
    ttk::checkbutton $w -style Tablelist.TCheckbutton \
			-variable ::tablelist::ns${win}::data(editText)

    foreach {opt val} $args {
	switch -- $opt {
	    -state  { $w configure $opt $val }
	    default {}
	}
    }

    #
    # Adjust the dimensions of the tile checkbutton's parent
    # and manage the checkbutton, depending on the current theme
    #
    switch -- $currentTheme {
	aqua {
	    [winfo parent $w] configure -width 16 -height 16
	    place $w -x -3 -y -3
	}

	Aquativo {
	    [winfo parent $w] configure -width 14 -height 14
	    place $w -x -1 -y -1
	}

	blue -
	winxpblue {
	    set height [winfo reqheight $w]
	    [winfo parent $w] configure -width $height -height $height
	    place $w -x 0
	}

	clam {
	    [winfo parent $w] configure -width 11 -height 11
	    place $w -x 0
	}

	keramik -
	keramik_alt {
	    [winfo parent $w] configure -width 16 -height 16
	    place $w -x -1 -y -1
	}

	plastik {
	    [winfo parent $w] configure -width 15 -height 15
	    place $w -x -2 -y 1
	}

	sriv -
	srivlg {
	    [winfo parent $w] configure -width 15 -height 16
	    place $w -x -1
	}

	tileqt {
	    switch -- [string tolower [tileqt_currentThemeName]] {
		acqua {
		    [winfo parent $w] configure -width 17 -height 18
		    place $w -x -1 -y -2
		}
		cde -
		cleanlooks -
		motif {
		    [winfo parent $w] configure -width 13 -height 13
		    if {[info exists ::env(KDE_SESSION_VERSION)] &&
			[string length $::env(KDE_SESSION_VERSION)] != 0} {
			place $w -x -2
		    } else {
			place $w -x 0
		    }
		}
		gtk+ {
		    [winfo parent $w] configure -width 15 -height 15
		    place $w -x -1 -y -1
		}
		kde_xp {
		    [winfo parent $w] configure -width 13 -height 13
		    place $w -x 0
		}
		keramik -
		thinkeramik {
		    [winfo parent $w] configure -width 16 -height 16
		    place $w -x 0
		}
		oxygen {
		    [winfo parent $w] configure -width 17 -height 17
		    place $w -x -2 -y -1
		}
		default {
		    set height [winfo reqheight $w]
		    [winfo parent $w] configure -width $height -height $height
		    place $w -x 0
		}
	    }
	}

	vista {
	    set height [winfo reqheight $w]
	    [winfo parent $w] configure -width $height -height $height
	    place $w -x 0
	}

	winnative -
	xpnative {
	    set height [winfo reqheight $w]
	    [winfo parent $w] configure -width $height -height $height
	    if {[info exists tile::patchlevel] &&
		[string compare $tile::patchlevel "0.8.0"] < 0} {
		place $w -x -2
	    } else {
		place $w -x 0
	    }
	}

	default {
	    pack $w
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileMenubutton
#
# Creates a tile menubutton widget with the given path name for interactive
# cell editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileMenubutton {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    styleConfig Tablelist.TMenubutton -anchor w -justify left -padding 1 \
				      -relief raised

    set win [getTablelistPath $w]
    ttk::menubutton $w -style Tablelist.TMenubutton \
		       -textvariable ::tablelist::ns${win}::data(editText)

    foreach {opt val} $args {
	switch -- $opt {
	    -state  { $w configure $opt $val }
	    default {}
	}
    }

    variable winSys
    upvar ::tablelist::ns${win}::data data
    if {[string compare $winSys "aqua"] == 0} {
	catch {
	    set data(useCustomMDEFSav) $::tk::mac::useCustomMDEF
	    set ::tk::mac::useCustomMDEF 1
	}
    }

    set menu $w.menu
    menu $menu -tearoff 0 -postcommand [list tablelist::postMenuCmd $w]
    if {[string compare $winSys "x11"] == 0} {
	$menu configure -background $data(-background) \
			-foreground $data(-foreground) \
			-activebackground $data(-selectbackground) \
			-activeforeground $data(-selectforeground) \
			-activeborderwidth $data(-selectborderwidth)
    }

    $w configure -menu $menu
}

#------------------------------------------------------------------------------
# tablelist::createBWidgetComboBox
#
# Creates a BWidget ComboBox widget with the given path name for interactive
# cell editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createBWidgetComboBox {w args} {
    eval [list ComboBox $w -editable 1 -width 0] $args
    ComboBox::_create_popup $w

    foreach event {<Map> <Unmap>} {
	bind $w.shell.listb $event {
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createIncrCombobox
#
# Creates an [incr Widgets] combobox with the given path name for interactive
# cell editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createIncrCombobox {w args} {
    eval [list iwidgets::combobox $w -dropdown 1 -editable 1 -width 0] $args

    foreach event {<Map> <Unmap>} {
	bind [$w component list] $event {+
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }

    #
    # Make sure that the entry component will receive the input focus
    # whenever the list component (a scrolledlistbox widget) gets unmapped
    #
    bind [$w component list] <Unmap> +[list focus [$w component entry]]
}

#------------------------------------------------------------------------------
# tablelist::createOakleyCombobox
#
# Creates an Oakley combobox widget with the given path name for interactive
# cell editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createOakleyCombobox {w args} {
    eval [list combobox::combobox $w -editable 1 -width 0] $args

    foreach event {<Map> <Unmap>} {
	bind $w.top.list $event {
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }

    #
    # Repack the widget's components, to make sure that the
    # button will remain visible when shrinking the combobox.
    # This patch is needed for combobox versions earlier than 2.3.
    #
    pack forget $w.entry $w.button
    pack $w.button -side right -fill y    -expand 0
    pack $w.entry  -side left  -fill both -expand 1
}

#------------------------------------------------------------------------------
# tablelist::doEditCell
#
# Processes the tablelist editcell subcommand.  cmd may be an empty string,
# "condChangeSelection", or "changeSelection".  charPos stands for the
# character position component of the index in the body text widget of the
# character underneath the mouse cursor if this command was invoked by clicking
# mouse button 1 in the body of the tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::doEditCell {win row col restore {cmd ""} {charPos -1}} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || ![isRowViewable $win $row] || $data($col-hide) ||
	![isCellEditable $win $row $col]} {
	return ""
    }
    if {$data(editRow) == $row && $data(editCol) == $col} {
	return ""
    }
    if {$data(editRow) >= 0 && ![doFinishEditing $win]} {
	return ""
    }
    set item [lindex $data(itemList) $row]
    set key [lindex $item end]
    getIndentData $win $key $col indentWidth
    set pixels [colWidth $win $col -stretched]
    if {$indentWidth >= $pixels} {
	return ""
    }

    #
    # Create a frame to be embedded into the tablelist's body, together with
    # a child of column/cell-specific type; replace the binding tag Frame with
    # $data(editwinTag) and TablelistEdit in the frame's list of binding tags
    #
    seeCell $win $row $col
    set netRowHeight [lindex [bboxSubCmd $win $row] 3]
    set frameHeight [expr {$netRowHeight + 6}]	;# because of the -pady -3 below
    set f $data(bodyFr)
    tk::frame $f -borderwidth 0 -container 0 -height $frameHeight \
		 -highlightthickness 0 -relief flat -takefocus 0
    catch {$f configure -padx 0 -pady 0}
    bindtags $f [lreplace [bindtags $f] 1 1 $data(editwinTag) TablelistEdit]
    set name [getEditWindow $win $row $col]
    variable editWin
    set creationCmd [strMap {"%W" "$w"} $editWin($name-creationCmd)]
    append creationCmd { $editWin($name-fontOpt) [getCellFont $win $key $col]} \
		       { -state normal}
    set w $data(bodyFrEd)
    if {[catch {eval $creationCmd} result] != 0} {
	destroy $f
	return -code error $result
    }
    catch {$w configure -highlightthickness 0}
    clearTakefocusOpt $w
    set class [winfo class $w]
    set isCheckbtn [string match "*Checkbutton" $class]
    set isMenubtn [string match "*Menubutton" $class]
    set isText [expr {[string compare $class "Text"] == 0 ||
		      [string compare $class "Ctext"] == 0}]
    set isMentry [expr {[string compare $class "Mentry"] == 0}]
    if {!$isCheckbtn && !$isMenubtn} {
	catch {$w configure -relief ridge}
	catch {$w configure -borderwidth 2}
    }
    if {$isText && $data($col-wrap) && $::tk_version >= 8.5} {
	$w configure -wrap word
    }
    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
    if {!$isText && !$isMentry} {
	catch {$w configure -justify $alignment}
    }

    #
    # Define some bindings for the above frame
    #
    bind $f <Enter> {
	set tablelist::W [tablelist::getTablelistPath %W]
	set tablelist::ns${tablelist::W}::data(inEditWin) 1
	tablelist::invokeMotionHandler $tablelist::W
    }
    bind $f <Leave> {
	set tablelist::W [tablelist::getTablelistPath %W]
	set tablelist::ns${tablelist::W}::data(inEditWin) 0
	set tablelist::ns${tablelist::W}::data(prevCell) -1,-1
	tablelist::invokeMotionHandler $tablelist::W
    }
    bind $f <Destroy> {
	set tablelist::W [tablelist::getTablelistPath %W]
	array set tablelist::ns${tablelist::W}::data \
	      {editKey ""  editRow -1  editCol -1  inEditWin 0  prevCell -1,-1}
	if {[catch {tk::CancelRepeat}] != 0} {
	    tkCancelRepeat 
	}
	if {[catch {ttk::CancelRepeat}] != 0} {
	    catch {tile::CancelRepeat}
	}
	tablelist::invokeMotionHandler $tablelist::W
    }

    #
    # Replace the cell's contents between the two tabs with the above frame
    #
    array set data [list editKey $key editRow $row editCol $col]
    findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
    set b $data(body)
    getIndentData $win $data(editKey) $data(editCol) indentWidth
    if {$indentWidth == 0} {
	set textIdx [$b index $tabIdx1+1c]
    } else {
	$b mark set editIndentMark [$b index $tabIdx1+1c]
	set textIdx [$b index $tabIdx1+2c]
    }
    if {$isCheckbtn} {
	set editIdx $textIdx
	$b delete $editIdx $tabIdx2
    } else {
	getAuxData $win $data(editKey) $data(editCol) auxType auxWidth
	if {$auxType == 0 || $auxType > 1} {			;# no image
	    set editIdx $textIdx
	    $b delete $editIdx $tabIdx2
	} elseif {[string compare $alignment "right"] == 0} {
	    $b mark set editAuxMark $tabIdx2-1c
	    set editIdx $textIdx
	    $b delete $editIdx $tabIdx2-1c
	} else {
	    $b mark set editAuxMark $textIdx
	    set editIdx [$b index $textIdx+1c]
	    $b delete $editIdx $tabIdx2
	}
    }
    $b window create $editIdx -padx -3 -pady -3 -window $f
    $b mark set editMark $editIdx

    #
    # Insert the binding tags $data(editwinTag) and TablelistEdit
    # into the list of binding tags of some components
    # of w, just before the respective path names
    #
    if {$isMentry} {
	set compList [$w entries]
    } else {
	set comp [subst [strMap {"%W" "$w"} $editWin($name-focusWin)]]
	set compList [list $comp]
	set data(editFocus) $comp
    }
    foreach comp $compList {
	set bindTags [bindtags $comp]
	set idx [lsearch -exact $bindTags $comp]
	bindtags $comp [linsert $bindTags $idx $data(editwinTag) TablelistEdit]
    }

    #
    # Restore or initialize some of the edit window's data
    #
    if {$restore} {
	restoreEditData $win
    } else {
	#
	# Put the cell's contents to the edit window
	#
	set data(canceled) 0
	set data(invoked) 0
	set text [lindex $item $col]
	if {$editWin($name-useFormat) && [lindex $data(fmtCmdFlagList) $col]} {
	    set text [formatElem $win $key $row $col $text]
	}
	catch {
	    eval [strMap {"%W" "$w"  "%T" "$text"} $editWin($name-putValueCmd)]
	}

	#
	# Save the edit window's text
	#
	set data(origEditText) \
	    [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]

	if {[string length $data(-editstartcommand)] != 0} {
	    set text [uplevel #0 $data(-editstartcommand) \
		      [list $win $row $col $text]]

	    variable winSys
	    if {[string compare $winSys "aqua"] == 0} {
		catch {set ::tk::mac::useCustomMDEF $data(useCustomMDEFSav)}
	    }

	    if {$data(canceled)} {
		return ""
	    }

	    catch {
		eval [strMap {"%W" "$w"  "%T" "$text"} \
		      $editWin($name-putValueCmd)]
	    }
	}

	if {$isMenubtn} {
	    set menu [$w cget -menu]
	    set last [$menu index last]
	    if {[string compare $last "none"] != 0} {
		set varName [$w cget -textvariable]
		for {set idx 0} {$idx <= $last} {incr idx} {
		    if {[string compare [$menu type $idx] "radiobutton"] == 0} {
			$menu entryconfigure $idx -variable $varName
		    }
		}
	    }
	}

	#
	# Save the edit window's text again
	#
	set data(origEditText) \
	    [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]
	set data(rejected) 0

	if {[string length $editWin($name-getListCmd)] != 0 &&
	    [string length $editWin($name-selectCmd)] != 0} {
	    #
	    # Select the edit window's item corresponding to text
	    #
	    set itemList [eval [strMap {"%W" "$w"} $editWin($name-getListCmd)]]
	    if {[set idx [lsearch -exact $itemList $text]] >= 0} {
		eval [strMap {"%W" "$w"  "%I" "$idx"} $editWin($name-selectCmd)]
	    }
	}

	#
	# Evaluate the optional command passed as argument
	#
	if {[string length $cmd] != 0} {
	    eval [list $cmd $win $row $col]
	}

	#
	# Set the focus and the insertion cursor
	#
	if {$charPos >= 0} {
	    if {$isText || !$editWin($name-isEntryLike)} {
		focus $w
	    } else {
		set hasAuxObject [expr {
		    [info exists data($key,$col-image)] ||
		    [info exists data($key,$col-window)]}]
		if {[string compare $alignment "right"] == 0} {
		    scan $tabIdx2 "%d.%d" line tabCharIdx2
		    if {$isMentry} {
			set len [string length [$w getstring]]
		    } else {
			set len [$comp index end]
		    }
		    set number [expr {$len - $tabCharIdx2 + $charPos}]
		    if {$hasAuxObject} {
			incr number 2
		    }
		} else {
		    scan $tabIdx1 "%d.%d" line tabCharIdx1
		    set number [expr {$charPos - $tabCharIdx1 - 1}]
		    if {$hasAuxObject} {
			incr number -2
		    }
		}
		if {$isMentry} {
		    setMentryCursor $w $number
		} else {
		    focus $comp
		    $comp icursor $number
		}
	    }
	} else {
	    if {$isText || $isMentry || !$editWin($name-isEntryLike)} {
		focus $w
	    } else {
		focus $comp
		$comp icursor end
		$comp selection range 0 end
	    }
	}
    }

    if {$data(-autofinishediting)} {
	#
	# Make sure that selecting a combobox or menu
	# entry will automatically finish the editing
	#
	switch $class {
	    TCombobox {
		bind $w <<ComboboxSelected>> \
		    {+ [tablelist::getTablelistPath %W] finishediting}
	    }

	    ComboBox {					;# BWidget
		set cmd [$w cget -modifycmd]
		$w configure -modifycmd [format {
		    eval [list %s]
		    after 0 [list %s finishediting]
		} $cmd $win]
	    }

	    Combobox {					;# IWidgets or Oakley
		if {[catch {$w cget -selectioncommand} cmd] == 0} {  ;# IWidgets
		    set cmd [$w cget -selectioncommand]
		    $w configure -selectioncommand [format {
			eval [list %s]
			after 0 [list %s finishediting]
		    } $cmd $win]
		} elseif {[catch {$w cget -command} cmd] == 0} {     ;# Oakley
		    if {[string length $cmd] == 0} {
			proc ::tablelist::comboboxCmd {w val} [format {
			    after 0 [list %s finishediting]
			} $win]
		    } else {
			proc ::tablelist::comboboxCmd {w val} [format {
			    eval [list %s $w $val]
			    after 0 [list %s finishediting]
			} $cmd $win]
		    }
		    $w configure -command ::tablelist::comboboxCmd
		}
	    }

	    Menubutton -
	    TMenubutton {
		set menu [$w cget -menu]
		set last [$menu index last]
		if {[string compare $last "none"] != 0} {
		    for {set idx 0} {$idx <= $last} {incr idx} {
			if {[regexp {^(command|checkbutton|radiobutton)$} \
			     [$menu type $idx]]} {
			    set cmd [$menu entrycget $idx -command]
			    $menu entryconfigure $idx -command [format {
				eval [list %s]
				after 0 [list %s finishediting]
			    } $cmd $win]
			}
		    }
		}
	    }
	}
    }

    #
    # Adjust the frame's height
    #
    if {$isText} {
	if {[string compare [$w cget -wrap] "none"] == 0 ||
	    $::tk_version < 8.5} {
	    set numLines [expr {int([$w index end-1c])}]
	    $w configure -height $numLines
	    update idletasks				;# needed for ctext
	    if {![array exists ::tablelist::ns${win}::data]} {
		return ""
	    }
	    $f configure -height [winfo reqheight $w]
	} else {
	    bind $w <Configure> {
		%W configure -height [%W count -displaylines 1.0 end]
		[winfo parent %W] configure -height [winfo reqheight %W]
	    }
	}
	if {[info exists ::wcb::version]} {
	    wcb::cbappend $w after insert tablelist::adjustTextHeight
	    wcb::cbappend $w after delete tablelist::adjustTextHeight
	}
    } elseif {!$isCheckbtn} {
	update idletasks
	if {![array exists ::tablelist::ns${win}::data]} {
	    return ""
	}
	$f configure -height [winfo reqheight $w]
    }

    #
    # Adjust the frame's width and paddings
    #
    if {!$isCheckbtn} {
	place $w -relwidth 1.0 -relheight 1.0
	adjustEditWindow $win $pixels
	update idletasks
	if {![array exists ::tablelist::ns${win}::data]} {
	    return ""
	}
    }

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::doCancelEditing
#
# Processes the tablelist cancelediting subcommand.  Aborts the interactive
# cell editing and restores the cell's contents after destroying the edit
# window.
#------------------------------------------------------------------------------
proc tablelist::doCancelEditing win {
    upvar ::tablelist::ns${win}::data data
    if {[set row $data(editRow)] < 0} {
	return ""
    }
    set col $data(editCol)

    #
    # Invoke the command specified by the -editendcommand option if needed
    #
    set data(canceled) 1
    if {$data(-forceeditendcommand) &&
	[string length $data(-editendcommand)] != 0} {
	uplevel #0 $data(-editendcommand) \
		[list $win $row $col $data(origEditText)]
    }

    if {[winfo exists $data(bodyFr)]} {
	destroy $data(bodyFr)
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	foreach opt {-window -image} {
	    if {[info exists data($key,$col$opt)]} {
		doCellConfig $row $col $win $opt $data($key,$col$opt)
		break
	    }
	}
	doCellConfig $row $col $win -text [lindex $item $col]
    }

    focus $data(body)

    set userData [list $row $col]
    genVirtualEvent $win <<TablelistCellRestored>> $userData

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::doFinishEditing
#
# Processes the tablelist finishediting subcommand.  Invokes the command
# specified by the -editendcommand option if needed, and updates the element
# just edited after destroying the edit window if the latter's content was not
# rejected.  Returns 1 on normal termination and 0 otherwise.
#------------------------------------------------------------------------------
proc tablelist::doFinishEditing win {
    upvar ::tablelist::ns${win}::data data
    if {[set row $data(editRow)] < 0} {
	return 1
    }
    set col $data(editCol)

    #
    # Get the edit window's text, and invoke the command
    # specified by the -editendcommand option if needed
    #
    set w $data(bodyFrEd)
    set name [getEditWindow $win $row $col]
    variable editWin
    set text [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]
    set item [lindex $data(itemList) $row]
    if {!$data(-forceeditendcommand) &&
	[string compare $text $data(origEditText)] == 0} {
	set text [lindex $item $col]
    } else {
	if {[catch {
	    eval [strMap {"%W" "$w"} $editWin($name-getValueCmd)]
	} text] != 0} {
	    set data(rejected) 1
	}
	if {[string length $data(-editendcommand)] != 0} {
	    set text \
		[uplevel #0 $data(-editendcommand) [list $win $row $col $text]]
	}
    }

    #
    # Check whether the input was rejected (by the above "set data(rejected) 1"
    # statement or within the command specified by the -editendcommand option)
    #
    if {$data(rejected)} {
	if {[winfo exists $data(bodyFr)]} {
	    seeCell $win $row $col
	    if {[string compare [winfo class $w] "Mentry"] != 0} {
		focus $data(editFocus)
	    }
	} else {
	    focus $data(body)
	}

	set data(rejected) 0
	set result 0
    } else {
	if {[winfo exists $data(bodyFr)]} {
	    destroy $data(bodyFr)
	    set key [lindex $item end]
	    foreach opt {-window -image} {
		if {[info exists data($key,$col$opt)]} {
		    doCellConfig $row $col $win $opt $data($key,$col$opt)
		    break
		}
	    }
	    doCellConfig $row $col $win -text $text
	    set result 1
	} else {
	    set result 0
	}

	focus $data(body)

	set userData [list $row $col]
	genVirtualEvent $win <<TablelistCellUpdated>> $userData
    }

    updateViewWhenIdle $win
    return $result
}

#------------------------------------------------------------------------------
# tablelist::clearTakefocusOpt
#
# Sets the -takefocus option of all members of the widget hierarchy starting
# with w to 0.
#------------------------------------------------------------------------------
proc tablelist::clearTakefocusOpt w {
    catch {$w configure -takefocus 0}
    foreach c [winfo children $w] {
	clearTakefocusOpt $c
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustTextHeight
#
# This procedure is an after-insert and after-delete callback asociated with a
# (c)text widget used for interactive cell editing.  It sets the height of the
# edit window to the number of lines currently contained in it.
#------------------------------------------------------------------------------
proc tablelist::adjustTextHeight {w args} {
    if {$::tk_version >= 8.5} {
	#
	# Count the display lines (taking into account the line wraps)
	#
	set numLines [$w count -displaylines 1.0 end]
    } else {
	#
	# We can only count the logical lines (irrespective of wrapping)
	#
	set numLines [expr {int([$w index end-1c])}]
    }
    $w configure -height $numLines

    set path [wcb::pathname $w]
    [winfo parent $path] configure -height [winfo reqheight $path]
}

#------------------------------------------------------------------------------
# tablelist::setMentryCursor
#
# Sets the focus to the entry child of the mentry widget w that contains the
# global character position specified by number, and sets the insertion cursor
# in that entry to the relative character position corresponding to number.  If
# that entry is not enabled then the procedure sets the focus to the last
# enabled entry child preceding the found one and sets the insertion cursor to
# its end.
#------------------------------------------------------------------------------
proc tablelist::setMentryCursor {w number} {
    #
    # Find the entry child containing the given character
    # position; if the latter is contained in a label child
    # then take the entry immediately preceding that label
    #
    set entryIdx -1
    set childIdx 0
    set childCount [llength [$w cget -body]]
    foreach c [winfo children $w] {
	set class [winfo class $c]
	switch $class {
	    Entry {
		set str [$c get]
		set entry $c
		incr entryIdx
	    }
	    Frame {
		set str [$c.e get]
		set entry $c.e
		incr entryIdx
	    }
	    Label { set str [$c cget -text] }
	}
	set len [string length $str]

	if {$number < $len} {
	    break
	} elseif {$childIdx < $childCount - 1} {
	    incr number -$len
	}

	incr childIdx
    }

    #
    # If the entry's state is normal then set the focus to this entry and
    # the insertion cursor to the relative character position corresponding
    # to number; otherwise set the focus to the last enabled entry child
    # preceding the found one and set the insertion cursor to its end
    #
    switch $class {
	Entry -
	Frame { set relIdx $number }
	Label { set relIdx end }
    }
    if {[string compare [$entry cget -state] "normal"] == 0} {
	focus $entry
	$entry icursor $relIdx
    } else {
	for {incr entryIdx -1} {$entryIdx >= 0} {incr entryIdx -1} {
	    set entry [$w entrypath $entryIdx]
	    if {[string compare [$entry cget -state] "normal"] == 0} {
		focus $entry
		$entry icursor end
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustEditWindow
#
# Adjusts the width and the horizontal padding of the frame containing the edit
# window associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::adjustEditWindow {win pixels} {
    #
    # Adjust the width of the auxiliary object (if any)
    #
    upvar ::tablelist::ns${win}::data data
    set indent [getIndentData $win $data(editKey) $data(editCol) indentWidth]
    set aux [getAuxData $win $data(editKey) $data(editCol) auxType auxWidth]
    if {$indentWidth >= $pixels} {
	set indentWidth $pixels
	set pixels 0
	set auxWidth 0
    } else {
	incr pixels -$indentWidth
	if {$auxType == 1} {					;# image
	    if {$auxWidth + 5 <= $pixels} {
		incr auxWidth 3
		incr pixels -[expr {$auxWidth + 2}]
	    } elseif {$auxWidth <= $pixels} {
		set pixels 0
	    } else {
		set auxWidth $pixels
		set pixels 0
	    }
	}
    }

    if {$indentWidth != 0} {
	insertOrUpdateIndent $data(body) editIndentMark $indent $indentWidth
    }
    if {$auxType == 1} {					;# image
	setImgLabelWidth $data(body) editAuxMark $auxWidth
    }

    #
    # Compute an appropriate width and horizontal
    # padding for the frame containing the edit window
    #
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    if {$editWin($name-useReqWidth) &&
	[set reqWidth [winfo reqwidth $data(bodyFrEd)]] <=
	$pixels + 2*$data(charWidth)} {
	set width $reqWidth
	set padX [expr {$reqWidth <= $pixels ? -3 : ($pixels - $reqWidth) / 2}]
    } else {
	if {$editWin($name-usePadX)} {
	    set amount $data(charWidth)
	} else {
	    switch -- $name {
		text { set amount 4 }
		ttk::entry {
		    if {[string compare [getCurrentTheme] "aqua"] == 0} {
			set amount 5
		    } else {
			set amount 3
		    }
		}
		default { set amount 3 }
	    }
	}
	set width [expr {$pixels + 2*$amount}]
	set padX -$amount
    }

    $data(bodyFr) configure -width $width
    $data(body) window configure editMark -padx $padX
}

#------------------------------------------------------------------------------
# tablelist::setEditWinFont
#
# Sets the font of the edit window associated with the tablelist widget win to
# that of the cell currently being edited.
#------------------------------------------------------------------------------
proc tablelist::setEditWinFont win {
    upvar ::tablelist::ns${win}::data data
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    if {[string length $editWin($name-fontOpt)] == 0} {
	return ""
    }

    set key [lindex $data(keyList) $data(editRow)]
    set cellFont [getCellFont $win $key $data(editCol)]
    $data(bodyFrEd) configure $editWin($name-fontOpt) $cellFont

    $data(bodyFr) configure -height [winfo reqheight $data(bodyFrEd)]
}

#------------------------------------------------------------------------------
# tablelist::saveEditData
#
# Saves some data of the edit window associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::saveEditData win {
    upvar ::tablelist::ns${win}::data data
    set w $data(bodyFrEd)
    set entry $data(editFocus)
    set class [winfo class $w]
    set isText [expr {[string compare $class "Text"] == 0 ||
		      [string compare $class "Ctext"] == 0}]
    set isMentry [expr {[string compare $class "Mentry"] == 0}]

    #
    # Miscellaneous data
    #
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    set data(editText) [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]
    if {[string length $editWin($name-getListCmd)] != 0} {
	set data(editList) \
	    [eval [strMap {"%W" "$w"} $editWin($name-getListCmd)]]
    }
    if {$isText} {
	set data(editPos) [$w index insert]
	set data(textSelRanges) [$w tag ranges sel]
    } elseif {$editWin($name-isEntryLike)} {
	set data(editPos) [$entry index insert]
	if {[set data(entryHadSel) [$entry selection present]]} {
	    set data(entrySelFrom) [$entry index sel.first]
	    set data(entrySelTo)   [$entry index sel.last]
	}
    }
    set data(editHadFocus) \
	[expr {[string compare [focus -lastfor $entry] $entry] == 0}]

    #
    # Configuration options and widget callbacks
    #
    saveEditConfigOpts $w
    if {[info exists ::wcb::version] &&
	$editWin($name-isEntryLike) && !$isMentry} {
	set wcbOptList {insert delete motion}
	if {$isText} {
	    lappend wcbOptList selset selclear
	    if {$::wcb::version >= 3.2} {
		lappend wcbOptList replace
	    }
	}
	foreach when {before after} {
	    foreach opt $wcbOptList {
		set data(entryCb-$when-$opt) \
		    [::wcb::callback $entry $when $opt]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::saveEditConfigOpts
#
# Saves the non-default values of the configuration options of the edit window
# w associated with a tablelist widget, as well as those of its descendants.
#------------------------------------------------------------------------------
proc tablelist::saveEditConfigOpts w {
    regexp {^(.+)\.body\.f\.(e.*)$} $w dummy win tail
    upvar ::tablelist::ns${win}::data data

    foreach configSet [$w configure] {
	if {[llength $configSet] != 2} {
	    set default [lindex $configSet 3]
	    set current [lindex $configSet 4]
	    if {[string compare $default $current] != 0} {
		set opt [lindex $configSet 0]
		set data($tail$opt) $current
	    }
	}
    }

    foreach c [winfo children $w] {
	saveEditConfigOpts $c
    }

    if {[string match "*Menubutton" [winfo class $w]]} {
	set menu [$w cget -menu]
	set last [$menu index last]
	set types {}

	if {[string compare $last "none"] != 0} {
	    for {set idx 0} {$idx <= $last} {incr idx} {
		lappend types [$menu type $idx]
		foreach configSet [$menu entryconfigure $idx] {
		    set default [lindex $configSet 3]
		    set current [lindex $configSet 4]
		    if {[string compare $default $current] != 0} {
			set opt [lindex $configSet 0]
			set data($menu,$idx$opt) $current
		    }
		}
	    }
	}

	set data($menu:types) $types
    }
}

#------------------------------------------------------------------------------
# tablelist::restoreEditData
#
# Restores some data of the edit window associated with the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::restoreEditData win {
    upvar ::tablelist::ns${win}::data data
    set w $data(bodyFrEd)
    set entry $data(editFocus)
    set class [winfo class $w]
    set isText [expr {[string compare $class "Text"] == 0 ||
		      [string compare $class "Ctext"] == 0}]
    set isMentry [expr {[string compare $class "Mentry"] == 0}]
    set isIncrDateTimeWidget [regexp {^(Date.+|Time.+)$} $class]

    #
    # Miscellaneous data
    #
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    if {[string length $editWin($name-putTextCmd)] != 0} {
	eval [strMap {"%W" "$w"  "%T" "$data(editText)"} \
	      $editWin($name-putTextCmd)]
    }
    if {[string length $editWin($name-putListCmd)] != 0 &&
	[string length $data(editList)] != 0} {
	eval [strMap {"%W" "$w"  "%L" "$data(editList)"} \
	      $editWin($name-putListCmd)]
    }
    if {[string length $editWin($name-selectCmd)] != 0 &&
	[set idx [lsearch -exact $data(editList) $data(editText)]] >= 0} {
	eval [strMap {"%W" "$w"  "%I" "$idx"} $editWin($name-selectCmd)]
    }
    if {$isText} {
	$w mark set insert $data(editPos)
	if {[llength $data(textSelRanges)] != 0} {
	    eval [list $w tag add sel] $data(textSelRanges)
	}
    } elseif {$editWin($name-isEntryLike)} {
	$entry icursor $data(editPos)
	if {$data(entryHadSel)} {
	    $entry selection range $data(entrySelFrom) $data(entrySelTo)
	}
    }
    if {$data(editHadFocus)} {
	focus $entry
    }

    #
    # Configuration options and widget callbacks
    #
    restoreEditConfigOpts $w
    if {[info exists ::wcb::version] &&
	$editWin($name-isEntryLike) && !$isMentry} {
	set wcbOptList {insert delete motion}
	if {$isText} {
	    lappend wcbOptList selset selclear
	    if {$::wcb::version >= 3.2} {
		lappend wcbOptList replace
	    }
	}
	foreach when {before after} {
	    foreach opt $wcbOptList {
		eval [list ::wcb::callback $entry $when $opt] \
		     $data(entryCb-$when-$opt)
	    }
	}
    }

    #
    # If the edit window is a datefield, dateentry, timefield, or timeentry
    # widget then restore its text here, because otherwise it would be
    # overridden when the above invocation of restoreEditConfigOpts sets
    # the widget's -format option.  Note that this is a special case; in
    # general we must restore the text BEFORE the configuration options.
    #
    if {$isIncrDateTimeWidget} {
	eval [strMap {"%W" "$w"  "%T" "$data(editText)"} \
	      $editWin($name-putTextCmd)]
    }
}

#------------------------------------------------------------------------------
# tablelist::restoreEditConfigOpts
#
# Restores the non-default values of the configuration options of the edit
# window w associated with a tablelist widget, as well as those of its
# descendants.
#------------------------------------------------------------------------------
proc tablelist::restoreEditConfigOpts w {
    regexp {^(.+)\.body\.f\.(e.*)$} $w dummy win tail
    upvar ::tablelist::ns${win}::data data
    set isMentry [expr {[string compare [winfo class $w] "Mentry"] == 0}]

    foreach name [array names data $tail-*] {
	set opt [string range $name [string last "-" $name] end]
	if {!$isMentry || [string compare $opt "-body"] != 0} {
	    $w configure $opt $data($name)
	}
	unset data($name)
    }

    foreach c [winfo children $w] {
	restoreEditConfigOpts $c
    }

    if {[string match "*Menubutton" [winfo class $w]]} {
	set menu [$w cget -menu]
	foreach type $data($menu:types) {
	    $menu add $type
	}
	unset data($menu:types)

	foreach name [array names data $menu,*] {
	    regexp {^.+,(.+)(-.+)$} $name dummy idx opt
	    $menu entryconfigure $idx $opt $data($name)
	    unset data($name)
	}
    }
}

#
# Private procedures used in bindings related to interactive cell editing
# =======================================================================
#

#------------------------------------------------------------------------------
# tablelist::defineTablelistEdit
#
# Defines the bindings for the binding tag TablelistEdit.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistEdit {} {
    #
    # Get the supported modifier keys in the set {Alt, Meta, Command} on
    # the current windowing system ("x11", "win32", "classic", or "aqua")
    #
    variable winSys
    switch $winSys {
	x11	{ set modList {Alt Meta} }
	win32	{ set modList {Alt} }
	classic -
	aqua	{ set modList {Command} }
    }

    #
    # Define some bindings for the binding tag TablelistEdit
    #
    bind TablelistEdit <Button-1> {
	#
	# Very short left-clicks on the tablelist's body are sometimes
	# unexpectedly propagated to the edit window just created - make
	# sure they won't be handled by the latter's default bindings
	#
	if {$tablelist::priv(justReleased)} {
	    break
	}

	set tablelist::priv(clickedInEditWin) 1
	focus %W
    }
    bind TablelistEdit <ButtonRelease-1> {
	if {%X >= 0} {				;# i.e., no generated event
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}

	    set tablelist::priv(x) ""
	    set tablelist::priv(y) ""
	    after cancel $tablelist::priv(afterId)
	    set tablelist::priv(afterId) ""
	    set tablelist::priv(justReleased) 1
	    after 100 [list set tablelist::priv(justReleased) 0]
	    set tablelist::priv(releasedInEditWin) 1
	    if {!$tablelist::priv(clickedInEditWin)} {
		if {$tablelist::priv(justClicked)} {
		    tablelist::moveOrActivate $tablelist::W \
			$tablelist::priv(row) $tablelist::priv(col) 1
		} else {
		    tablelist::moveOrActivate $tablelist::W \
			[$tablelist::W nearest       $tablelist::y] \
			[$tablelist::W nearestcolumn $tablelist::x] \
			[expr {$tablelist::x >= 0 &&
			       $tablelist::x < [winfo width $tablelist::W] &&
			       $tablelist::y >= [winfo y $tablelist::W.body] &&
			       $tablelist::y < [winfo height $tablelist::W]}]
		}
	    }
	    after 100 [list tablelist::condEvalInvokeCmd $tablelist::W]
	}
    }
    bind TablelistEdit <Control-i>    { tablelist::insertChar %W "\t" }
    bind TablelistEdit <Control-j>    { tablelist::insertChar %W "\n" }
    bind TablelistEdit <Escape>       { tablelist::cancelEditing %W }
    foreach key {Return KP_Enter} {
	bind TablelistEdit <$key> {
	    if {[string compare [winfo class %W] "Text"] == 0 ||
		[string compare [winfo class %W] "Ctext"] == 0} {
		tablelist::insertChar %W "\n"
	    } else {
		tablelist::finishEditing %W
	    }
	}
	bind TablelistEdit <Control-$key> {
	    tablelist::finishEditing %W
	}
    }
    bind TablelistEdit <Tab>	      { tablelist::goToNextPrevCell %W  1 }
    bind TablelistEdit <Shift-Tab>    { tablelist::goToNextPrevCell %W -1 }
    bind TablelistEdit <<PrevWindow>> { tablelist::goToNextPrevCell %W -1 }
    foreach modifier $modList {
	bind TablelistEdit <$modifier-Left> {
	    tablelist::goLeftRight %W -1
	}
	bind TablelistEdit <$modifier-Right> {
	    tablelist::goLeftRight %W 1
	}
	bind TablelistEdit <$modifier-Up> {
	    tablelist::goUpDown %W -1
	}
	bind TablelistEdit <$modifier-Down> {
	    tablelist::goUpDown %W 1
	}
	bind TablelistEdit <$modifier-Prior> {
	    tablelist::goToPriorNextPage %W -1
	}
	bind TablelistEdit <$modifier-Next> {
	    tablelist::goToPriorNextPage %W 1
	}
	bind TablelistEdit <$modifier-Home> {
	    tablelist::goToNextPrevCell %W 1 0 -1
	}
	bind TablelistEdit <$modifier-End> {
	    tablelist::goToNextPrevCell %W -1 0 0
	}
    }
    foreach direction {Left Right} amount {-1 1} {
	bind TablelistEdit <$direction> [format {
	    if {![tablelist::isKeyReserved %%W %%K]} {
		tablelist::goLeftRight %%W %d
	    }
	} $amount]
    }
    foreach direction {Up Down} amount {-1 1} {
	bind TablelistEdit <$direction> [format {
	    if {![tablelist::isKeyReserved %%W %%K]} {
		tablelist::goUpDown %%W %d
	    }
	} $amount]
    }
    foreach page {Prior Next} amount {-1 1} {
	bind TablelistEdit <$page> [format {
	    if {![tablelist::isKeyReserved %%W %%K]} {
		tablelist::goToPriorNextPage %%W %d
	    }
	} $amount]
    }
    bind TablelistEdit <Control-Home> {
	if {![tablelist::isKeyReserved %W Control-Home]} {
	    tablelist::goToNextPrevCell %W 1 0 -1
	}
    }
    bind TablelistEdit <Control-End> {
	if {![tablelist::isKeyReserved %W Control-End]} {
	    tablelist::goToNextPrevCell %W -1 0 0
	}
    }
    foreach pattern {Tab Shift-Tab ISO_Left_Tab hpBackTab} {
	catch {
	    foreach modifier {Control Meta} {
		bind TablelistEdit <$modifier-$pattern> [format {
		    mwutil::processTraversal %%W Tablelist <%s>
		} $pattern]
	    }
	}
    }
    bind TablelistEdit <FocusIn> {
	set tablelist::W [tablelist::getTablelistPath %W]
	set tablelist::ns${tablelist::W}::data(editFocus) %W
    }

    #
    # Define some emacs-like key bindings for the binding tag TablelistEdit
    #
    foreach pattern {Meta-b Meta-f} amount {-1 1} {
	bind TablelistEdit <$pattern> [format {
	    if {!$tk_strictMotif && ![tablelist::isKeyReserved %%W %s]} {
		tablelist::goLeftRight %%W %d
	    }
	} $pattern $amount]
    }
    foreach pattern {Control-p Control-n} amount {-1 1} {
	bind TablelistEdit <$pattern> [format {
	    if {!$tk_strictMotif && ![tablelist::isKeyReserved %%W %s]} {
		tablelist::goUpDown %%W %d
	    }
	} $pattern $amount]
    }
    bind TablelistEdit <Meta-less> {
	if {!$tk_strictMotif &&
	    ![tablelist::isKeyReserved %W Meta-less]} {
	    tablelist::goToNextPrevCell %W 1 0 -1
	}
    }
    bind TablelistEdit <Meta-greater> {
	if {!$tk_strictMotif &&
	    ![tablelist::isKeyReserved %W Meta-greater]} {
	    tablelist::goToNextPrevCell %W -1 0 0
	}
    }

    #
    # Define some bindings for the binding tag TablelistEdit that
    # propagate the mousewheel events to the tablelist's body
    #
    catch {
	bind TablelistEdit <MouseWheel> {
	    if {![tablelist::hasMouseWheelBindings %W] &&
		![tablelist::isComboTopMapped %W]} {
		tablelist::genMouseWheelEvent \
		    [[tablelist::getTablelistPath %W] bodypath] %D
	    }
	}
	bind TablelistEdit <Option-MouseWheel> {
	    if {![tablelist::hasMouseWheelBindings %W] &&
		![tablelist::isComboTopMapped %W]} {
		tablelist::genOptionMouseWheelEvent \
		    [[tablelist::getTablelistPath %W] bodypath] %D
	    }
	}
    }
    foreach detail {4 5} {
	bind TablelistEdit <Button-$detail> [format {
	    if {![tablelist::hasMouseWheelBindings %%W] &&
		![tablelist::isComboTopMapped %%W]} {
		event generate \
		    [[tablelist::getTablelistPath %%W] bodypath] <Button-%s>
	    }
	} $detail]
    }
}

#------------------------------------------------------------------------------
# tablelist::insertChar
#
# Inserts the string str ("\t" or "\n") into the entry-like widget w at the
# point of the insertion cursor.
#------------------------------------------------------------------------------
proc tablelist::insertChar {w str} {
    set class [winfo class $w]
    if {[string compare $class "Text"] == 0 ||
	[string compare $class "Ctext"] == 0} {
	if {[string compare $str "\n"] == 0} {
	    eval [strMap {"%W" "$w"} [bind Text <Return>]]
	} else {
	    eval [strMap {"%W" "$w"} [bind Text <Control-i>]]
	}
	return -code break ""
    } elseif {[regexp {^(T?Entry|TCombobox|T?Spinbox)$} $class]} {
	if {[string match "T*" $class]} {
	    if {[string length [info procs "::ttk::entry::Insert"]] != 0} {
		ttk::entry::Insert $w $str
	    } else {
		tile::entry::Insert $w $str
	    }
	} elseif {[string length [info procs "::tk::EntryInsert"]] != 0} {
	    tk::EntryInsert $w $str
	} else {
	    tkEntryInsert $w $str
	}
	return -code break ""
    }
}

#------------------------------------------------------------------------------
# tablelist::cancelEditing
#
# Invokes the doCancelEditing procedure.
#------------------------------------------------------------------------------
proc tablelist::cancelEditing w {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(sourceRow)]} {	;# move operation in progress
	return ""
    }

    doCancelEditing $win
    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::finishEditing
#
# Invokes the doFinishEditing procedure.
#------------------------------------------------------------------------------
proc tablelist::finishEditing w {
    if {[isComboTopMapped $w]} {
	return ""
    }

    doFinishEditing [getTablelistPath $w]
    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::goToNextPrevCell
#
# Moves the edit window into the next or previous editable cell different from
# the one indicated by the given row and column, if there is such a cell.
#------------------------------------------------------------------------------
proc tablelist::goToNextPrevCell {w amount args} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    variable winSys
    if {[string compare $winSys "aqua"] == 0 &&
	([string length $::tk::Priv(postedMb)] != 0 ||
	 [string length $::tk::Priv(popup)] != 0)} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    if {[llength $args] == 0} {
	set row $data(editRow)
	set col $data(editCol)
	set cmd condChangeSelection
    } else {
	foreach {row col} $args {}
	set cmd changeSelection
    }

    if {![doFinishEditing $win]} {
	return ""
    }

    set oldRow $row
    set oldCol $col

    while 1 {
	incr col $amount
	if {$col < 0} {
	    incr row $amount
	    if {$row < 0} {
		set row $data(lastRow)
	    }
	    set col $data(lastCol)
	} elseif {$col > $data(lastCol)} {
	    incr row $amount
	    if {$row > $data(lastRow)} {
		set row 0
	    }
	    set col 0
	}

	if {$row == $oldRow && $col == $oldCol} {
	    return -code break ""
	} elseif {[isRowViewable $win $row] && !$data($col-hide) &&
		  [isCellEditable $win $row $col]} {
	    doEditCell $win $row $col 0 $cmd
	    return -code break ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::goLeftRight
#
# Moves the edit window into the previous or next editable cell of the current
# row if the cell being edited is not the first/last editable one within that
# row.
#------------------------------------------------------------------------------
proc tablelist::goLeftRight {w amount} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    set row $data(editRow)
    set col $data(editCol)

    if {![doFinishEditing $win]} {
	return ""
    }

    while 1 {
	incr col $amount
	if {$col < 0 || $col > $data(lastCol)} {
	    return -code break ""
	} elseif {!$data($col-hide) && [isCellEditable $win $row $col]} {
	    doEditCell $win $row $col 0 condChangeSelection
	    return -code break ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::goUpDown
#
# Invokes the goToPrevNextLine procedure.
#------------------------------------------------------------------------------
proc tablelist::goUpDown {w amount} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    goToPrevNextLine $w $amount $data(editRow) $data(editCol) \
	condChangeSelection
    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::goToPrevNextLine
#
# Moves the edit window into the last or first editable cell that is located in
# the specified column and has a row index less/greater than the given one, if
# there is such a cell.
#------------------------------------------------------------------------------
proc tablelist::goToPrevNextLine {w amount row col cmd} {
    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    if {![doFinishEditing $win]} {
	return ""
    }

    while 1 {
	incr row $amount
	if {$row < 0 || $row > $data(lastRow)} {
	    return 0
	} elseif {[isRowViewable $win $row] &&
		  [isCellEditable $win $row $col]} {
	    doEditCell $win $row $col 0 $cmd
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::goToPriorNextPage
#
# Moves the edit window up or down by one page within the current column if the
# cell being edited is not the first/last editable one within that column.
#------------------------------------------------------------------------------
proc tablelist::goToPriorNextPage {w amount} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    #
    # Check whether there is any viewable editable cell
    # above/below the current one, in the same column
    #
    set row $data(editRow)
    set col $data(editCol)
    while 1 {
	incr row $amount
	if {$row < 0 || $row > $data(lastRow)} {
	    return -code break ""
	} elseif {[isRowViewable $win $row] &&
		  [isCellEditable $win $row $col]} {
	    break
	}
    }

    #
    # Scroll up/down the view by one page and get the corresponding row index
    #
    set row $data(editRow)
    seeRow $win $row
    set bbox [bboxSubCmd $win $row]
    yviewSubCmd $win [list scroll $amount pages]
    set newRow [rowIndex $win @0,[lindex $bbox 1] 0]

    if {$amount < 0} {
	if {$newRow < $row} {
	    if {![goToPrevNextLine $w -1 [expr {$newRow + 1}] $col \
		  changeSelection]} {
		goToPrevNextLine $w 1 $newRow $col changeSelection
	    }
	} else {
	    goToPrevNextLine $w 1 -1 $col changeSelection
	}
    } else {
	if {$newRow > $row} {
	    if {![goToPrevNextLine $w 1 [expr {$newRow - 1}] $col \
		  changeSelection]} {
		goToPrevNextLine $w -1 $newRow $col changeSelection
	    }
	} else {
	    goToPrevNextLine $w -1 $data(itemCount) $col changeSelection
	}
    }

    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::genMouseWheelEvent
#
# Generates a <MouseWheel> event with the given delta on the widget w.
#------------------------------------------------------------------------------
proc tablelist::genMouseWheelEvent {w delta} {
    set focus [focus -displayof $w]
    focus $w
    event generate $w <MouseWheel> -delta $delta
    focus $focus
}

#------------------------------------------------------------------------------
# tablelist::genOptionMouseWheelEvent
#
# Generates an <Option-MouseWheel> event with the given delta on the widget w.
#------------------------------------------------------------------------------
proc tablelist::genOptionMouseWheelEvent {w delta} {
    set focus [focus -displayof $w]
    focus $w
    event generate $w <Option-MouseWheel> -delta $delta
    focus $focus
}

#------------------------------------------------------------------------------
# tablelist::isKeyReserved
#
# Checks whether the given keysym is used in the standard binding scripts
# associated with the widget w, which is assumed to be the edit window or one
# of its descendants.
#------------------------------------------------------------------------------
proc tablelist::isKeyReserved {w keySym} {
    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    return [expr {[lsearch -exact $editWin($name-reservedKeys) $keySym] >= 0}]
}

#------------------------------------------------------------------------------
# tablelist::hasMouseWheelBindings
#
# Checks whether the given widget, which is assumed to be the edit window or
# one of its descendants, has mouse wheel bindings.
#------------------------------------------------------------------------------
proc tablelist::hasMouseWheelBindings w {
    if {[regexp {^(Text|Ctext|TCombobox|TSpinbox)$} [winfo class $w]]} {
	return 1
    } else {
	set bindTags [bindtags $w]
	return [expr {([lsearch -exact $bindTags "MentryDateTime"] >= 0 ||
		       [lsearch -exact $bindTags "MentryMeridian"] >= 0 ||
		       [lsearch -exact $bindTags "MentryIPAddr"] >= 0 ||
		       [lsearch -exact $bindTags "MentryIPv6Addr"] >= 0) &&
		      ($mentry::version >= 3.2)}]
    }
}

#------------------------------------------------------------------------------
# tablelist::isComboTopMapped
#
# Checks whether the given widget is a component of an Oakley combobox having
# its toplevel child mapped.  This is needed in our binding scripts to make
# sure that the interactive cell editing won't be terminated prematurely,
# because Bryan Oakley's combobox keeps the focus on its entry child even if
# its toplevel component is mapped.
#------------------------------------------------------------------------------
proc tablelist::isComboTopMapped w {
    set par [winfo parent $w]
    if {[string compare [winfo class $par] "Combobox"] == 0 &&
	[winfo exists $par.top] && [winfo ismapped $par.top]} {
	return 1
    } else {
	return 0
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistImages.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
#==============================================================================
# Contains procedures that create various bitmap and photo images.  The
# argument w specifies a canvas displaying a sort arrow, while the argument win
# stands for a tablelist widget.
#
# Copyright (c) 2006-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#------------------------------------------------------------------------------
# tablelist::flat5x3Arrows
#------------------------------------------------------------------------------
proc tablelist::flat5x3Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp5x3_width 5
#define triangleUp5x3_height 3
static unsigned char triangleUp5x3_bits[] = {
   0x04, 0x0e, 0x1f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn5x3_width 5
#define triangleDn5x3_height 3
static unsigned char triangleDn5x3_bits[] = {
   0x1f, 0x0e, 0x04};
"
}

#------------------------------------------------------------------------------
# tablelist::flat5x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat5x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp5x4_width 5
#define triangleUp5x4_height 4
static unsigned char triangleUp5x4_bits[] = {
   0x04, 0x0e, 0x1f, 0x1f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn5x4_width 5
#define triangleDn5x4_height 4
static unsigned char triangleDn5x4_bits[] = {
   0x1f, 0x1f, 0x0e, 0x04};
"
}

#------------------------------------------------------------------------------
# tablelist::flat6x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat6x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp6x4_width 6
#define triangleUp6x4_height 4
static unsigned char triangleUp6x4_bits[] = {
   0x0c, 0x1e, 0x3f, 0x3f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn6x4_width 6
#define triangleDn6x4_height 4
static unsigned char triangleDn7x4_bits[] = {
   0x3f, 0x3f, 0x1e, 0x0c};
"
}

#------------------------------------------------------------------------------
# tablelist::flat7x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat7x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x4_width 7
#define triangleUp7x4_height 4
static unsigned char triangleUp7x4_bits[] = {
   0x08, 0x1c, 0x3e, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x4_width 7
#define triangleDn7x4_height 4
static unsigned char triangleDn7x4_bits[] = {
   0x7f, 0x3e, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flat7x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flat7x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x5_width 7
#define triangleUp7x5_height 5
static unsigned char triangleUp7x5_bits[] = {
   0x08, 0x1c, 0x3e, 0x7f, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x5_width 7
#define triangleDn7x5_height 5
static unsigned char triangleDn7x5_bits[] = {
   0x7f, 0x7f, 0x3e, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flat7x7Arrows
#------------------------------------------------------------------------------
proc tablelist::flat7x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x7_width 7
#define triangleUp7x7_height 7
static unsigned char triangleUp7x7_bits[] = {
   0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x7_width 7
#define triangleDn7x7_height 7
static unsigned char triangleDn7x7_bits[] = {
   0x7f, 0x7f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flat8x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat8x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp8x4_width 8
#define triangleUp8x4_height 4
static unsigned char triangleUp8x4_bits[] = {
   0x18, 0x3c, 0x7e, 0xff};
"
    image create bitmap triangleDn$w -data "
#define triangleDn8x4_width 8
#define triangleDn8x4_height 4
static unsigned char triangleDn8x4_bits[] = {
   0xff, 0x7e, 0x3c, 0x18};
"
}

#------------------------------------------------------------------------------
# tablelist::flat8x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flat8x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp8x5_width 8
#define triangleUp8x5_height 5
static unsigned char triangleUp8x5_bits[] = {
   0x18, 0x3c, 0x7e, 0xff, 0xff};
"
    image create bitmap triangleDn$w -data "
#define triangleDn8x5_width 8
#define triangleDn8x5_height 5
static unsigned char triangleDn8x5_bits[] = {
   0xff, 0xff, 0x7e, 0x3c, 0x18};
"
}

#------------------------------------------------------------------------------
# tablelist::flat9x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flat9x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x5_width 9
#define triangleUp9x5_height 5
static unsigned char triangleUp9x5_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x5_width 9
#define triangleDn9x5_height 5
static unsigned char triangleDn9x5_bits[] = {
   0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flat9x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flat9x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x6_width 9
#define triangleUp9x6_height 6
static unsigned char triangleUp9x6_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01, 0xff, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x6_width 9
#define triangleDn9x6_height 6
static unsigned char triangleDn9x6_bits[] = {
   0xff, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flat11x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flat11x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp11x6_width 11
#define triangleUp11x6_height 6
static unsigned char triangleUp11x6_bits[] = {
   0x20, 0x00, 0x70, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xff, 0x07};
"
    image create bitmap triangleDn$w -data "
#define triangleDn11x6_width 11
#define triangleDn11x6_height 6
static unsigned char triangleDn11x6_bits[] = {
   0xff, 0x07, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00, 0x20, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flat15x8Arrows
#------------------------------------------------------------------------------
proc tablelist::flat15x8Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp15x8_width 15
#define triangleUp15x8_height 8
static unsigned char triangleUp15x8_bits[] = {
   0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
   0xfe, 0x3f, 0xff, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn15x8_width 15
#define triangleDn15x8_height 8
static unsigned char triangleDn15x8_bits[] = {
   0xff, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03,
   0xc0, 0x01, 0x80, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle7x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle7x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x4_width 7
#define triangleUp7x4_height 4
static unsigned char triangleUp7x4_bits[] = {
   0x08, 0x1c, 0x36, 0x63};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x4_width 7
#define triangleDn7x4_height 4
static unsigned char triangleDn7x4_bits[] = {
   0x63, 0x36, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle7x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle7x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x5_width 7
#define triangleUp7x5_height 5
static unsigned char triangleUp7x5_bits[] = {
   0x08, 0x1c, 0x3e, 0x77, 0x63};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x5_width 7
#define triangleDn7x5_height 5
static unsigned char triangleDn7x5_bits[] = {
   0x63, 0x77, 0x3e, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle9x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle9x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x5_width 9
#define triangleUp9x5_height 5
static unsigned char triangleUp9x5_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x6c, 0x00, 0xc6, 0x00, 0x83, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x5_width 9
#define triangleDn9x5_height 5
static unsigned char triangleDn9x5_bits[] = {
   0x83, 0x01, 0xc6, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle9x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle9x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x6_width 9
#define triangleUp9x6_height 6
static unsigned char triangleUp9x6_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xee, 0x00, 0xc7, 0x01, 0x83, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x6_width 9
#define triangleDn9x6_height 6
static unsigned char triangleDn9x6_bits[] = {
   0x83, 0x01, 0xc7, 0x01, 0xee, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle9x7Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle9x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x7_width 9
#define triangleUp9x7_height 7
static unsigned char triangleUp9x7_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xef, 0x01, 0xc7, 0x01,
   0x83, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x7_width 9
#define triangleDn9x7_height 7
static unsigned char triangleDn9x7_bits[] = {
   0x83, 0x01, 0xc7, 0x01, 0xef, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00,
   0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle10x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle10x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp10x6_width 10
#define triangleUp10x6_height 6
static unsigned char triangleUp10x6_bits[] = {
   0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xce, 0x01, 0x87, 0x03, 0x03, 0x03};
"
    image create bitmap triangleDn$w -data "
#define triangleDn10x6_width 10
#define triangleDn10x6_height 6
static unsigned char triangleDn10x6_bits[] = {
   0x03, 0x03, 0x87, 0x03, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x30, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle10x7Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle10x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp10x7_width 10
#define triangleUp10x7_height 7
static unsigned char triangleUp10x7_bits[] = {
   0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xfe, 0x01, 0xcf, 0x03, 0x87, 0x03,
   0x03, 0x03};
"
    image create bitmap triangleDn$w -data "
#define triangleDn10x7_width 10
#define triangleDn10x7_height 7
static unsigned char triangleDn10x6_bits[] = {
   0x03, 0x03, 0x87, 0x03, 0xcf, 0x03, 0xfe, 0x01, 0xfc, 0x00, 0x78, 0x00,
   0x30, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle11x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle11x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp11x6_width 11
#define triangleUp11x6_height 6
static unsigned char triangleUp11x6_bits[] = {
   0x20, 0x00, 0x70, 0x00, 0xd8, 0x00, 0x8c, 0x01, 0x06, 0x03, 0x03, 0x06};
"
    image create bitmap triangleDn$w -data "
#define triangleDn11x6_width 11
#define triangleDn11x6_height 6
static unsigned char triangleDn11x6_bits[] = {
   0x03, 0x06, 0x06, 0x03, 0x8c, 0x01, 0xd8, 0x00, 0x70, 0x00, 0x20, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle15x8Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle15x8Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp15x8_width 15
#define triangleUp15x8_height 8
static unsigned char triangleUp15x8_bits[] = {
   0x80, 0x00, 0xc0, 0x01, 0x60, 0x03, 0x30, 0x06, 0x18, 0x0c, 0x0c, 0x18,
   0x06, 0x30, 0x03, 0x60};
"
    image create bitmap triangleDn$w -data "
#define triangleDn15x8_width 15
#define triangleDn15x8_height 8
static unsigned char triangleDn15x8_bits[] = {
   0x03, 0x60, 0x06, 0x30, 0x0c, 0x18, 0x18, 0x0c, 0x30, 0x06, 0x60, 0x03,
   0xc0, 0x01, 0x80, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::photo7x4Arrows
#------------------------------------------------------------------------------
proc tablelist::photo7x4Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhBwAEAIQRAAAAADxZbDxeckNfb0BidF6IoWGWtlabwIexxZq2xYbI65HL7LXd8rri9MPk
9cTj9Mrm9f///////////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAHAAQAAAUS4CcSYikcRRkYypJ8A9IwD+SEADs=
"
    triangleDn$w put "
R0lGODlhBwAEAIQQAAAAADxeclKLq2KauWes03CpxnKrynOy2IO62ZXG4JrH4JrL5pnQ7qbY87Pb
8cTj9P///////////////////////////////////////////////////////////////yH5BAEK
AAAALAAAAAAHAAQAAAUSYDAUBpIogHAwzgO8ROO+70KHADs=
"
}

#------------------------------------------------------------------------------
# tablelist::photo7x7Arrows
#------------------------------------------------------------------------------
proc tablelist::photo7x7Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA7DAAAOwwHHb6hk
AAAAGnRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAABCSURBVBhXXY4BCgAgCAP9
T//R9/Ryc+ZEHCyb40CB3D1n6OAZuQOKi9klPhUsjNJ6VwUp+tOLopOGNkXncToWw6IPjiowJNyp
gu8AAAAASUVORK5CYII=
"
    triangleDn$w put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwwAADsMBx2+oZAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAP0lE
QVQYV22LgQ0AIAjD9g//yD1ejoBoFpRkISsUPsMzPwkOIcARmJlvKMGIJq9jt+Uem51Wscfe1hkq
8VAdWKBfMCRjQcZZAAAAAElFTkSuQmCC
"
}

#------------------------------------------------------------------------------
# tablelist::photo9x5Arrows
#------------------------------------------------------------------------------
proc tablelist::photo9x5Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhCQAFAIQTAAAAADxeckBidGaJmlabwG6mw4exxZy9z4bI647M7JvS76HV8KjX8a3a8rPc
8rLe87jf9Lzh9MPk9f///////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAJAAUAAAUZ4Cd+wWgGhGCSBKIMY1AkSwMdpPEwTiT9IQA7
"
    triangleDn$w put "
R0lGODlhCQAFAIQSAAAAADxeck90imuUrGKauW2jwWes036xzXOy2IO83YO83o++2JrH4JrK5rPZ
7rPZ77TZ7sTj9P///////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAJAAUAAAUaYECMxbEwzCcgSNJA0ScPSuPEsmw8eC43vhAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::photo11x6Arrows
#------------------------------------------------------------------------------
proc tablelist::photo11x6Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhCwAGAKUjAAAAADJdfDJefDFefjRffDhhfC9njDNrjThtjj5xkUJykWuXs2Ogw2ukxHKp
yHusyZrD2o7M7JfQ7qDE2qfH2arJ2aPQ6aLU76Td+6/h/bDi/rrj+bjm/rrn/8Pm+sLr/8Ps/8ro
+szu////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAALAAYAAAYqwJ9Q
WBgahQTF4ohMPCyQYwDhuHA2k6Hg0JBkOh8P5TcwMCIYTQckClWCADs=
"
    triangleDn$w put "
R0lGODlhCwAGAKUkAAAAADl1ml+DnlaRtWGZu2ievXaet2+gvXekvmKfw32owXu314Kqwoiswoey
yo21zIa+3JC2zZ26y5DB3ZjG34fE5ZHJ55/J4ZrN6KTC1KjN4qLb+azf+rrV5rDi/rrn/7/m+8Ps
/8vu/9Pw////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAALAAYAAAYqQEFg
QCgcEApGQ/IzJBaQCeWi6fyujsrG8wmNruCHhfMRgc8RDOjMzrCDADs=
"
}

#------------------------------------------------------------------------------
# tablelist::photo15x8Arrows
#------------------------------------------------------------------------------
proc tablelist::photo15x8Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhDwAIAKU/AAAAAB1YfjJefy1pjjVmhjJrjzppiD1qiTVtkTpwkTxwkT18oUFsikRuilKP
s16Rr1aStFyUtWeHnGKKo2CWtXGhvV6dwnOy1Ha02Hu01YKovommuI2xxIC314S31JGyx5W1x5S3
zJi2yJG915nE2p/F24fD44/I5o7K65bF4JbN7ZjM6J/P6Z3Q7Z7X9abJ3anN4KfS6q/U6azV66zX
76fa9qzb9and+bLb8Lne8rHg+rLi+7fi+bnk+73l+v///yH5BAEKAD8ALAAAAAAPAAgAAAZJwJ9w
+JMQj8QGYYI8NhSPiqYpZCQontSI0zwgIp2WjUb6HA8FSEZV0/FwJdDQMHBcUK7brufLvUQ/AgEL
FhgmJyssMTMyMCEbQQA7
"
    triangleDn$w put "
R0lGODlhDwAIAKU/AAAAACdjiUBtjkKBpkaGqlWFpVaUuFyav2SVtGGdv2Cew2ehwm2jw26tz3Ok
wXOmw3amwnuow3ioxH6pw3Gv0nSz13iz03611ICsxYOux4mtwomxyI2yyIK00oa41Yy815KvwZm5
zJO+2JjC2Z/D2J7E2obC4o/I5o3J6pTM65jM6J/P6ZzP657X9avH2anP5afS6q7U6azV66fa9qnZ
9Knd+bjV5rrc8bHg+rLi+7fi+b/g8rnk+7zl+sXh8v///yH5BAEKAD8ALAAAAAAPAAgAAAZIQEFg
YEgsGA8JJrPhaEC/AkHRsFw8H9GoRHL9vohDxXRSrWCymO3LdlBQrVqO1/Ox7xBLaobT7e6AERcs
NDeAhxMdL4eMIYxBADs=
"
}

#------------------------------------------------------------------------------
# tablelist::sunken8x7Arrows
#------------------------------------------------------------------------------
proc tablelist::sunken8x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp8x7_width 8
#define triangleUp8x7_height 7
static unsigned char triangleUp8x7_bits[] = {
   0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0xff, 0xff};
"
    image create bitmap darkLineUp$w -data "
#define darkLineUp8x7_width 8
#define darkLineUp8x7_height 7
static unsigned char darkLineUp8x7_bits[] = {
   0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x00};
"
    image create bitmap lightLineUp$w -data "
#define lightLineUp8x7_width 8
#define lightLineUp8x7_height 7
static unsigned char lightLineUp8x7_bits[] = {
   0x10, 0x30, 0x20, 0x60, 0x40, 0xc0, 0xff};
"
    image create bitmap triangleDn$w -data "
#define triangleDn8x7_width 8
#define triangleDn8x7_height 7
static unsigned char triangleDn8x7_bits[] = {
   0xff, 0xff, 0x7e, 0x7e, 0x3c, 0x3c, 0x18};
"
    image create bitmap darkLineDn$w -data "
#define darkLineDn8x7_width 8
#define darkLineDn8x7_height 7
static unsigned char darkLineDn8x7_bits[] = {
   0xff, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08};
"
    image create bitmap lightLineDn$w -data "
#define lightLineDn8x7_width 8
#define lightLineDn8x7_height 7
static unsigned char lightLineDn8x7_bits[] = {
   0x00, 0xc0, 0x40, 0x60, 0x20, 0x30, 0x10};
"
}

#------------------------------------------------------------------------------
# tablelist::sunken10x9Arrows
#------------------------------------------------------------------------------
proc tablelist::sunken10x9Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp10x9_width 10
#define triangleUp10x9_height 9
static unsigned char triangleUp10x9_bits[] = {
   0x30, 0x00, 0x78, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfe, 0x01,
   0xfe, 0x01, 0xff, 0x03, 0xff, 0x03};
"
    image create bitmap darkLineUp$w -data "
#define darkLineUp10x9_width 10
#define darkLineUp10x9_height 9
static unsigned char darkLineUp10x9_bits[] = {
   0x10, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x06, 0x00,
   0x02, 0x00, 0x03, 0x00, 0x00, 0x00};
"
    image create bitmap lightLineUp$w -data "
#define lightLineUp10x9_width 10
#define lightLineUp10x9_height 9
static unsigned char lightLineUp10x9_bits[] = {
   0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x80, 0x00, 0x80, 0x01,
   0x00, 0x01, 0x00, 0x03, 0xff, 0x03};
"
    image create bitmap triangleDn$w -data "
#define triangleDn10x9_width 10
#define triangleDn10x9_height 9
static unsigned char triangleDn10x9_bits[] = {
   0xff, 0x03, 0xff, 0x03, 0xfe, 0x01, 0xfe, 0x01, 0xfc, 0x00, 0xfc, 0x00,
   0x78, 0x00, 0x78, 0x00, 0x30, 0x00};
"
    image create bitmap darkLineDn$w -data "
#define darkLineDn10x9_width 10
#define darkLineDn10x9_height 9
static unsigned char darkLineDn10x9_bits[] = {
   0xff, 0x03, 0x03, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0c, 0x00,
   0x08, 0x00, 0x18, 0x00, 0x10, 0x00};
"
    image create bitmap lightLineDn$w -data "
#define lightLineDn10x9_width 10
#define lightLineDn10x9_height 9
static unsigned char lightLineDn10x9_bits[] = {
   0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0xc0, 0x00,
   0x40, 0x00, 0x60, 0x00, 0x20, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::sunken12x11Arrows
#------------------------------------------------------------------------------
proc tablelist::sunken12x11Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp12x11_width 12
#define triangleUp12x11_height 11
static unsigned char triangleUp12x11_bits[] = {
   0x60, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf8, 0x01, 0xf8, 0x01, 0xfc, 0x03,
   0xfc, 0x03, 0xfe, 0x07, 0xfe, 0x07, 0xff, 0x0f, 0xff, 0x0f};
"
    image create bitmap darkLineUp$w -data "
#define darkLineUp12x11_width 12
#define darkLineUp12x11_height 11
static unsigned char darkLineUp12x11_bits[] = {
   0x20, 0x00, 0x30, 0x00, 0x10, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0c, 0x00,
   0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00};
"
    image create bitmap lightLineUp$w -data "
#define lightLineUp12x11_width 12
#define lightLineUp12x11_height 11
static unsigned char lightLineUp12x11_bits[] = {
   0x40, 0x00, 0xc0, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x03,
   0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0c, 0xff, 0x0f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn12x11_width 12
#define triangleDn12x11_height 11
static unsigned char triangleDn12x11_bits[] = {
   0xff, 0x0f, 0xff, 0x0f, 0xfe, 0x07, 0xfe, 0x07, 0xfc, 0x03, 0xfc, 0x03,
   0xf8, 0x01, 0xf8, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0x60, 0x00};
"
    image create bitmap darkLineDn$w -data "
#define darkLineDn12x11_width 12
#define darkLineDn12x11_height 11
static unsigned char darkLineDn12x11_bits[] = {
   0xff, 0x0f, 0x03, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0c, 0x00,
   0x08, 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00};
"
    image create bitmap lightLineDn$w -data "
#define lightLineDn12x11_width 12
#define lightLineDn12x11_height 11
static unsigned char lightLineDn12x11_bits[] = {
   0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03,
   0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0xc0, 0x00, 0x40, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::createSortRankImgs
#------------------------------------------------------------------------------
proc tablelist::createSortRankImgs win {
    image create bitmap sortRank1$win -data "
#define sortRank1_width 4
#define sortRank1_height 6
static unsigned char sortRank1_bits[] = {
   0x04, 0x06, 0x04, 0x04, 0x04, 0x04};
"
    image create bitmap sortRank2$win -data "
#define sortRank2_width 4
#define sortRank2_height 6
static unsigned char sortRank2_bits[] = {
   0x06, 0x09, 0x08, 0x04, 0x02, 0x0f};
"
    image create bitmap sortRank3$win -data "
#define sortRank3_width 4
#define sortRank3_height 6
static unsigned char sortRank3_bits[] = {
   0x0f, 0x08, 0x06, 0x08, 0x09, 0x06};
"
    image create bitmap sortRank4$win -data "
#define sortRank4_width 4
#define sortRank4_height 6
static unsigned char sortRank4_bits[] = {
   0x04, 0x06, 0x05, 0x0f, 0x04, 0x04};
"
    image create bitmap sortRank5$win -data "
#define sortRank5_width 4
#define sortRank5_height 6
static unsigned char sortRank5_bits[] = {
   0x0f, 0x01, 0x07, 0x08, 0x09, 0x06};
"
    image create bitmap sortRank6$win -data "
#define sortRank6_width 4
#define sortRank6_height 6
static unsigned char sortRank6_bits[] = {
   0x06, 0x01, 0x07, 0x09, 0x09, 0x06};
"
    image create bitmap sortRank7$win -data "
#define sortRank7_width 4
#define sortRank7_height 6
static unsigned char sortRank7_bits[] = {
   0x0f, 0x08, 0x04, 0x04, 0x02, 0x02};
"
    image create bitmap sortRank8$win -data "
#define sortRank8_width 4
#define sortRank8_height 6
static unsigned char sortRank8_bits[] = {
   0x06, 0x09, 0x06, 0x09, 0x09, 0x06};
"
    image create bitmap sortRank9$win -data "
#define sortRank9_width 4
#define sortRank9_height 6
static unsigned char sortRank9_bits[] = {
   0x06, 0x09, 0x09, 0x0e, 0x08, 0x06};
"
}

#------------------------------------------------------------------------------
# tablelist::createCheckbuttonImgs
#------------------------------------------------------------------------------
proc tablelist::createCheckbuttonImgs {} {
    variable checkedImg [image create bitmap tablelist_checkedImg -data "
#define checked_width 9
#define checked_height 9
static unsigned char checked_bits[] = {
   0x00, 0x00, 0x80, 0x00, 0xc0, 0x00, 0xe2, 0x00, 0x76, 0x00, 0x3e, 0x00,
   0x1c, 0x00, 0x08, 0x00, 0x00, 0x00};
"]

    variable uncheckedImg [image create bitmap tablelist_uncheckedImg -data "
#define unchecked_width 9
#define unchecked_height 9
static unsigned char unchecked_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
"]
}

#------------------------------------------------------------------------------
# tablelist::adwaitaTreeImgs
#------------------------------------------------------------------------------
proc tablelist::adwaitaTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel
		  collapsedAct expandedAct collapsedSelAct expandedSelAct} {
	variable adwaita_${mode}Img \
		 [image create photo tablelist_adwaita_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_adwaita_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAS0lEQVQoz2NgGCgQRIwiJjS+GgMD
QzipmhgYGBhkCGnEpomVkEYmHOIwjUmkaMILWHCI/2ZgYHjCwMCwklib8GrApQmvBrIjl34AABCG
CT/IZJIxAAAAAElFTkSuQmCC
"
	tablelist_adwaita_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAVUlEQVQoz+3RsQmAMBQG4U/ENVI7
k5M4kSBuJThA6jQ2EUKIoKXgNY8f7qrHD+gQMD1wF+zQI+Yx5l2TsF6BQoo4GmHCVgYqoQ6bwR0B
c76vGD783BOQlRBaIgVX4QAAAABJRU5ErkJggg==
"
	tablelist_adwaita_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAT0lEQVQoz2NgGBDw////WGLUMaHx
df7//59CqiYGBgYGBUIasWliJaSRCYc4TGMRKZrwAhYc4r8ZGBgeMDIyziHWJrwacGnCq4HsyKUf
AADrxRtigikXoAAAAABJRU5ErkJggg==
"
	tablelist_adwaita_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAVElEQVQoz+3RsQ2AMAwF0XORSTIZ
DbuwAg2TMQnF0YRICAulReLq/9wY/gAItQLzwHaNiB0gABqcgJKMD2C7QEcv8AFuKIEpSFOrurQD
46nlw889ASlNI826HLaoAAAAAElFTkSuQmCC
"
	tablelist_adwaita_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAU0lEQVQoz8XRsQ2AMAwEwFO6bAPj
sAOjULID0yDYJi0LBIIRiC9fPlmW+SvTE7Ribg2lSte1YA3lFkwnfUaPJYLCN0HBhuEuKtgxRjZd
gtee+10OdDMKiEMkR3cAAAAASUVORK5CYII=
"
	tablelist_adwaita_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAWUlEQVQoz+3RoQ2AQBAF0UfAUM/V
QCsIBAXRz0kEVdDCScxegjgBkoRxP5kxu/yADgnbA3fGDj3OGBOGhlyw1KBGIjwaYcF6D1ok5JBy
7EekiNLbA40ffu4FEEUOYdYQ3mYAAAAASUVORK5CYII=
"
	tablelist_adwaita_collapsedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAPUlEQVQoz2NgGBDw////deRo+v//
//+d5Gj6TJLG/whAvMb/qODb////L2JTx0SN0CPbeWQFxE7aRy5NAQBViGDybBLtUAAAAABJRU5E
rkJggg==
"
	tablelist_adwaita_expandedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAMUlEQVQoz2NgGAUQ8P//f/v/xAF7
bBq/4VD8DUMDAY24NeDQSFgDFj/akxo4PEM4bgEyPobIeZ962wAAAABJRU5ErkJggg==
"
    } else {
	tablelist_adwaita_collapsedImg put "
R0lGODlhDQAOAMIGAAAAAIeHh4yMjJ2dnaioqK2trf///////yH5BAEKAAcALAAAAAANAA4AAAMd
eLrc/qdAFshUQdgZ8n5dNkChMIIep13VFbkwnAAAOw==
"
	tablelist_adwaita_expandedImg put "
R0lGODlhDQAOAKEDAAAAAIeHh4yMjP///yH5BAEKAAMALAAAAAANAA4AAAIWnI+py+0fopRJzCCW
jZnZ3gTPSJZNAQA7
"
	tablelist_adwaita_collapsedSelImg put "
R0lGODlhDQAOAKECAAAAAMzMzP///////yH5BAEKAAAALAAAAAANAA4AAAIXhI+pC8EY3Gtxxsou
Vlry+4Chl03maRQAOw==
"
	tablelist_adwaita_expandedSelImg put "
R0lGODlhDQAOAKECAAAAAMzMzP///////yH5BAEKAAAALAAAAAANAA4AAAIRhI+py+0fopRpUmXb
1a/73xQAOw==
"
	tablelist_adwaita_collapsedActImg put "
R0lGODlhDQAOAMIHAAAAADIyMjo6Ojs7O1hYWGtra3Nzc////yH5BAEKAAcALAAAAAANAA4AAAMd
eLrc/sdAFspUYdgZ8n5dIBBQOJYep13VFbkwnAAAOw==
"
	tablelist_adwaita_expandedActImg put "
R0lGODlhDQAOAKEDAAAAADIyMjo6Ov///yH5BAEKAAMALAAAAAANAA4AAAIWnI+py+0fopRJzCCW
jZnZ3gTPSJZNAQA7
"
	tablelist_adwaita_collapsedSelActImg put "
R0lGODlhDQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAANAA4AAAIXhI+pC8EY3Gtxxsou
Vlry+4Chl03maRQAOw==
"
	tablelist_adwaita_expandedSelActImg put "
R0lGODlhDQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAANAA4AAAIRhI+py+0fopRpUmXb
1a/73xQAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::ambianceTreeImgs
#------------------------------------------------------------------------------
proc tablelist::ambianceTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable ambiance_${mode}Img \
		 [image create photo tablelist_ambiance_${mode}Img]
    }

    tablelist_ambiance_collapsedImg put "
R0lGODlhEgAQAKUxAAAAADw7N9/Wxd/Wxt/WyODYyeLZyuHazeTdz+Pd0eTd0uXf0+Xf1efg1OXg
1ujh0+jg1Onj1+nj2Ork2O3m3Ozm3e7p4e/q4e7s5u/s6PHs5PHs5fHs5vHu6fPw6vTw6vTw6/bz
7vbz7/b07vb07/b08Pb08fj28/n49Pr59fr59vv5+Pv6+Pr6+vz6+fz7+v39/f//////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAahwJ9w
SCwWD4KkUnkwFjotmHQKa2UKxENmxXK5XmAva4VpCgWmEwqVSqna61NJMBSERKSSyRTYl0gjJHRn
Hx4dHiAgAYkeHh8fgz8CHJQcGhsBGxuVHJECFxcWAaOkAaAXnhUVFKoVAa2tnhMRErUSAbYRExOe
DxC/vwHAEA0PngoIycrLCAuRBwwG0tPUBg5mQgUJBAPd3gMECVhHS+XYQkEAOw==
"
    tablelist_ambiance_expandedImg put "
R0lGODlhEgAQAKUyAAAAADw7N9/Wxd/Wxt/WyODYyeLZyuHazeTdz+Pd0eTd0uXf0+Xf1efg1OXg
1ujh0+jg1Onj1+nj2Ork2O3m3Ozm3e7p4e/q4e7s5u/s6PHs5PHs5fHs5vHu6fPw6vTw6vTw6/bz
7vbz7/b07vb07/b08Pb08fj18fj28/n49Pr59fr59vv5+Pv6+Pr6+vz6+fz7+v39/f//////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAabwJ9w
SCwWD4KkUnkwFjqumHQac2UKxEOG1Xq9YGBvi4VpCgUmVCqlUq3aa1RJMBSERKSSyXTal0gjJHRn
Hx4dHiCJiR4eHx+DPwIckxwaGxwbl5SQAhcXFgGhogGeF5wVFRSoq6wVnBMRErKzshETE5wPELu8
vQ0PnAoIw8TFCAuQBwwGzM3OBg5mQgUJBAPX2AMECVhHS9/SQkEAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::aquaTreeImgs
#------------------------------------------------------------------------------
proc tablelist::aquaTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable aqua_${mode}Img \
		 [image create photo tablelist_aqua_${mode}Img]
    }

    variable pngSupported
    variable winSys
    scan $::tcl_platform(osVersion) "%d" majorOSVersion
    if {[string compare $winSys "aqua"] == 0 && $majorOSVersion > 10} {
	set osVerPost10 1
    } else {
	set osVerPost10 0
    }

    if {$pngSupported} {
	if {$osVerPost10} {
	    tablelist_aqua_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAAOCAYAAADABlfOAAAAhElEQVQ4y2NgGNGAGZtgcXHxQysr
q3vHjx+/SY6hjDgM/Q9lbmNgYMjt7e29R4qhTATkvRgYGK4XFxdXUdOlyOAaAwNDVm9v70FKXYoM
tBgYGA4UFxcHUNPQawwMDA69vb0bCClkIcKwXwwMDI29vb1txNpOyFCyYh+XoY+ghm0a3tkUADMc
JviPkg0NAAAAAElFTkSuQmCC
"
	    tablelist_aqua_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAAOCAYAAADABlfOAAAAh0lEQVQ4y2NgGAXUBozoAsXFxQ8Z
GBjk8Oh51NvbK4/PUCYsYrkEHJJLskuhrt3KwMDghUVqW29vrzchQ5nwuOYXmtgvYlzJwMDAwIxN
8Pjx4++trKz+MTAwOCMJ1/X29m4iK6LQguEqAwODFgMDw7Xe3l5tYmOfiYB8FhpNHVBcXBwwfHMU
AB22HTxODBH0AAAAAElFTkSuQmCC
"
	} else {
	    tablelist_aqua_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAAOCAYAAADABlfOAAAAfUlEQVQ4y2NgGAXooK2t7WFbW5sf
ufoZcRj6H8rcxsDAkFtVVXWPFEOZCMh7MTAwXG9ra6uipkuRwTUGBoasqqqqg5S6FBloMTAwHGhr
awugpqHXGBgYHKqqqjYQUshChGG/GBgYGquqqtqItZ2QoWTFPi5DH0EN2zS8cyQA1kwj4qCn3a0A
AAAASUVORK5CYII=
"
	    tablelist_aqua_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAAOCAYAAADABlfOAAAAfElEQVQ4y2NgGAXUBozoAm1tbQ8Z
GBjk8Oh5VFVVJY/PUCYsYrkEHJJLskuhrt3KwMDghUVqW1VVlTchQ5nwuOYXmtgvYlyJ09Cqqqp7
DAwMjWjCjVBxBrK8jxQMVxkYGLQYGBiuVVVVaRMb+0wE5LPQaOqAtra2gOGbowDBEhsE22H0+QAA
AABJRU5ErkJggg==
"
	}

	tablelist_aqua_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAAOCAYAAADABlfOAAAASUlEQVQ4y2NgGAXo4P///zf////v
SG1DYWDJ////Jaht6P////9/+v//fxa1DYWB0////zeltqEw4DxoXUr1MKVq7FM/nQ5KAACuJ6cJ
Ve1XOwAAAABJRU5ErkJggg==
"
	tablelist_aqua_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAAOCAYAAADABlfOAAAAUUlEQVQ4y2NgGAU0B////7/5Hz+4
SY6hjgQMdSTXtUtwGLiEkiCQ+P///yc0Az/9//9fgtKwzUIzNItakXYaauBpaqYEU6ihptROYs7D
NwMBAJg2pwnAMF20AAAAAElFTkSuQmCC
"
    } else {
	if {$osVerPost10} {
	    tablelist_aqua_collapsedImg put "
R0lGODlhFQAOAMIGAAAAAHNzc3Z2doODg4qKipubm////////yH5BAEKAAcALAAAAAAVAA4AAAMi
eLrc/jDKqQaFIZTbchDc4mVEOHrcWaYZGB7Z9h7WbN9KAgA7
"
	    tablelist_aqua_expandedImg put "
R0lGODlhFQAOAMIGAAAAAHNzc3Z2doODg4qKipubm////////yH5BAEKAAcALAAAAAAVAA4AAAMg
eLrc/jDKSeUIOIdRda5H4RXgIWRCqXzqQQREu8p0LScAOw==
"
	} else {
	    tablelist_aqua_collapsedImg put "
R0lGODlhFQAOAMIGAAAAAIaGhoiIiJSUlJmZmampqf///////yH5BAEKAAcALAAAAAAVAA4AAAMi
eLrc/jDKqQaFIZTbchDc4mVEOHrcWaYZGB7Z9h7WbN9KAgA7
"
	    tablelist_aqua_expandedImg put "
R0lGODlhFQAOAMIGAAAAAIaGhoiIiJSUlJmZmampqf///////yH5BAEKAAcALAAAAAAVAA4AAAMg
eLrc/jDKSeUIOIdRda5H4RXgIWRCqXzqQQREu8p0LScAOw==
"
	}

	tablelist_aqua_collapsedSelImg put "
R0lGODlhFQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAVAA4AAAIchI+py+1vAmShzlTt
jVnPnl2gJIYbYJ7kybZIAQA7
"
	tablelist_aqua_expandedSelImg put "
R0lGODlhFQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAVAA4AAAIahI+py+0PXZiUxmov
DtHgfmQgII7ciKYqUgAAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::baghiraTreeImgs
#------------------------------------------------------------------------------
proc tablelist::baghiraTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable baghira_${mode}Img \
		 [image create photo tablelist_baghira_${mode}Img]
    }

    tablelist_baghira_collapsedImg put "
R0lGODlhEAAOAIABAAAAAP///yH5BAEKAAEALAAAAAAQAA4AAAIUjI+py+1/AIxygmtvdTrPsH3i
6BQAOw==
"
    tablelist_baghira_expandedImg put "
R0lGODlhEAAOAIABAAAAAP///yH5BAEKAAEALAAAAAAQAA4AAAITjI+py+0PIwO0Amfvq1LLD4ZN
AQA7
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor1TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor1_${mode}Img \
		 [image create photo tablelist_bicolor1_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor1_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwYtcCg47AAAACpJREFUGNNjYKAA1BOjiIlUTUyk
2sREqvOYSPUTPg2NpGhoJMVJjVSNBwD8+gSMwdvvHwAAAABJRU5ErkJggg==
"
	tablelist_bicolor1_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwkTNtE5iAAAAC9JREFUGNNjYBh0gJGBgaGeCHWN
yBoYCGhqRLeBAY+mRmxOYsChqZFYf9UPbLACACL9BIS+a6kZAAAAAElFTkSuQmCC
"
    } else {
	tablelist_bicolor1_collapsedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIUjI8IybB83INypmqjhGFzxxkZ
UgAAOw==
"
	tablelist_bicolor1_expandedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIQjI+py+D/EIxpNscMyLyHAgA7
"
    }

    tablelist_bicolor1_collapsedSelImg put "
R0lGODlhDAAKAIAAAP///////yH5BAEKAAEALAAAAAAMAAoAAAIUjI8IybB83INypmqjhGFzxxkZ
UgAAOw==
"
    tablelist_bicolor1_expandedSelImg put "
R0lGODlhDAAKAIAAAP///////yH5BAEKAAEALAAAAAAMAAoAAAIQjI+py+D/EIxpNscMyLyHAgA7
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor2TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor2_${mode}Img \
		 [image create photo tablelist_bicolor2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI    
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwwFv3J4nAAAADJJREFUKM9jYKASaCJWIRO5mpnI    
tZmJXGczketnJnIDjBiNdeRorCPHqXXkBE4dzVIOAPKWBZkKDbb3AAAAAElFTkSuQmCC
"
	tablelist_bicolor2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEw4I8/VmowAAADZJREFUKM9jYBgygJGBgaGeBPWN
yBoZiNTciG4jAxGaG7E5lYGA5kZcfmTAo7mR1ECrZxg+AAC4iAWFJSdDXQAAAABJRU5ErkJggg==
"
    } else {
	tablelist_bicolor2_collapsedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIXjI9poA3c0IMxTOpuvS/yPVVW
J5KlWAAAOw==
"
	tablelist_bicolor2_expandedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIUjI+pywoPI0AyuspkC3Cb6YWi
WAAAOw==
"
    }

    tablelist_bicolor2_collapsedSelImg put "
R0lGODlhDgAMAIAAAP///////yH5BAEKAAEALAAAAAAOAAwAAAIXjI9poA3c0IMxTOpuvS/yPVVW
J5KlWAAAOw==
"
    tablelist_bicolor2_expandedSelImg put "
R0lGODlhDgAMAIAAAP///////yH5BAEKAAEALAAAAAAOAAwAAAIUjI+pywoPI0AyuspkC3Cb6YWi
WAAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor3TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor3TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor3_${mode}Img \
		 [image create photo tablelist_bicolor3_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor3_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExAQNNjBKgAAADtJREFUKM9jYKABqCdHExM1DGKi
houYqOE1JmqEERM1ApuJGrFGrCGNlBrSSKl3GikN2EZKo7iR7nkHAKniBpTspddsAAAAAElFTkSu
QmCC
"
	tablelist_bicolor3_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExIRcemTPgAAAD5JREFUKM/t0jsOACAIRMHnycne
3J6IgJa6PRN+8OMzADuok0doQlp1QgNSNA5FSLudUICULZYE0s3l7NGPnffUBoaD5FpzAAAAAElF
TkSuQmCC
"
    } else {
	tablelist_bicolor3_collapsedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIdjI+ZoH3AnIJRPmovznTL7jVg
5YBZ0J0opK4tqhYAOw==
"
	tablelist_bicolor3_expandedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIYjI+py+1vgJx0pooXtmy/CgVc
CITmiR4FADs=
"
    }

    tablelist_bicolor3_collapsedSelImg put "
R0lGODlhEQAOAIAAAP///////yH5BAEKAAEALAAAAAARAA4AAAIdjI+ZoH3AnIJRPmovznTL7jVg
5YBZ0J0opK4tqhYAOw==
"
    tablelist_bicolor3_expandedSelImg put "
R0lGODlhEQAOAIAAAP///////yH5BAEKAAEALAAAAAARAA4AAAIYjI+py+1vgJx0pooXtmy/CgVc
CITmiR4FADs=
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor4TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor4TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor4_${mode}Img \
		 [image create photo tablelist_bicolor4_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor4_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExUCuhZEJwAAAEdJREFUOMu91IsNACAIQ0HSxU03
dwf1ZIBH6IeZz7NegSIXRF4QKVGkB5EmR6YoMqaRPTiBV8GrZKkytCqKVSWqqv8VmP/zDd6/CJzv
kRcqAAAAAElFTkSuQmCC
"
	tablelist_bicolor4_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExY6uTmvegAAAExJREFUOMvtlNsNACAIA8/JSTd3
ApWHfmjsAD1SCvD1lBpgG3w0MqcI0GxyCgCtYiEJkCdzEgB5F0oQoEhbCAAUrSJOgE7cgv13cI86
Y04IiOwcRtoAAAAASUVORK5CYII=
"
    } else {
	tablelist_bicolor4_collapsedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIojI+pCusL2pshSgotznoj23kV
GIkjeWFoSK1pi5qxDJpGbZ/5/cp5AQA7
"
	tablelist_bicolor4_expandedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIijI+py+0Po3Sg2ovrylyzjj2g
J3YTNxlhqpJsALzyTNdKAQA7
"
    }

    tablelist_bicolor4_collapsedSelImg put "
R0lGODlhFwASAIAAAP///////yH5BAEKAAEALAAAAAAXABIAAAIojI+pCusL2pshSgotznoj23kV
GIkjeWFoSK1pi5qxDJpGbZ/5/cp5AQA7
"
    tablelist_bicolor4_expandedSelImg put "
R0lGODlhFwASAIAAAP///////yH5BAEKAAEALAAAAAAXABIAAAIijI+py+0Po3Sg2ovrylyzjj2g
J3YTNxlhqpJsALzyTNdKAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::classic1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic1TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic1_${mode}Img \
		 [image create photo tablelist_classic1_${mode}Img]
    }

    tablelist_classic1_collapsedImg put "
R0lGODlhDAAKAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAMAAoAAAIgnI8Xy4EhohTOwAhk
HVfkuEHAOFKK9JkWqp0T+DQLUgAAOw==
"
    tablelist_classic1_expandedImg put "
R0lGODlhDAAKAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAMAAoAAAIcnI8Xy4EhohTOwBnr
uFhDAIKUgmVk6ZWj0ixIAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::classic2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic2TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic2_${mode}Img \
		 [image create photo tablelist_classic2_${mode}Img]
    }

    tablelist_classic2_collapsedImg put "
R0lGODlhDgAMAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOAAwAAAInnI8Zy4whopThQAlm
NTdmak1ftA0QgKZZ2QmjwIpaiM3chJdm0yAFADs=
"
    tablelist_classic2_expandedImg put "
R0lGODlhDgAMAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOAAwAAAIinI8Zy4whopThwDmr
uTjqwXUfBJQmIIwdZa1e66rx0zRIAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::classic3TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic3TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic3_${mode}Img \
		 [image create photo tablelist_classic3_${mode}Img]
    }

    tablelist_classic3_collapsedImg put "
R0lGODlhEQAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAARAA4AAAIwnI95we2Rgpi0Cris
xkZWYHGDR4GVSE4mharAC0/tFyKpsMq2lV+7dvoBdbbHI1EAADs=
"
    tablelist_classic3_expandedImg put "
R0lGODlhEQAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAARAA4AAAIrnI95we2Rgpi0Cris
xkbqyg3eN4UjaU7AygIlcn4p+Wb0Bd+4TYfi80gUAAA7
"
}

#------------------------------------------------------------------------------
# tablelist::classic4TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic4TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic4_${mode}Img \
		 [image create photo tablelist_classic4_${mode}Img]
    }

    tablelist_classic4_collapsedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAJGXI6pMe0hopxUMGeq
lvdpAGhdA1WgiGVmWI0qdbZpCbOUW4L6rkd4xAuyfisUhjaJ3WYf24RYM3qKsuNmA70+U4aF98At
AAA7
"
    tablelist_classic4_expandedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAI9XI6pMe0hopxUMGeq
lvft3TXQV4UZSZkjymEnG6kRQNc2HbvjzQM5toLJYD8P0aI7IoHKIdEpdBkW1IO0AAA7
"
}

#------------------------------------------------------------------------------
# tablelist::dustTreeImgs
#------------------------------------------------------------------------------
proc tablelist::dustTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable dust_${mode}Img \
		 [image create photo tablelist_dust_${mode}Img]
    }

    tablelist_dust_collapsedImg put "
R0lGODlhEgAQAKU0AAAAADIyMrConLGpncC6scC7ssG8s8K8tMK9tdDMxtDMx9LOyNrVztvVz9vW
ztvWz9vX0NzW0N3Y0d/a0uDd1uHe1+Lf2OPg2uTh2+Xj3efk3+jl4Ojm4enm4unn4+nn5Orn5evo
5Ovo5evq5ezp5e3q5u3q5+7s6O/t6e7t6vDu6/Hv7PHv7fLw7PLw7vT08vf39fj39fn49vn49///
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAakwJ9w
SCwSCQOBcrkcEIiGxQsWk82ushjspTgMB6zSCaVatVYq1GnkGgwFrE6IVDLZS6RQhyV4pzAZGhsc
ARwbGhkYKX1CAiYUFRYXFwGTFhUUJow/AiISnxITAROgEiKbAh0MEQGtrgEPDx2oHbEPDg8BDbay
qB68ucAevsCwvMNvIRHLzM0RIZsDHhDOzRAebkIHCiAi3t/fHwkIR0lMTAMFREEAOw==
"
    tablelist_dust_expandedImg put "
R0lGODlhEgAQAKU0AAAAADIyMrConLGpncS+tcS/tsbBuMfBucfCucfCutfTzdjUztnUz9vWztvW
z9vX0NzW0N3Y0d/a0t/a0+Dd1uHe1+Lf2OPg2uTh2+Xj3efk3+jl4Ojm4enm4unn4+vo5Ovo5evp
5uvq5ezp5e3q5u3q5+7s6O/t6e7t6vDu6/Hv7PLv7fLw7PHw7fLx7vX08vf39fj39fn49vn49///
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAagwJ9w
SCwSCQOBcrkcEIiGxQsWk82ushjspUAMBy2S6ZRSsVSpk0nkGgwFq85nRCrZSaNPZyV4ozAZGhsc
hBsaGRgofUICJRQVFhcXGJIWFRQliz8CIBGeERITEp8RIJoCHQsQAaytAQ4OHacdsA4NsAy1sace
ur6wHry/vsFvHxDIycoQH5oDHw/Lyg8fbkIHDCEg29zdCwlHSUxMAwVEQQA7
"
}

#------------------------------------------------------------------------------
# tablelist::dustSandTreeImgs
#------------------------------------------------------------------------------
proc tablelist::dustSandTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable dustSand_${mode}Img \
		 [image create photo tablelist_dustSand_${mode}Img]
    }

    tablelist_dustSand_collapsedImg put "
R0lGODlhEgAQAKU1AAAAADIyMpuWjJyXjrSxqbWxqre0rbi1rrm2r8K+tsO+t8TAuMXBusbCu8nF
vcnGvsrHv8vHwMnGwcrIwczIwMzIwc3Jw87LxMzKxc/MxdDMxdDMx9HOx9HOyNLPydPPytPQydPQ
y9TRy9TRzNXTzNXSzdfTztbUzNbUzdfVz9nV0NjW0NnW0drY097c2eDe2eXi3uXj3+jm4+nn5Oro
5f///////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAajwJ9w
SCwSCQOBcrkcEIiGCUwmm81oVmpMchgOXqWSSbVirVSm0ug1GApcm85HNKqLPp2NS+BuVSwXGRoB
GhkXFhUtfEICKQ4PEBEUARQREA8OKYs/AiEMnwwNAQ2gDCGbAhwJCgGtrgEKChyoHLGxCQGrtrNu
tbasv7KoHcGwvx2oHgvLzM0LHpsDJc7UJG1CBxgoINzd3ScYCEQFSUxMAwVEQQA7
"
    tablelist_dustSand_expandedImg put "
R0lGODlhEgAQAKU3AAAAADIyMpuWjJyXjrSxqbWxqre0rbi1rrm2r8K+tsO+t8TAuMXBusbCu8bC
vMnFvcnGvsrHv8vHwMnGwcrIwczIwMzIwc3Jw87LxMzKxc/Mxc/MxtDMxdDMx9HOx9HOyNLPydPP
ytPQydPQy9TRy9TRzNXTzNXSzdfTztbUzNbUzdfVz9nV0NjW0NnW0drY097c2eDe2eXi3uXj3+jm
4+nn5Oro5f///////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAagwJ9w
SCwSCQOBcrkcEIgGioxGq9VsVupschgOYqcTitVytVioUyk2GApgnU+IVKqTQp8OTOB+WS4YGhwb
HBoYFxYvfEICKw8QERIVFhUSERAPK4s/AiMMnwwNDg2gDCObAh4JCgGtrgEKCh6oHrGxCbi2srS6
vbGzbh++vR+oIAvIycoLIJsDJ8vRJm1CBxkqItna2ikZCEQFSUxMAwVEQQA7
"
}

#------------------------------------------------------------------------------
# tablelist::gtkTreeImgs
#------------------------------------------------------------------------------
proc tablelist::gtkTreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable gtk_${mode}Img \
		 [image create photo tablelist_gtk_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_gtk_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAUUlEQVQoz8XTwQ2AQAhE0T17+jVQ
h/XRGIV9L5p4FsxSwAuZgbV+nHNEARzBACOijwFWVR8DVPvYA7WxN6Samd4FHHs3GslorLWxO5p6
k0/IBbP6VlQP0oOsAAAAAElFTkSuQmCC
"
	tablelist_gtk_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAW0lEQVQoz+3SwQmAQAxE0fHqKTVM
HWt7aWwsKB3Ek4IQYXVBEPzXkJdLgL/XmgA0M1PvQkQsANareSOZkrJKUpJMAK3nWIndRUrsKXLC
3H0IOTAzG0b25m8/5Aai703YBhwgYAAAAABJRU5ErkJggg==
"
	tablelist_gtk_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAa0lEQVQoz7XSMQqAMAyF4d9OAZeM
OYyeXg/TMZN0qwdQKyltxjz4CI/AxNmGKKpah2CqWs0sjKW3ZSkFMzsiWPoKolhqhRFs+Sj7Me6+
AlfXRQAigrvvLeQXEhFyzjtwdncUQYb+0bzP7kVuCWMmCi7K2XoAAAAASUVORK5CYII=
"
	tablelist_gtk_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAXUlEQVQoz2NgGAV0A4wMDAyZAgIC
04jV8OHDhywGBobp6OLMDAwMZ378+PGKg4PDm1xDYAYxEGMYPkOwgUwBAYH/6JiBgSGTnHCDG6ak
pES2ISiGUWoIDIgM7QQJACRKJBMon0pJAAAAAElFTkSuQmCC
"
    } else {
	tablelist_gtk_collapsedImg put "
R0lGODlhEgAOAMIFAAAAABAQECIiIoaGhsPDw////////////yH5BAEKAAcALAAAAAASAA4AAAMi
eLrc/pCFCIOgLpCLVyhbp3wgh5HFMJ1FKX7hG7/mK95MAgA7
"
	tablelist_gtk_expandedImg put "
R0lGODlhEgAOAMIFAAAAABAQECIiIoaGhsPDw////////////yH5BAEKAAcALAAAAAASAA4AAAMg
eLrc/jDKSWu4OAcoSPkfIUgdKFLlWQnDWCnbK8+0kgAAOw==
"
	tablelist_gtk_collapsedActImg put "
R0lGODlhEgAOAKEDAAAAABAQEBgYGP///yH5BAEKAAMALAAAAAASAA4AAAIdnI+pyxjNgoAqSOrs
xMNq7nlYuFFeaV5ch47raxQAOw==
"
	tablelist_gtk_expandedActImg put "
R0lGODlhEgAOAKEDAAAAABAQECIiIv///yH5BAEKAAMALAAAAAASAA4AAAIYnI+py+0PY5i0Bmar
y/fZOEwCaHTkiZIFADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::klearlooksTreeImgs
#------------------------------------------------------------------------------
proc tablelist::klearlooksTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable klearlooks_${mode}Img \
		 [image create photo tablelist_klearlooks_${mode}Img]
    }

    tablelist_klearlooks_collapsedImg put "
R0lGODlhEAAOAIABAAAAAP///yH5BAEKAAEALAAAAAAQAA4AAAIVjI+py+1vAIBR0iAnzZA//2nX
SD4FADs=
"
    tablelist_klearlooks_expandedImg put "
R0lGODlhEAAOAIABAAAAAP///yH5BAEKAAEALAAAAAAQAA4AAAIVjI+py+0PEwBntkmxw/bpSEXi
SIoFADs=
"
}

#------------------------------------------------------------------------------
# tablelist::mateTreeImgs
#------------------------------------------------------------------------------
proc tablelist::mateTreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable mate_${mode}Img \
		 [image create photo tablelist_mate_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_mate_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAHdElNRQfgBQkTFQk/cTJBAAAAGnRFWHRTb2Z0
d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAABvSURBVChTY/j//z/JGKsgIYxVkBBGMBgYJJAl
8GEEg4FhCxCnIEviwggGA8N+IF4MxKuBWB9ZETpGMCCaKoF4AhBvBuIOIMbqZAQDoakBiFuBeAcQ
rwRiDI3YNJFsE8l+Iiv0SI8nUjBWQfz4PwMAdOLOFUtMsZ8AAAAASUVORK5CYII=
"
	tablelist_mate_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwQAADsEBuJFr7QAAAAd0SU1FB+AFCRMYGg5hDdIAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAIVJREFUKFOV0DESQDAQBdB/AD2ncCKNS2h0ZjROoUFHoXO5+EuYkB07
ipdN/u42gXPuNzW0qKFFDS3nAaS00KaQPI2W/GJBPVUBeZfhwjF7X4CMRuqo9nWiJFw4Zh8PIKeZ
Gl/zsH/PRQHQ0ir13bvEwfkpg9R376KHHwtCDS1qaFHDbw47S7vHxT1vFYcAAAAASUVORK5CYII=
"
	tablelist_mate_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwQAADsEBuJFr7QAAAAd0SU1FB+AFCRMaDb+E6pcAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAG9JREFUKFNj+P//P8kYqyAhjFWQEEYwGBgkkCXwYQSDgeEIEE9GlsSF
EQwGhv1AvAeI9wJxMLIidIxgQDQtBeLNQAyydQMQ6yArhquFMxCaVgLxOigfZCuGX7FpItkmkv1E
VuiRHk+kYKyC+PF/BgB1jdECrfqPqwAAAABJRU5ErkJggg==
"
	tablelist_mate_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwQAADsEBuJFr7QAAAAd0SU1FB+AFCRMbDj+WimwAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAHZJREFUKFOVkNsJwCAMRe8WbtOF3KrQAUpf4HKp1ihRg6Efx5CTe38E
Ef1GlRaqtFClRX4AFwkT3FDi4sqBXZD2TRa+bLPk0BM5eAZ5r7lmAXwKRk6eXt5rbhDAxYW7vxVG
ASxcWvpbQZfdb/Wo0kKVFqqcQ3gBKsLRaJdxo5AAAAAASUVORK5CYII=
"
    } else {
	tablelist_mate_collapsedImg put "
R0lGODlhDQAOAOMOAAAAAEBAQEdHR0tLS0xMTFRUVFZWVlxcXG9vb3d3d3p6en9/f4aGhpubm///
/////yH5BAEKAA8ALAAAAAANAA4AAAQf8MlJq70459H0C0ehBQxCJBi5KIJxkSb6hhrn3fgdAQA7
"
	tablelist_mate_expandedImg put "
R0lGODlhDQAOAIQQAAAAAEVFRUxMTFBQUFFRUVhYWFlZWVpaWl9fX3V1dXp6en19fYSEhImJiZ6e
nqOjo////////////////////////////////////////////////////////////////yH5BAEK
AAAALAAAAAANAA4AAAUlICCOZGmeaJoOQdsO5oM0NOKcRsIkRUosBJVCoFABDsakcpkKAQA7
"
	tablelist_mate_collapsedActImg put "
R0lGODlhDQAOAOMLAAAAADs7O0BAQEJCQkNDQ0xMTE9PT1FRUVZWVlpaWmxsbP//////////////
/////yH5BAEKAA8ALAAAAAANAA4AAAQf8MlJq70456D0E8SgCUkRGBiJHIJokSZ6gS7GeXiORwA7
"
	tablelist_mate_expandedActImg put "
R0lGODlhDQAOAOMKAAAAAEVFRUhISElJSUpKSktLS0xMTE5OTlpaWl1dXf//////////////////
/////yH5BAEKAA8ALAAAAAANAA4AAAQg8MlJq70458B7sElwjAFyBYIhfFhQsBgRDNoD13iuWxEA
Ow==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::mintTreeImgs
#------------------------------------------------------------------------------
proc tablelist::mintTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable mint_${mode}Img \
		 [image create photo tablelist_mint_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_mint_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA6/AAAOvwE4BVMkAAAAB3RJTUUH4AgVETkWapOs4gAAAFRJREFUKM/F0csJgDAQBcAht7Qj
NmERVpajRdiEWIJt5GoFWYxEfMdlB/bDnylv0IUtakiN+hTBFsoRTMEUGTP2HtS9E1QcWJ6iihPr
sJMPe+43uQEqOwsax3OY5AAAAABJRU5ErkJggg==
"
	tablelist_mint_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA6/AAAOvwE4BVMkAAAAB3RJTUUH4AgVEgAUiF/+LQAAAFlJREFUKM/t0bEJgDAQRuFPdAIH
Su0YFg7mLFnAzjLgFpY2EVIEiaXgg+O443/XHD+gyz1gbcjPiH0eDmyYMFTCJxbE2qWAHamoPe8f
KcUmoRTTG+Fm/OhzL/U/D1OvbHP6AAAAAElFTkSuQmCC
"
	tablelist_mint_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA6+AAAOvgHqQrHAAAAAB3RJTUUH4AgVETo0lN6+xQAAAE1JREFUKM9jYBgw8P///3nkaHrx
////5fjUMOEQt8CnEZcmTnwamfC4AqZxHymaSPYTAwMDw3cGBoYTjIyMTsSG3n1CIUhykFMncmkG
AH8QL3kc9+eHAAAAAElFTkSuQmCC
"
	tablelist_mint_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI    
WXMAAA6/AAAOvwE4BVMkAAAAB3RJTUUH4AgVEgEbAfvS/QAAAFhJREFUKM/t0cEJwCAQRNE/gfRk
GZaaMuzCqx14nFwSEIPoVcjAnnYeLCz8AUAAtgNwLfSjpHQASEpABOqgXF/w2dgOtrPt0kx+Lhmn
g3PQwbIMGnhu+twbiKFCUb0So1cAAAAASUVORK5CYII=
"
    } else {
	tablelist_mint_collapsedImg put "
R0lGODlhDQAOAMIHAAAAACEhISgoKCoqKkhISFxcXGRkZP///yH5BAEKAAcALAAAAAANAA4AAAMd
eLrc/spAFspUYdgZ8n5dIBBQOJYep13VdUhufCUAOw==
"
	tablelist_mint_expandedImg put "
R0lGODlhDQAOAKEDAAAAACEhISkpKf///yH5BAEKAAMALAAAAAANAA4AAAIXnI+py+0/gpwzCRrE
ulKz6zUBRJYmUgAAOw==
"
	tablelist_mint_collapsedSelImg put "
R0lGODlhDQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAANAA4AAAIXhI+pa8EY3ANRsmoV
zhDf+oAhp03mCRQAOw==
"
	tablelist_mint_expandedSelImg put "
R0lGODlhDQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAANAA4AAAIShI+py+0Pgpwz0apu
wxv6DyIFADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::mint2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::mint2TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable mint2_${mode}Img \
		 [image create photo tablelist_mint2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_mint2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADr4AAA6+AepCscAAAAAHdElNRQfgBQkTHSnMxpiBAAAAGnRFWHRTb2Z0
d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAABRSURBVChTpZGxCQAgDAR/fkdwMitXiYqFPsRE
Y3HFPRwEhYg8o44eLEDa/QQLUDt53zRYZlS8kGVGbsiyIjNk+Yyezws9hBkMWCKfe4s62gga8dTd
YGVViS0AAAAASUVORK5CYII=
"
	tablelist_mint2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOvgAADr4B6kKxwAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAYklE
QVQoU5XLQQqAMAxE0ZzBW/T+lxDciK49S5rUGiidZrDwFh3yRVV/gyMDRwaODBwZf8Wc5klcpkTU
Sw8Pg4LbRBBREk5Bux0+YwiDdjcNb7ivAodHkQ3tHzgycGTgmFOpl2jLGnIdx90AAAAASUVORK5C
YII=
"
	tablelist_mint2_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOvAAADrwBlbxySQAAAAd0SU1FB+AFCRMdKczGmIEAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAFVJREFUKFOlkDEKwDAMA/N7736If+dZjYcOAlPF6XCEEzkIWQDGtKOC
xN33wRc6SMwMJyFJRREhQ5KKMlOGJG+kQpJf0fh5Vx+hgoLkJCjaUdGO32A9XVwfc0mdLjYAAAAA
SUVORK5CYII=
"
	tablelist_mint2_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOvQAADr0BR/uQrQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAW0lE
QVQoU5XLwQ3AIAxDUbbPjckyRJbIOcg9VG1xsHp4SHzwqKrfaFRoVGhUaFSuY85ZZtbC+zYCPERE
ZeYN9+8AXpfnsBvAFvDR3dsB0HgaAI0KjQqNCo1nNRZ9ViCcGRAOXQAAAABJRU5ErkJggg==
"
    } else {
	tablelist_mint2_collapsedImg put "
R0lGODlhDQAOAMIFAAAAACEhIScnJ2VlZXV1df///////////yH5BAEKAAcALAAAAAANAA4AAAMc
eLrc/odAFsZUQdgZ8n6dB4XaKI4l90HS5b5HAgA7
"
	tablelist_mint2_expandedImg put "
R0lGODlhDQAOAMIHAAAAACIiIiwsLC0tLS8vLzQ0NDc3N////yH5BAEKAAcALAAAAAANAA4AAAMZ
eLrc/jDKSYK9YbSCg3ic9UHcGBlTqq5RAgA7
"
	tablelist_mint2_collapsedSelImg put "
R0lGODlhDQAOAMIFAAAAAIeHh5KSkq6urvX19f///////////yH5BAEKAAcALAAAAAANAA4AAAMd
eLrc/kdAFuQ8YVgYiJ6dtzXh93TmmZ7j017wlAAAOw==
"
	tablelist_mint2_expandedSelImg put "
R0lGODlhDQAOAMIGAAAAAIeHh46OjszMzODg4PX19f///////yH5BAEKAAcALAAAAAANAA4AAAMa
eLrc/jDKKYK9QTRBiieawxVgJAyhOa1sGyUAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::newWaveTreeImgs
#------------------------------------------------------------------------------
proc tablelist::newWaveTreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable newWave_${mode}Img \
		 [image create photo tablelist_newWave_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_newWave_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfgBQkTJAyJRsF8AAAAGnRFWHRTb2Z0
d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAADQSURBVDhPY6A7+P//P5SFBfj4+PAB8QxfX19R
qBBWQMgQAQ8Pjw/u7u73gexCIGaFSqEAgoY4OzvfYmNjyzczM9vk7e19ESjmBZWGA4KGuLi4XAUy
I0BYVFQ0y9HR8RBQfCsQa4AVAQFBQ9zc3C4CmW7IWENDIx/oxctA+X6QGoKGABWfATJNkLGOjk4K
MKxAXiPOEE9PzxNAphIIq6qqWgNdthkoTpp3vLy8DsvKykoCNXcA+eeAmPSABeLHQAxyOtlRTHli
IxZQxRDsgIEBAK1PZ2HAQtNpAAAAAElFTkSuQmCC
"
	tablelist_newWave_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfgBQkTJh3RwIMMAAAAGnRFWHRTb2Z0
d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAACySURBVDhPYxiGwMfHhw+IBQhgPqhy7ACoYIaH
h8cHJyenu9gwSA6kBqocO/D19RUFKrzHxsaWD+RmIWOQGEgOpAbIxw+ANhVaWFisBjIjkDFIDCQH
ZBMGQIWs3t7eFyQkJKKBXDcQBrFBYiA5sCJiAFCxl4uLyw4g0xSEQWyQGFiSFADUtNXExCQMhEFs
qDBpAKhRA+iFUyAMYkOFSQdAzf0gDOWSB4AGgBMYlEsPwMAAAFjwRMOCm1MPAAAAAElFTkSuQmCC
"
	tablelist_newWave_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfgBQkTJzSKaSohAAAAGnRFWHRTb2Z0
d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAADeSURBVDhPY6A7+P//P5SFBZiYmPAZGxvPAGJR
qBBWQMgQATtT4z/2psZvgAYVAvmsUCkUQNAQHwvjH7M8DJ+k2xl9tDAxvg40zAsqDQeEDbE0/r7I
1+gBCE/xMnocbmP8BWjQNiDWgCojbIivlfG3pYHGd5Fxp5fxEw9L489Ag/qBWICwIdbGX1eEmtxE
xl0+Jo+Ahnwi2hA/a5OvayLNroHwnBDTW5H2Jh+BGknzjp+NyZdVMeaXc9xMX1iYGl8DaiY9YO3N
jX85Wpi8AmomO4opT2zEAqoYgh0wMAAArYN9OA1qURYAAAAASUVORK5CYII=
"
	tablelist_newWave_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQfgBQkTKQLbUJI2AAAAGnRFWHRTb2Z0
d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAAC6SURBVDhPYxiGwMTEhA+IBQhgPqhy7MDY2HiG
ranxH29zo5/YMEgOpAaqHDsAKhC1NzV+M8PV4NkcN1QMEgPJgdRAleMGQEWF6fZGHxb6GD1ExiAx
kBxUGX4A9DOrhYnxtem+xg+WBhrfBWEQGyQGkoMqIwyANnpF2Jl8XBVuegOEQWyQGFSaeADUtK0v
0PQuCJsA2VBh0gDQEA1Pa5MPIAxiQ4VJB0DN/SAM5ZIHgAYIgDCUSw/AwAAAH1NYxpYmHp0AAAAA
SUVORK5CYII=
"
    } else {
	tablelist_newWave_collapsedImg put "
R0lGODlhEQAOAIQdAAAAAFJSUl5eXl9fX2JiYmZmZmdnZ2lpaWtra2xsbG5ubnBwcHJycnR0dH19
fX9/f5KSkpSUlJqampycnJ2dnaGhoaenp6ysrLm5ucvLy8zMzN3d3ejo6P///////////yH5BAEK
AB8ALAAAAAARAA4AAAU44CeOZGmeaISigbCaAsQg70hYFqU8tYH9mEpBskJkjpnLgYhabDYaB+/V
4EwUNdEgkR2puuBwKQQAOw==
"
	tablelist_newWave_expandedImg put "
R0lGODlhEQAOAIQSAAAAAFJSUltbW19fX2xsbHBwcHh4eHl5eX9/f5KSkpSUlJWVlZqamqenp6ys
rLm5ubq6usrKyv///////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAARAA4AAAU04CeOZGmeaKquoxIIcBwo6JAs+JIM6tH8jcOK4Hg8HASWIRIxsD4ICATx
/BQK1Q+Dke0+QwA7
"
	tablelist_newWave_collapsedActImg put "
R0lGODlhEQAOAKUgAAAAAEA3NUI6N1A9OFE/OVNAOlNCO1BCPFFDPVRCO1VEPF5EO2JJP29IPU1E
QlBIRFdTU1dVU3lWR21tbZVdSJ9dSJdgS6RbRq1iSqpsUrFoTrRuUrlzVrh4WYWFhYyMjP//////
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAAAALAAAAAARAA4AAAY8QIBw
SCwaj0gPEhlwLI2DSwPyHBIwmMpiUi1ovhrK4bM0bM4bC4KMTHA4GQb3qehIIlWh4JEfKvuAgUVB
ADs=
"
	tablelist_newWave_expandedActImg put "
R0lGODlhEQAOAIQSAAAAAD83NU87NlNGP2FIP29KPk1EQldUU21tbZ1oT6JXRKVYRKNiS6xhSrFo
TrdwU4WFhYyMjP///////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAARAA4AAAU04CeOZGmeaKquIxQIcBxAqKEs+KIYatH8jcLqwHA4GAcW4fEgsD6IRALx
/AwG1U8kku0+QwA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::oxygen1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::oxygen1TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable oxygen1_${mode}Img \
		 [image create photo tablelist_oxygen1_${mode}Img]
    }

    tablelist_oxygen1_collapsedImg put "
R0lGODlhEAAOAKECAAAAABQTEv///////yH5BAEKAAAALAAAAAAQAA4AAAIShI+py+0PVYhmwoBx
tJv6D0YFADs=
"
    tablelist_oxygen1_expandedImg put "
R0lGODlhEAAOAKECAAAAABQTEv///////yH5BAEKAAAALAAAAAAQAA4AAAIPhI+py+0Po2yh1omz
3rwAADs=
"
}

#------------------------------------------------------------------------------
# tablelist::oxygen2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::oxygen2TreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable oxygen2_${mode}Img \
		 [image create photo tablelist_oxygen2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_oxygen2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AgXFB4trZ/9wwAAAFpJREFUKM/t0rENQGAUReEv0UgM
YgEVlUQjEttYRaGyixXEABpraBR/67Wc6jbn3lc8flI6jG+lLMklZhTYoldU2LE+RSEaXJgico0D
C/K38oAzugwt+g9+3w3IEAlJihLp4AAAAABJRU5ErkJggg==
"
	tablelist_oxygen2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AgXFCEWREo+2wAAAFdJREFUKM/t0iEKgEAQheEvCl7H
pEmwLIK3MXkTk4cSuxavYdlkWhfj/m1eGP4ZHoXf6DG+soAhdUHAhTbODU5MXyxmHOiwY8k5ZcWN
LfcXVTSpSy3SeQBkeAlg0OObegAAAABJRU5ErkJggg==
"
	tablelist_oxygen2_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AgXFB85rl4Y/wAAAHtJREFUKM/tkiEOwkAURN9v6H1W
VFWTIJpwhu82AY3qMVZi9g4ILrHin4E7gP04ssF93Y4aM5OZycCOH9T8qObnqG7o+AgUNV8jBvKX
YgIq0IBrTfKOJKAmaUAGTsAlWgE1n4E78ABKdMRFzV9qfovoDh3/ALkmeW7sgF/KlyBRWhng6wAA
AABJRU5ErkJggg==
"
	tablelist_oxygen2_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AgXFCIMkgWUYgAAAHdJREFUKM9jYBgF1AEJF/47Jlz4
740m5plw4b8LIb1MUJqDgYFhesKF/1ZQzSYMDAwzGBgYuAgZwIhkYykDA0MiAwNDKgMDw0wGBobl
CwwYW4k2AGrILAYGBl8GBoadCwwYE4jxPgsaP4+BgeE2AwPDtNGUQTwAAF28HMqTOZpSAAAAAElF
TkSuQmCC
"
    } else {
	tablelist_oxygen2_collapsedImg put "
R0lGODlhEAAOAIABAAAAAP///yH5BAEKAAEALAAAAAAQAA4AAAIVjI+py+0PwDtRzlAvjjND3lna
SF4FADs=
"
	tablelist_oxygen2_expandedImg put "
R0lGODlhEAAOAIABAAAAAP///yH5BAEKAAEALAAAAAAQAA4AAAIVjI+py+0PDwCSskmxwxPqaEXi
SI4FADs=
"
	tablelist_oxygen2_collapsedActImg put "
R0lGODlhEAAOAKECAAAAAGDQ/////////yH5BAEKAAAALAAAAAAQAA4AAAIVhI+py+0fwjtRTlAv
jjND3lnaSF4FADs=
"
	tablelist_oxygen2_expandedActImg put "
R0lGODlhEAAOAKECAAAAAGDQ/////////yH5BAEKAAAALAAAAAAQAA4AAAIVhI+py+0PTwiSskmx
wxPqaEXiSI4FADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::phaseTreeImgs
#------------------------------------------------------------------------------
proc tablelist::phaseTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable phase_${mode}Img \
		 [image create photo tablelist_phase_${mode}Img]
    }

    tablelist_phase_collapsedImg put "
R0lGODlhEAAOAKECAAAAAMfHx////////yH5BAEKAAAALAAAAAAQAA4AAAIYhI+py63hUoDRTBov
bnovXV0VMI2kiaIFADs=
"
    tablelist_phase_expandedImg put "
R0lGODlhEAAOAKECAAAAAMfHx////////yH5BAEKAAAALAAAAAAQAA4AAAIThI+py+0PT5iUsmob
hpnHD4ZhAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::plain1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain1TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain1_${mode}Img \
		 [image create photo tablelist_plain1_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain1_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwYtcCg47AAAACpJREFUGNNjYKAA1BOjiIlUTUyk
2sREqvOYSPUTPg2NpGhoJMVJjVSNBwD8+gSMwdvvHwAAAABJRU5ErkJggg==
"
	tablelist_plain1_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwkTNtE5iAAAAC9JREFUGNNjYBh0gJGBgaGeCHWN
yBoYCGhqRLeBAY+mRmxOYsChqZFYf9UPbLACACL9BIS+a6kZAAAAAElFTkSuQmCC
"
    } else {
	tablelist_plain1_collapsedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIUjI8IybB83INypmqjhGFzxxkZ
UgAAOw==
"
	tablelist_plain1_expandedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIQjI+py+D/EIxpNscMyLyHAgA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plain2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain2TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain2_${mode}Img \
		 [image create photo tablelist_plain2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwwFv3J4nAAAADJJREFUKM9jYKASaCJWIRO5mpnI
tZmJXGczketnJnIDjBiNdeRorCPHqXXkBE4dzVIOAPKWBZkKDbb3AAAAAElFTkSuQmCC
"
	tablelist_plain2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEw4I8/VmowAAADZJREFUKM9jYBgygJGBgaGeBPWN
yBoZiNTciG4jAxGaG7E5lYGA5kZcfmTAo7mR1ECrZxg+AAC4iAWFJSdDXQAAAABJRU5ErkJggg==
"
    } else {
	tablelist_plain2_collapsedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIXjI9poA3c0IMxTOpuvS/yPVVW
J5KlWAAAOw==
"
	tablelist_plain2_expandedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIUjI+pywoPI0AyuspkC3Cb6YWi
WAAAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plain3TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain3TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain3_${mode}Img \
		 [image create photo tablelist_plain3_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain3_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExAQNNjBKgAAADtJREFUKM9jYKABqCdHExM1DGKi
houYqOE1JmqEERM1ApuJGrFGrCGNlBrSSKl3GikN2EZKo7iR7nkHAKniBpTspddsAAAAAElFTkSu
QmCC
"
	tablelist_plain3_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExIRcemTPgAAAD5JREFUKM/t0jsOACAIRMHnycne
3J6IgJa6PRN+8OMzADuok0doQlp1QgNSNA5FSLudUICULZYE0s3l7NGPnffUBoaD5FpzAAAAAElF
TkSuQmCC
"
    } else {
	tablelist_plain3_collapsedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIdjI+ZoH3AnIJRPmovznTL7jVg
5YBZ0J0opK4tqhYAOw==
"
	tablelist_plain3_expandedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIYjI+py+1vgJx0pooXtmy/CgVc
CITmiR4FADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plain4TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain4TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain4_${mode}Img \
		 [image create photo tablelist_plain4_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain4_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExUCuhZEJwAAAEdJREFUOMu91IsNACAIQ0HSxU03
dwf1ZIBH6IeZz7NegSIXRF4QKVGkB5EmR6YoMqaRPTiBV8GrZKkytCqKVSWqqv8VmP/zDd6/CJzv
kRcqAAAAAElFTkSuQmCC
"
	tablelist_plain4_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExY6uTmvegAAAExJREFUOMvtlNsNACAIA8/JSTd3
ApWHfmjsAD1SCvD1lBpgG3w0MqcI0GxyCgCtYiEJkCdzEgB5F0oQoEhbCAAUrSJOgE7cgv13cI86
Y04IiOwcRtoAAAAASUVORK5CYII=
"
    } else {
	tablelist_plain4_collapsedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIojI+pCusL2pshSgotznoj23kV
GIkjeWFoSK1pi5qxDJpGbZ/5/cp5AQA7
"
	tablelist_plain4_expandedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIijI+py+0Po3Sg2ovrylyzjj2g
J3YTNxlhqpJsALzyTNdKAQA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plastikTreeImgs
#------------------------------------------------------------------------------
proc tablelist::plastikTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plastik_${mode}Img \
		 [image create photo tablelist_plastik_${mode}Img]
    }

    tablelist_plastik_collapsedImg put "
R0lGODlhDwAOAMIDAAAAAHZ2drW1tf///////////////////yH5BAEKAAQALAAAAAAPAA4AAAMq
SLrc/jAqEWoVj469A24BB3CBE25jZw5A2w4lKJIrSjcaB3+4dUnA4CIBADs=
"
    tablelist_plastik_expandedImg put "
R0lGODlhDwAOAMIDAAAAAHZ2drW1tf///////////////////yH5BAEKAAQALAAAAAAPAA4AAAMo
SLrc/jAqEWoVj469A24BJwZOKHblAKzrQIInCscvo41fQ1me5P+LBAA7
"
}

#------------------------------------------------------------------------------
# tablelist::plastiqueTreeImgs
#------------------------------------------------------------------------------
proc tablelist::plastiqueTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plastique_${mode}Img \
		 [image create photo tablelist_plastique_${mode}Img]
    }

    tablelist_plastique_collapsedImg put "
R0lGODlhEQAOAOMLAAAAAHp4eH59fa+trfHx8fPz8/X19ff39/n5+fv7+/39/f//////////////
/////yH5BAEKAA8ALAAAAAARAA4AAAQ+8MlJq7042yG6FwMmKGSpCGKiBmqCXgIiBzLyWsIR7Ptx
VwKDMCA0/CiCgjKgLBwnAoJ0SnhKOJ9OSMPtYiIAOw==
"
    tablelist_plastique_expandedImg put "
R0lGODlhEQAOAOMLAAAAAHp4eH59fa+trfHx8fPz8/X19ff39/n5+fv7+/39/f//////////////
/////yH5BAEKAA8ALAAAAAARAA4AAAQ78MlJq7042yG6FwMmKGSpCGKirgl6CUgsI64lHEGeH3Ul
GMCgoUcRFI7IAnEiIDifhKWE8+mENNgsJgIAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::radianceTreeImgs
#------------------------------------------------------------------------------
proc tablelist::radianceTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable radiance_${mode}Img \
		 [image create photo tablelist_radiance_${mode}Img]
    }

    tablelist_radiance_collapsedImg put "
R0lGODlhEgAQAKUoAAAAAEBAQOTe1eTe1uTf1+bh2ejj2ujk3erl3uvn4Ozo4u3p4+7q5O/r5u/s
5+/t6PDt6PPw7PLw7fXz8Pb08ff18vb18/f28vj28fj28vj28/j39Pj39fj49fn49/n5+Pr6+Pv7
+fz8+fz8+vz8+/39/P39/f7+/f//////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAaZwJ9w
SCwWD4KkUnkwFjAj02k6NY0oBeLBQiKVvuBS19IUCkCgkGjEZotCaMFQ4Kl/7oH7p+6RmzkcGxsc
HQEdgYAcfj8CGhoZGhQVARUVF44aiwIUFBMBn6ABnBSaEhESqBIBqamaEA+wsAGxsBCaC7i5Abm4
DJoJCMHCwwgKiwcNBsrLzAYOZUIFCgQD1dYDBApZR0vd0EJBADs=
"
    tablelist_radiance_expandedImg put "
R0lGODlhEgAQAKUoAAAAAEBAQOTe1eTe1uTf1+bh2ejj2ujk3erl3uvn4Ozo4u3p4+7q5O/r5u/s
5+/t6PDt6PPw7PLw7fXz8Pb08ff18vb18/f28vj28fj28vj28/j39Pj39fj49fn49/n5+Pr6+Pv7
+fz8+fz8+vz8+/39/P39/f7+/f//////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAaTwJ9w
SCwWD4KkUnkwFjAj02k6NY0oBeLBQiKVvuBS19IUCkCgkGjEZotCaMFQ4Kl/7vhP3SM3czgbGxwd
hIB/HH0/AhoaGRoUFRcVkYwaiQIUFBMBnJ0BmRSXEhESpaanEpcQD6ytrg8QlwuztLWzDJcJCLu8
vQgKiQcNBsTFxgYOZUIFCgQDz9ADBApZR0vXykJBADs=
"
}

#------------------------------------------------------------------------------
# tablelist::ubuntuTreeImgs
#------------------------------------------------------------------------------
proc tablelist::ubuntuTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable ubuntu_${mode}Img \
		 [image create photo tablelist_ubuntu_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_ubuntu_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAgElEQVQoz73ROwrCUBSE4Q8jATtR
AkoWpZCVuA8xO0gr2LgdF+Cj0CJ1bGyuTUhuECTTzTn/FMMwllaxZ9LyFd64dMGTlk9RoEQ+BMMN
sxAohmCoccUmhNYxGBo8QukDsmkETrHEHXs8++A5Fjji/D12wTle2IWyvTph+5cFf9IH6EoSOPaU
kccAAAAASUVORK5CYII=
"
	tablelist_ubuntu_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAiklEQVQoz9XRIQoCYRAF4M8VXCzC
j2lFTJ7H5C02eA+bd9BgEBeP4R3MBrVZNFn+hZ8/qEnwwYThvZl5vOH/0EGFFfpvdE8surjjgSlO
uGTVwxbHIk4ecEXINgbcsIciIZYYoIx9iVDX9Sb1nGKGOc4YYYemJYtM3NqZxPPNp4QqrDH+NtLh
bz/4Au5zF3nYGscDAAAAAElFTkSuQmCC
"
	tablelist_ubuntu_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAiElEQVQoz72SoQoCURREz11YweIv
uFEQo83id+wvWMT/M4nFbhCxLNjXKMixaHks6xPEaQOHO8xw4S9Sp9/AN3WTC9/Vq3roSikSXwIn
YATs05RILwO7lx0CY6AB6og498FvzYAHMC96KgyACXABFhHRdBXcqke1Vde5a1SfpmvVVe7Oy5+9
wxNzbFn4+q5BGgAAAABJRU5ErkJggg==
"
	tablelist_ubuntu_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAj0lEQVQoz9WRMQ4BARBF30ejICKa
jUg4z15EOMsewC00nEOhlJAoHEDUT7MrCkQl8ZufmXnF/Bn4P0WdAlug/4G7AWUnyUmtgAVwfAHO
gFWSQ5qOugF6wOUJLIBrkhKg9TSYA0OgW9ddYAQsG+ABJzkDFTAG2rVXSU5vk6hrdV+v9Vlqoe7U
yVf3VAe//eAdhJ0u3C54tZ8AAAAASUVORK5CYII=
"
    } else {
	tablelist_ubuntu_collapsedImg put "
R0lGODlhCwAOAKECAAAAAExMTP///////yH5BAEKAAAALAAAAAALAA4AAAIWhI+py8EWYotOUZou
PrrynUmL95RLAQA7
"
	tablelist_ubuntu_expandedImg put "
R0lGODlhCwAOAKECAAAAAExMTP///////yH5BAEKAAAALAAAAAALAA4AAAIThI+pyx0P4Yly0pDo
qor3BoZMAQA7
"
	tablelist_ubuntu_collapsedSelImg put "
R0lGODlhCwAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAALAA4AAAIWhI+py8EWYotOUZou
PrrynUmL95RLAQA7
"
	tablelist_ubuntu_expandedSelImg put "
R0lGODlhCwAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAALAA4AAAIThI+pyx0P4Yly0pDo
qor3BoZMAQA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::ubuntu2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::ubuntu2TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable ubuntu2_${mode}Img \
		 [image create photo tablelist_ubuntu2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_ubuntu2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAkAAAAOCAYAAAD9lDaoAAAAP0lEQVQoz2NgGFBQRYyijwwMDBaE
FB1mYGDYh66QCYtCVgYGhjZkhUzkOByrddgUYShgRuNLMjAwLB/YWGAAAKvHB5tkvnheAAAAAElF
TkSuQmCC
"
	tablelist_ubuntu2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAkAAAAOCAYAAAD9lDaoAAAAUElEQVQoz9XMsQmAQBSD4U+vcAJL
O5dxI7FxLGuxORzFFWxs3oEIDnBpEsKfUKma8AXTD7OlCAcG9Oiiu5GxptdixxhgixMzpM91Aa8C
VK0HIeMJSGA/nM0AAAAASUVORK5CYII=
"
	tablelist_ubuntu2_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAkAAAAOCAYAAAD9lDaoAAAAQElEQVQoz2NgGFAgjk2QCY3Py8DA
wENIEcP////1sClEBir/IcAKWSETOQ5XQTcFqyJsCpjR+KwMDAzvBzYWGACK6w9f19Y/wAAAAABJ
RU5ErkJggg==
"
	tablelist_ubuntu2_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAkAAAAOCAYAAAD9lDaoAAAAP0lEQVQoz2NgGKKAEUqLMDAw8OJQ
8xmZw/f//3+D/whgw8DAwI1sErJCJQYGBh5GRsbzDAwMX3E5gQ9mwpAHAI7TFKfP6kUoAAAAAElF
TkSuQmCC
"
    } else {
	tablelist_ubuntu2_collapsedImg put "
R0lGODlhCQAOAMIEAAAAAA4ODjw8PEFBQf///////////////yH5BAEKAAEALAAAAAAJAA4AAAMR
GLrc/nAJKMYT1WHbso5gGCYAOw==
"
	tablelist_ubuntu2_expandedImg put "
R0lGODlhCQAOAMIEAAAAADw8PEFBQUpKSv///////////////yH5BAEKAAAALAAAAAAJAA4AAAMR
CLrc/jCqQCsbVLihpf+glAAAOw==
"
	tablelist_ubuntu2_collapsedSelImg put "
R0lGODlhCQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAJAA4AAAIOhI+py43BAlRyTYez
BgUAOw==
"
	tablelist_ubuntu2_expandedSelImg put "
R0lGODlhCQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAJAA4AAAINhI+py+0WYlDx2YtX
AQA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs {{treeStyle "vistaAero"}} {
    variable scalingpct
    vistaAeroTreeImgs_$scalingpct $treeStyle
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_100
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_100 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAZElE
QVQoU2P4//8/A1GApgotgZgbwsQCkBRGAHE4EAuDeegATaEoEKcAsTRIAAUgK4SyQSbmA7EqiAMH
6AqhfAkgrgViQRAHDLCYKATE+E0EYhEgJuxGICbK10SHI35AnEIGBgDfPzypQe1LowAAAABJRU5E
rkJggg==
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAASklE
QVQoU2P4//8/A1Fg8Cl0BOJyCBMKsCgEKboCxDfBPBhAUwhWFBERARLEqRCuCJ9CFEX4FIIcDpJA
xpVAjABYPIMdDJRCBgYA0sVCxaUivcEAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAY0lE
QVQoU2P4//8/A1GAdgpljnyfAsSGYA42gKTwExBfB2JnsAA6QFNYAMQvgTgSLIgMkBWC2EA6CYi/
gWiwBAygK4QqTgfi/0CsAZYEAbJMBGLi3AjERPmauHAkCIhTyMAAAJhFf793qI06AAAAAElFTkSu
QmCC
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAARklE
QVQoU2P4//8/A1FgkCmUOfK9Eog3QrkQgK4Qqug3EKNKICuEKWq6//s/ToXIinAqRFeET+FGkAQa
xu8ZnGCgFDIwAAAYyHMZpMy2ogAAAABJRU5ErkJggg==
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhCgAOAMIHAAAAAIKCgpCQkJubm6enp6ioqMbGxv///yH5BAEKAAcALAAAAAAKAA4AAAMa
eLrc/szAQwokZzx8hONH0HDemG3WI03skwAAOw==
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhCgAOAMIGAAAAACYmJisrK1hYWIaGhoiIiP///////yH5BAEKAAcALAAAAAAKAA4AAAMY
eLrc/jCeAkV4YtyWNR/gphRBGRBSqkoJADs=
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhCgAOAMIGAAAAABzE9ybG9y/J9z/N+Hvc+v///////yH5BAEKAAcALAAAAAAKAA4AAAMa
eLrc/qzAIwgUZzxMHT9Bw30LpnnWI03skwAAOw==
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhCgAOAMIEAAAAAB3E92HW+YLf+////////////////yH5BAEKAAAALAAAAAAKAA4AAAMX
CLrc/jACAUN4YdyWNR/gpgiWRUloGiUAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_125
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_125 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwQAADsEBuJFr7QAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAfElE
QVQ4T6XSSwqAMAwE0NygYBUP4M4jeBK37l269upx0AgZKdag8NCZNogfUdWwYllTLGs4iEyQfFfC
QWQ2ne+fOFwDGRbo/ZrHAUN2bmCFwa/fONiQXSfYYPR7zjUKbshyCztk6in8uROO2DNB/O2Z0HeK
/xFfFct3Kgd7BgT8X0rnFQAAAABJRU5ErkJggg==
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAX0lE
QVQ4T5WLwQ3AIAzEWIWF+GcUBuwQnSaECqQqOTiI5Ed8clLVa6BkQMmAkgHlxC4bJXgvJiN4jDds
XnxyBCLSHx79g6PIBzRCwTZaBSwqfVxQYXQLlAwoGVDu0dQApYwcjGzIaS0AAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwQAADsEBuJFr7QAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAjElE
QVQ4T5XSzQ1AQBAFYIVI1KAGFTi67tVFFSpQkj5cXDTAcbxJduWNbNg5fNl9wyN+KhFxyw7/ZId/
TKjXa4GWZzkmoLDDBh3P30yIpREOGPgYM0FLcQ1wwsTHExNSKe6HZr0E68znKBO4FHMPWgw8fzaK
S9j77qRXhvJnAv/bA/d38v8RpbLDb1LdInxaO2Da/xgAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAZUlE
QVQ4T5WQsQ2AMAwEMwhTMVI2yg7swQa0FCmMkbAURx+/Ka74s65xEZHfQMmAkgElA0pjO+5dabN3
Y+QLLkWnv7lhWFDPLqloDFLRHNAIBWG0CljU3uOC/MsjoGRAyYAyRsoDbx1o4rZ56f0AAAAASUVO
RK5CYII=
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhDQAQAMIHAAAAAIGBgYuLi5OTk56enqenp8XFxf///yH5BAEKAAcALAAAAAANABAAAAMg
eLrc/tCZuEqh5xJ6z4jdIUDhETzhiCofeWxg+UxYjSUAOw==
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhDQAQAMIGAAAAACYmJjo6OllZWYaGhrGxsf///////yH5BAEKAAcALAAAAAANABAAAAMe
eLrc/jDKVqYIUgwM9e5DyDWe6JQmUwRsS0xwLDsJADs=
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhDQAQAMIHAAAAAB7E9yTG9y/J9zTK9zjL+Hvc+v///yH5BAEKAAcALAAAAAANABAAAAMg
eLrc/tCZuEihh5xB9RGRdwSQOD4iiSpguXUXNWE0lgAAOw==
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhDQAQAMIFAAAAABzE9yvH92HW+YLf+////////////yH5BAEKAAcALAAAAAANABAAAAMe
eLrc/jDKNqYIUhAM9e5EyDWe6JQmMwRsW01wLDcJADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_150
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_150 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAkklE
QVQ4T63Tqw6AMAwF0GocjwSBIdlv8B84LBKD4evHHVS0S3ltLDmB20JDYJD3PotZ/MIsfqED0QCl
rD3RgWhkjazf0eG8uYIJWtm7ogMG8LGGGTrZt+jAA/g8DFmgl9fEdBADOIchKzhZl3SIBnDNwQZF
3Dv6Kvz5BFjp7wAr/StA3j5gyTsx719IYRbf87QDkkXd7AZZ8UwAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAaklE
QVQ4T6WM0QnAIAwF3a4zOIl0z/50mjSBBkSukkeF+/D0XjOzX6BUQKmAUgGlAsoZP4cz6C1Ambzx
5dz0HqAMMu69x0UbmGN5YI2lAYrLA19xaWAXB5WBEZ82nGuYoFRAqYBSAWUdaw84XP55BTs9TwAA
AABJRU5ErkJggg==
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAkklE
QVQ4T6WTuw2AMAxEMwjLsAItJQ0l27AQ81BQQGlsyZF8kSG/4sncmTtFIgQi6sI1a3DNGkAMx7Mz
k/VygODwxZzMbP0/QGjBqnOxuy9ASFCnlNwy7d4DRCzQ51iy2XdSQNgC1dkSEGmBelJCzJjuBBBp
gYbbTlASFkDEAhOu/woabr8HTNdN7PsXWnDNcii8/8FGqvnrvTkAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAcElE
QVQ4T6WSsQ2AIBQFGcQh7e3ciB1cwziGBcX3k0hCzEn+0+IKDu5VJDP7BUoFlAooFVAqoOyZtnN2
Mt1VUDbuuDh+5DcoKy1e9mLyQB+vhzjwjKUBisMDb3FoYBRHB3J9NODbP4iAUgGlAso4li4fLlnw
8CctEgAAAABJRU5ErkJggg==
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhEAASAOMIAAAAAIaGhouLi5CQkJiYmKGhoaioqMPDw///////////////////////////
/////yH5BAEKAAAALAAAAAAQABIAAAQrEMhJq70426OrMd0EFiEAAkR4AkO3AoL2AkH2xvbUylLq
AiTVLMMpGY+ACAA7
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhEAASAMIGAAAAACYmJisrK1lZWYaGhoiIiP///////yH5BAEKAAcALAAAAAAQABIAAAMj
eLrc/jDKSWepR4Qqxp6dBw7kB4VlhKbPyjZFIM8Bgd14DiUAOw==
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhEAASAMIFAAAAABzE9ybG9yvH93jc+v///////////yH5BAEKAAcALAAAAAAQABIAAAMj
eLrc/jA6IpsYdYmzc+8SCELj6JhBVIZa9XlcxmEyJd/4kQAAOw==
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhEAASAMIFAAAAAB3E92HW+Xvd+4Lf+////////////yH5BAEKAAcALAAAAAAQABIAAAMj
eLrc/jDKSaeoJ4Qaxp4d8UWhKJUmhKbOyjKCJmsXZt/4kwAAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_200
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_200 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUWORalREAAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAJNJREFUOE+10zsKgDAQBNCt7fyAhY2Qa3gPO1tLGxtPHye4RdgNJpI1
8DBOwiBqyHtvLhnWSoa1dEC0QCvzL3RAtLJBrpXSwVPYwQajXC+hA5TytYcdJrknRwdcyvNQfMAc
78nRQVTK96H4BBfnb3QgSjlzcEEj11J08PeTYti+Uwzbrw/2/ykzPVH2Z99CMqzj6QYGRertj0pe
+AAAAABJRU5ErkJggg==
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUeBx8d0+MAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAGtJREFUOE+tzMEJwCAQRFG7Sw1biaTPXFLNxoUIi3w9OArv4Ii/uPtx
OKpwVOGowlGF46idq6n0RnDM/uDTvPROcOx60Mziokdz8Eh0DMpRCkrRWXA7ugqG3WiNjwt3/riC
owpHFY4qHDVePsGgC4kbm9dDAAAAAElFTkSuQmCC
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUVIS7kj9UAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAJNJREFUOE+tkzEKgDAMRT2Il/EKro4ujt7GC3keBwcdYwIplPxAW5vh
UX0pj4J2IKJwXNmLK3sBMZ7vwczWtwCCgzdzMYud1QJCo5uuq53XAEJiukr4kdXuKQEiRfU5hfd8
TwkQeVTfm8MgbFSdhImZ7MwDhI1qMO6kf4ICiBTNgjFfX4Ox/ykTfqPi734EruyDhg9wSVOrXMoi
bgAAAABJRU5ErkJggg==
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUbEg+3w00AAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAHJJREFUOE+t0rENgCAURVEGcUh7OzdiB9cwjmFB8cVEEvJzpeD94hQ+
5FYkMwuHowpHFY4qHFU4estxr1WmM4Jj7wuWqn7yPx6OTQtuZ7GQaB/cr4CoD8pRCkrRv+B0dBRU
ovm9OBD3TmfgqMJRhaPG0gNGBmbxSYGdJwAAAABJRU5ErkJggg==
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhFQASAOMIAAAAAIaGhouLi5CQkJiYmKGhoaioqMPDw///////////////////////////
/////yH5BAEKAAAALAAAAAAVABIAAAQvEMhJq7046w0Ox4bxWWIxUiJAnFIKDKwLCKcMBKNM5xNc
S6sYwMQChIoSD3LJjAAAOw==
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhFQASAMIGAAAAACYmJisrK1lZWYaGhoiIiP///////yH5BAEKAAcALAAAAAAVABIAAAMl
eLrc/jDKSauV5TIRtBJDp4HhOJxiRaLWylLuiwV0HRBeru97AgA7
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhFQASAMIFAAAAABzE9ybG9yvH93jc+v///////////yH5BAEKAAcALAAAAAAVABIAAAMn
eLrc/jDKeQiFYlwnTt/L94HjeJnmlAYbSoagp6RUR9darFh67y8JADs=
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhFQASAMIFAAAAAB3E92HW+Xvd+4Lf+////////////yH5BAEKAAcALAAAAAAVABIAAAMl
eLrc/jDKSauV4rIQtApDp4GEaJHlhabVyk7uGwlczWVeru96AgA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs {{treeStyle "vistaClassic"}} {
    variable scalingpct
    vistaClassicTreeImgs_$scalingpct $treeStyle
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_100
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_100 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhDAAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAMAA4AAAIjnI+pyxMP4QmiWhGm
BTYbWnGV5wjAeWJa2K1m+12wE0XNvRQAOw==
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhDAAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAMAA4AAAIgnI+pyxMP4QmiWhHm
tdnQjWnAOIYeaDpop4JsBDfyUgAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_125
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_125 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhDwAQAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAPABAAAAIsnI+pyz0BowwoiIsx
PRaDvBnd9WlVVl7hIwDu+61jC55ezaG4mPXyNHEIhwUAOw==
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhDwAQAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAPABAAAAIonI+pyz0BowwoiIsx
PTbnbXTeBT6jVgnAygJCKY7wSab0fFfT5PR+AQA7
"
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_150
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_150 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhEgASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAASABIAAAI4nI+py+0Bo4wpiIuz
CFUDzSFW9mXhMWIldhrptV7tYAH2fW8dCe5qL/IAUUKTT8OqTJYzh/NpKAAAOw==
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhEgASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAASABIAAAIynI+py+0Bo4wpiIuz
CFV7jlheBh7ieJXGiaqDBcSyvHVoat8uO+43HvrVQpOiy4FMGgoAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_200
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_200 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAJHnI+pFu0Pmwqi2ovD
xPzqRGHAyH1IeI1AuYlk1qav16q2XZlHePd53cMJdAyOigUyAlawpItJc8qgFuIA1Wmesh1r5PtQ
FAAAOw==
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAI+nI+pFu0Pmwqi2ovD
xPzqRHXdh4Ritp0oqK5lBcTyDFTkEdK6neo0z2pZbgzhMGUkDkxCJbPlNAJLkapDUQAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::win7AeroTreeImgs
#------------------------------------------------------------------------------
proc tablelist::win7AeroTreeImgs {} {
    vistaAeroTreeImgs "win7Aero"
}

#------------------------------------------------------------------------------
# tablelist::win7ClassicTreeImgs
#------------------------------------------------------------------------------
proc tablelist::win7ClassicTreeImgs {} {
    vistaClassicTreeImgs "win7Classic"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs {} {
    variable scalingpct
    win10TreeImgs_$scalingpct
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_100
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_100 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAKCAYAAAC9vt6cAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAExJREFUKFNj+P//P0UYwWBg0AFiB2RJYjCCAdQMxJGkGoLKIcMQTAESDcEuyMAQ
DDVEB5s8MsYUoMQFpGoGYQSDDM0gjGCQlQ7+MwAAiH+aQTbAbFoAAAAASUVORK5CYII=
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAKCAYAAAC9vt6cAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAFRJREFUKFNj+P//P0UYqyApGATigbgDh2QHSB6bHAzDFO0H0WgSWMXRMYRAU4zO
x4cRDKgmHx8fEIcozSCMyiHBZhjGFCAQaOgYqyApGKsg8fg/AwClVaMkbFpt/wAAAABJRU5ErkJg
gg==
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhEAAKAMIGAAAAAKampqysrL+/v9LS0tTU1P///////yH5BAEKAAcALAAAAAAQAAoAAAMZ
eLrcS8PJM0KcrV68NGdCUHyURXof+kFkAgA7
"
	tablelist_win10_expandedImg put "
R0lGODlhEAAKAMIHAAAAAEBAQExMTHd3d5+fn6CgoKGhof///yH5BAEKAAcALAAAAAAQAAoAAAMb
eLrc/oyMNsobYSqsHT8fBAZCJi7hqRhq6z4JADs=
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhEAAKAMIGAAAAAE7Q+VjS+Xra+5vh/Jri/P///////yH5BAEKAAcALAAAAAAQAAoAAAMZ
eLrcW8PJM0KcrV68NGdCQHyURXof+kFkAgA7
"
    tablelist_win10_expandedActImg put "
R0lGODlhEAAKAMIGAAAAABzE9yjH+FbS+YDb+4Lc+////////yH5BAEKAAcALAAAAAAQAAoAAAMb
eLrc/oyMNsobYSqsHT8fBAZCJi7hqVhq6zoJADs=
"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_125
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_125 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABoAAAAMCAYAAAB8xa1IAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAF1JREFUOE+9lMEJwDAMA71QJ+gG3aD7D+JK0EKN9QlYCdxDl8eRTyIzt1BHxAGu
v5uiDkTA7Yh1YYppaYhJSaZjUn68IXKq+xWkJDj+F01HSBeGCKnDFCF12H6GjAdLF1EmW/vAagAA
AABJRU5ErkJggg==
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABoAAAAMCAYAAAB8xa1IAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAGNJREFUOE+9j4EJwCAMBDNqN3GUjuJosY8Eqf0UqUmFU3MfIoqq/gKVGVCZAdZx
cbLQQI4+lq1iQypOp+E1X6VvzjDPf2FcpqFzvcu9GMONkEfAUwT/xOBSpDC/A5UZUBmPSgPj7VvG
j4QeDgAAAABJRU5ErkJggg==
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhGgAMAMIFAAAAAKamprW1tcTExNLS0v///////////yH5BAEKAAcALAAAAAAaAAwAAAMi
eLrc/ocISJ8Is2p1867dp4UiFQRDaWGqQ7bLCx/yLM1KAgA7
"
	tablelist_win10_expandedImg put "
R0lGODlhGgAMAMIHAAAAAEBAQEFBQWBgYICAgJ+fn6CgoP///yH5BAEKAAcALAAAAAAaAAwAAAMi
eLrc/jDKSct4w9A1wmXdtx0h543gWaKpcLLNCjfEbN9oAgA7
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhGgAMAMIGAAAAAE7Q+WfV+mjV+oHc+5ri/P///////yH5BAEKAAcALAAAAAAaAAwAAAMj
eLrc/qcISJ8Is2p1867X8GnhWAUBYVrY6nRuA8fLTCvSfSQAOw==
"
    tablelist_win10_expandedActImg put "
R0lGODlhGgAMAMIGAAAAABzE9z7M+F/U+oDb+4Hc+////////yH5BAEKAAcALAAAAAAaAAwAAAMi
eLrc/jDKSYl4otAlwmXdtx0h543gWaJpcLLNCjfDbN9oAgA7
"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_150
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_150 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAB8AAAAQCAYAAADu+KTsAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAIZJREFUSEvNlbENgDAMBD0IDQNQswQLsP8gxi8R5OCvkOMQ6YocSOc0iajqNLgU
WZjPJgqRzTiN/f0tm35jJ77DjaEDRGFBFx86AJdFA1AJEHTxIQNQ2UDQxdMHoNJj63BxsLL/vkBl
w9ackyPkoulhwGVBGERRFAb95gc33Jy7/ZElr5rKBVezH+eTfDdNAAAAAElFTkSuQmCC
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAB8AAAAQCAYAAADu+KTsAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAJVJREFUSEvFkNkNgCAQRLcvCrAIfqzC9iwNmXiwukPiASvJ43i7YVBJKf0GlV5Q
6UXZiARdqHG37w7rJDJm5sx0bdCgvvWNrP4UjLBduEMfAK96wOc/sE724tMDcFY1U39L2VQCsCp3
+BacD5egGCNkl2Bghf3SLsGAS/uA5sGASoDAnsGAyp08BuZbQaUXVHpBpQ9JFsLONZHqquN4AAAA
AElFTkSuQmCC
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhHwAQAOMIAAAAAKamprOzs8jIyNLS0t7e3uPj4+Tk5P//////////////////////////
/////yH5BAEKAAAALAAAAAAfABAAAAQ3EMhJq7344M0lCUMnUkZghuM4mGCqsqjLrafc0a29CWyh
X7jYbxIcVopGIiw5KdWYk48QCtBAIwA7
"
	tablelist_win10_expandedImg put "
R0lGODlhHwAQAOMJAAAAAEBAQFtbW4mJiZ+fn6CgoLi4uMTExMXFxf//////////////////////
/////yH5BAEKAA8ALAAAAAAfABAAAAQ58MlJq7046807RRnoUUQwXENQjNIRvCeVvgf7zOaEx/Z+
vzmbDigA8oQSHAxp8TGbwafFIK1ar9IIADs=
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhHwAQAMIHAAAAAE7Q+WTV+oje+5ri/K3m/bbo/f///yH5BAEKAAcALAAAAAAfABAAAAM0
eLrc/tDASRUJo2pmgs/bNnhYKJKgSY2fWrGlOwlkIT9wei/53vQ+Hiq46LSIi4sOeZAgEwA7
"
    tablelist_win10_expandedActImg put "
R0lGODlhHwAQAOMJAAAAABzE9zjK+GnW+oDb+4Hc+5rh/Kfl/ajl/f//////////////////////
/////yH5BAEKAA8ALAAAAAAfABAAAAQ58MlJq7046807RRnoUUQwXENQjNIRvCeVvgf7zOaEx/Z+
vzmbDigA8oQSHAxp8TGbwafFIK1ar9IIADs=
"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_200
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_200 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAACgAAAASCAYAAAApH5ymAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAJJJREFUSEvV1rENwCAMRFEGykDZfxGHKyyh45fYIpFe8+PiSkZEoPk91LtxnOOm
V+h/pz0s45LfdOJoA4XuOmAUHyh0Vw1j8oFCd5Uwrnyg0F0VjM4HCt1VwEh8oNDdaRiJjxO6Ow2j
82FCdxUwrnyY0F0VjMmHCd1Vwig+TOiuGsdLxskefvJYuPe5lTSSeq8YH+NamKxWvX/LAAAAAElF
TkSuQmCC
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAACgAAAASCAYAAAApH5ymAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAJFJREFUSEvNzgEKgCAMhWFv2k272nKItdZvWDRa8Ik9J74iIqlhmAmGmRybUhZ7
MOPNnafaUh+qVuUHRvp8FVpSv71cR4OWn6/CSrbl+uCwpJ9TNPeVYzPxsD9XfuZr55+bAj5X9m6U
awBFiL8XhUMoZNGdKBgqX6qj2UgYdn+XUxhaf5ZTGGaCYSYYZoJhHlI2JrC2jqb+LJ4AAAAASUVO
RK5CYII=
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhKAASAMIHAAAAAKampqenp6ioqNLS0tPT09TU1P///yH5BAEKAAcALAAAAAAoABIAAANB
eLq1/jDKV4KYOEMT+tUgJnRWaEajd67LQH7s6ZLxOne1TAZ5ePO9zC8o3BExN9gRklxKUiUnpKKS
RghR61W7SAAAOw==
"
	tablelist_win10_expandedImg put "
R0lGODlhKAASAMIGAAAAAEBAQEJCQp+fn6CgoKGhof///////yH5BAEKAAcALAAAAAAoABIAAAM/
eLrc/jDKSau9qlCN4QiCJARE5xBBGj5jyplLCzryCjM1ns43va+5HusXFA53KqMIaVNCWk3nMyqt
Wq/YrCUBADs=
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhKAASAMIFAAAAAE7Q+VHQ+Zrh/Jri/P///////////yH5BAEKAAcALAAAAAAoABIAAAM9
eLqz/jDKN4KYOMMarP6Z0HlgCYndZa4K2rGsG8CrTJv2/eU6xveSH/A0mg2DI9WRmFpGOCQnhBCV
Tq2LBAA7
"
    tablelist_win10_expandedActImg put "
R0lGODlhKAASAMIEAAAAAB3E94Db+4Hc+////////////////yH5BAEKAAAALAAAAAAoABIAAAM6
CLrc/jDKSau9alCNoQiBBHIdM4AghAZkqaxhA7vOvNi0vL57/sA4Xw0YE6qCxh8qSUkxn9CodFpK
AAA7
"
}

#------------------------------------------------------------------------------
# tablelist::winnativeTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winnativeTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winnative_${mode}Img \
		 [image create photo tablelist_winnative_${mode}Img]
    }

    tablelist_winnative_collapsedImg put "
R0lGODlhDwAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAPAA4AAAImnI+pyz0BY1RB2CsC
veDqVFmd9SEVgKLZJnqsMK4g5oKS5OS6UQAAOw==
"
    tablelist_winnative_expandedImg put "
R0lGODlhDwAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAPAA4AAAIjnI+pyz0BY1RB2CsC
xVenymUbQJLiF54IyHlr6h7S7NS2UQAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::winxpBlueTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winxpBlueTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winxpBlue_${mode}Img \
		 [image create photo tablelist_winxpBlue_${mode}Img]
    }

    tablelist_winxpBlue_collapsedImg put "
R0lGODlhDwAOAIQeAAAAAHiYtbDC08C3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtjTydvWzNzY
z9/b0uPg2eTh2eXh2urp4+3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+////////yH5BAEK
AB8ALAAAAAAPAA4AAAVK4CeOZGmeaPoJQesGghl4dO0FcqcDHZfhpcBmowFoKhIgKYABOJ0P5Shw
sVAAE0hDKgpEHAzAQoHgfgKJQ4FAGBjMrFcrpqrbPyEAOw==
"
    tablelist_winxpBlue_expandedImg put "
R0lGODlhDwAOAKUgAAAAAHiYtbDC08C3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtfSx9jTydvW
zNzYz9/b0uPg2eTh2eXh2urp4+zr5u3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+///////
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAAPAA4AAAZPwJ9w
SCwaj8jkTxBoOgMCYwBErYIC0o9W69lgi4FOh0O+TL7EgAbAZkPQw0AGY6lQIg64MCB5NBgLCgh6
PwEJBwUEBAMGhExPTVFKk5Q/QQA7
"
}

#------------------------------------------------------------------------------
# tablelist::winxpOliveTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winxpOliveTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winxpOlive_${mode}Img \
		 [image create photo tablelist_winxpOlive_${mode}Img]
    }

    tablelist_winxpOlive_collapsedImg put "
R0lGODlhDwAOAIQdAAAAAI6ZfcC3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtjTydvWzNzYz9/b
0uPg2eTh2eXh2urp4+3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+////////////yH5BAEK
AB8ALAAAAAAPAA4AAAVH4CeOZGmeaCoGbBucQSfP3VsGXA5wG2aTAY0mA8hQIr9R4AJoNh3JlaUy
AUgejOgnAGksAIrEQRtAGAiDgaCg3bpYqrh8FAIAOw==
"
    tablelist_winxpOlive_expandedImg put "
R0lGODlhDwAOAKUfAAAAAI6ZfcC3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtfSx9jTydvWzNzY
z9/b0uPg2eTh2eXh2urp4+zr5u3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+///////////
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKACAALAAAAAAPAA4AAAZLQJBw
SCwaj8ikMMBsBo6Bj3T6eRYDnmy2o7ESAxzOZmyReIeBDGC9fpyXmEuFMoE03qBAxMFYKBIHeAEI
BgQDAwIFeHlOTEqPkENBADs=
"
}

#------------------------------------------------------------------------------
# tablelist::winxpSilverTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winxpSilverTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winxpSilver_${mode}Img \
		 [image create photo tablelist_winxpSilver_${mode}Img]
    }

    tablelist_winxpSilver_collapsedImg put "
R0lGODlhDwAOAIQXAAAAAJSVosTO2MXP2cbO2svT3NPZ4tXb5Nnf5trg593i6d/l6uDm6+bq7ufr
7+zv8+/y9PLz9vT39/b3+ff4+vn6+v39/f///////////////////////////////////yH5BAEK
AB8ALAAAAAAPAA4AAAVF4CeOZGmeaCoGbBucwSXP11sGVg7klE0GlQoFQIk4fKPABMBkMpArSQQC
eDQU0E+gsUgAEAdDNnAoDM4CQlbrYqne8FEIADs=
"
    tablelist_winxpSilver_expandedImg put "
R0lGODlhDwAOAIQYAAAAAJSVosTO2MXP2cbO2svT3NPZ4tXb5Nnf5trg593i6d/l6uDm6+bq7ufr
7+zv8+/x8+/y9PLz9vT39/b3+ff4+vn6+v39/f///////////////////////////////yH5BAEK
AB8ALAAAAAAPAA4AAAVD4CeOZGmeaCoGbBucASbP2FsGV65XNhlYlopQ4uiNAhSAUskwriaSCOTR
UDg/gcYikUAcDNfAoTAoCwhXrIulartHIQA7
"
}

#------------------------------------------------------------------------------
# tablelist::yuyoTreeImgs
#------------------------------------------------------------------------------
proc tablelist::yuyoTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable yuyo_${mode}Img \
		 [image create photo tablelist_yuyo_${mode}Img]
    }

    tablelist_yuyo_collapsedImg put "
R0lGODlhDwAOAOMKAAAAAIiKhby9ur7AvMDBvsrMyd3e3eHi4OHi4f7+/v//////////////////
/////yH5BAEKAA8ALAAAAAAPAA4AAARA8MlJq72zjM1HqQWSKCSZIN80jORRJgM1lEpAxyptl7g0
E4Fg0KDoPWalHcmIJCmLMpZC8DKGpCYUqMNJYb6PCAA7
"
    tablelist_yuyo_expandedImg put "
R0lGODlhDwAOAOMIAAAAAIiKhb7AvMDBvsrMyd3e3eHi4f7+/v//////////////////////////
/////yH5BAEKAA8ALAAAAAAPAA4AAAQ58MlJq72TiM0FqYRxICR5GN8kjGV5CJTQzrA6t7UkD0Hf
F4jcQ3YjCYnFI2v2ooSWJhSow0lhro8IADs=
"
}

#------------------------------------------------------------------------------
# tablelist::createTreeImgs
#------------------------------------------------------------------------------
proc tablelist::createTreeImgs {treeStyle depth} {
    set baseWidth  [image width  tablelist_${treeStyle}_collapsedImg]
    set baseHeight [image height tablelist_${treeStyle}_collapsedImg]

    #
    # Get the width of the images to create for the specified depth and
    # the destination x coordinate for copying the base images into them
    #
    set width [expr {$depth * $baseWidth}]
    set x [expr {($depth - 1) * $baseWidth}]
    if {[string compare $treeStyle "win10"] == 0} {
	variable scalingpct
	switch $scalingpct {
	    100 { set factor -8 }
	    125 { set factor -16 }
	    150 { set factor -19 }
	    200 { set factor -24 }
	}
    } elseif {[regexp {^(vistaAero|win7Aero)$} $treeStyle]} {
	variable scalingpct
	switch $scalingpct {
	    100 { set factor  0 }
	    125 { set factor -3 }
	    150 { set factor -6 }
	    200 { set factor -11 }
	}
    } elseif {[regexp {^(vistaClassic|win7Classic)$} $treeStyle]} {
	variable scalingpct
	switch $scalingpct {
	    100 { set factor -2 }
	    125 { set factor -5 }
	    150 { set factor -8 }
	    200 { set factor -13 }
	}
    } elseif {[regexp {^(mate|ubuntu)$} $treeStyle]} {
	set factor -2
    } elseif {[regexp {^mint2$} $treeStyle]} {
	set factor -1
    } elseif {[regexp \
	    {^plastik$} $treeStyle]} {
	set factor 2
    } elseif {[regexp \
	    {^plastique$} $treeStyle]} {
	set factor 3
    } elseif {[regexp \
	    {^(baghira|klearlooks|oxygen.|phase|plasti.+|winnative|winxp.+)$} \
	    $treeStyle]} {
	set factor 4
    } else {
	set factor 0
    }
    set delta [expr {($depth - 1) * $factor}]
    incr width $delta
    incr x $delta

    foreach mode {indented collapsed expanded} {
	image create photo tablelist_${treeStyle}_${mode}Img$depth \
	    -width $width -height $baseHeight
    }

    foreach mode {collapsed expanded} {
	tablelist_${treeStyle}_${mode}Img$depth copy \
	    tablelist_${treeStyle}_${mode}Img -to $x 0

	foreach modif {Sel Act SelAct} {
	    variable ${treeStyle}_${mode}${modif}Img
	    if {[info exists ${treeStyle}_${mode}${modif}Img]} {
		image create photo \
		    tablelist_${treeStyle}_${mode}${modif}Img$depth \
		    -width $width -height $baseHeight
		tablelist_${treeStyle}_${mode}${modif}Img$depth copy \
		    tablelist_${treeStyle}_${mode}${modif}Img -to $x 0
	    }
	}
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistMove.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
#==============================================================================
# Contains the implementation of the tablelist move and movecolumn subcommands.
#
# Copyright (c) 2003-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#------------------------------------------------------------------------------
# tablelist::moveRow
#
# Processes the 1st form of the tablelist move subcommand.
#------------------------------------------------------------------------------
proc tablelist::moveRow {win source target} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || $data(itemCount) == 0} {
	return ""
    }

    #
    # Adjust the indices to fit within the existing items and check them
    #
    if {$source > $data(lastRow)} {
	set source $data(lastRow)
    } elseif {$source < 0} {
	set source 0
    }
    if {$target > $data(itemCount)} {
	set target $data(itemCount)
    } elseif {$target < 0} {
	set target 0
    }

    set sourceItem [lindex $data(itemList) $source]
    set sourceKey [lindex $sourceItem end]
    if {$target == [nodeRow $win $sourceKey end] || $target == $source} {
	return ""
    }

    set parentKey $data($sourceKey-parent)
    set parentEndRow [nodeRow $win $parentKey end]
    if {($target <= [keyToRow $win $parentKey] || $target > $parentEndRow)} {
	return -code error \
	       "cannot move item with index \"$source\" outside its parent"
    }

    if {$target == $parentEndRow} {
	set targetChildIdx end
    } else {
	set targetKey [lindex $data(keyList) $target]
	if {[string compare $data($targetKey-parent) $parentKey] != 0} {
	    return -code error \
		   "cannot move item with index \"$source\" outside its parent"
	}

	set targetChildIdx \
	    [lsearch -exact $data($parentKey-children) $targetKey]
    }

    return [moveNode $win $source $parentKey $targetChildIdx]
}

#------------------------------------------------------------------------------
# tablelist::moveNode
#
# Processes the 2nd form of the tablelist move subcommand.
#------------------------------------------------------------------------------
proc tablelist::moveNode {win source targetParentKey targetChildIdx \
			 {withDescendants 1}} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || $data(itemCount) == 0} {
	return ""
    }

    #
    # Adjust the indices to fit within the existing items and check them
    #
    if {$source > $data(lastRow)} {
	set source $data(lastRow)
    } elseif {$source < 0} {
	set source 0
    }
    set target [nodeRow $win $targetParentKey $targetChildIdx]
    if {$target < 0} {
	set target 0
    }

    set sourceItem [lindex $data(itemList) $source]
    set sourceKey [lindex $sourceItem end]
    if {$target == [nodeRow $win $sourceKey end] && $withDescendants} {
	return ""
    }

    set sourceParentKey $data($sourceKey-parent)
    if {[string compare $targetParentKey $sourceParentKey] == 0 &&
	$target == $source && $withDescendants} {
	return ""
    }

    set sourceDescCount [descCount $win $sourceKey]
    if {$target > $source && $target <= $source + $sourceDescCount &&
	$withDescendants} {
	return -code error \
	       "cannot move item with index \"$source\"\
		before one of its descendants"
    }

    set w $data(body)
    if {$data(anchorRow) != $source} {
	$w mark set anchorRowMark [expr {double($data(anchorRow) + 1)}]
    }
    if {$data(activeRow) != $source} {
	$w mark set activeRowMark [expr {double($data(activeRow) + 1)}]
    }

    #
    # Save some data of the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editRow $data(editRow)
	set editKey $data(editKey)
	saveEditData $win
    }

    #
    # Build the list of column indices of the selected cells
    # within the source line and then delete that line
    #
    set selectedCols {}
    set line [expr {$source + 1}]
    set textIdx [expr {double($line)}]
    variable canElide
    variable elide
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {$data($col-hide) && !$canElide} {
	    continue
	}

	#
	# Check whether the 2nd tab character of the cell is selected
	#
	set textIdx [$w search $elide "\t" $textIdx+1c $line.end]
	if {[lsearch -exact [$w tag names $textIdx] select] >= 0} {
	    lappend selectedCols $col
	}

	set textIdx $textIdx+1c
    }
    $w delete [expr {double($source + 1)}] [expr {double($source + 2)}]

    #
    # Insert the source item before the target one
    #
    set target1 $target
    if {$source < $target} {
	incr target1 -1
    }
    set targetLine [expr {$target1 + 1}]
    $w insert $targetLine.0 "\n"
    set snipStr $data(-snipstring)
    set dispItem [lrange $sourceItem 0 $data(lastCol)]
    if {$data(hasFmtCmds)} {
	set dispItem [formatItem $win $sourceKey $source $dispItem]
    }
    if {[string match "*\t*" $dispItem]} {
	set dispItem [mapTabs $dispItem]
    }
    set col 0
    foreach text $dispItem colTags $data(colTagsList) \
	    {pixels alignment} $data(colList) {
	if {$data($col-hide) && !$canElide} {
	    incr col
	    continue
	}

	#
	# Build the list of tags to be applied to the cell
	#
	set cellFont [getCellFont $win $sourceKey $col]
	set cellTags $colTags
	if {[info exists data($sourceKey,$col-font)]} {
	    lappend cellTags cell-font-$data($sourceKey,$col-font)
	}

	#
	# Append the text and the labels or window (if
	# any) to the target line of the body text widget
	#
	appendComplexElem $win $sourceKey $source $col $text $pixels \
			  $alignment $snipStr $cellFont $cellTags $targetLine

	incr col
    }
    if {[info exists data($sourceKey-font)]} {
	$w tag add row-font-$data($sourceKey-font) $targetLine.0 $targetLine.end
    }
    if {[info exists data($sourceKey-elide)]} {
	$w tag add elidedRow $targetLine.0 $targetLine.end+1c
    }
    if {[info exists data($sourceKey-hide)]} {
	$w tag add hiddenRow $targetLine.0 $targetLine.end+1c
    }

    set treeCol $data(treeCol)
    set treeStyle $data(-treestyle)
    set indentImg [doCellCget $source $treeCol $win -indent]

    #
    # Update the item list and the key -> row mapping
    #
    set data(itemList) [lreplace $data(itemList) $source $source]
    set data(keyList) [lreplace $data(keyList) $source $source]
    if {$target == $data(itemCount)} {
	lappend data(itemList) $sourceItem	;# this works much faster
	lappend data(keyList) $sourceKey	;# this works much faster
    } else {
	set data(itemList) [linsert $data(itemList) $target1 $sourceItem]
	set data(keyList) [linsert $data(keyList) $target1 $sourceKey]
    }
    if {$source < $target} {
	for {set row $source} {$row < $targetLine} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set data($key-row) $row
	}
    } else {
	for {set row $target} {$row <= $source} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set data($key-row) $row
	}
    }

    #
    # Elide the moved item if the target parent is collapsed or non-viewable
    #
    set depth [depth $win $targetParentKey]
    if {([info exists data($targetParentKey,$treeCol-indent)] && \
	 [string compare $data($targetParentKey,$treeCol-indent) \
	  tablelist_${treeStyle}_collapsedImg$depth] == 0) ||
	[info exists data($targetParentKey-elide)] ||
	[info exists data($targetParentKey-hide)]} {
	doRowConfig $target1 $win -elide 1
    }

    if {$withDescendants} {
	#
	# Update the tree information
	#
	set targetBuddyCount [llength $data($targetParentKey-children)]
	set sourceChildIdx \
	    [lsearch -exact $data($sourceParentKey-children) $sourceKey]
	set data($sourceParentKey-children) \
	    [lreplace $data($sourceParentKey-children) \
	     $sourceChildIdx $sourceChildIdx]
	if {[string first $targetChildIdx "end"] == 0} {
	    set targetChildIdx $targetBuddyCount
	}
	if {$targetChildIdx >= $targetBuddyCount} {
	    lappend data($targetParentKey-children) $sourceKey
	} else {
	    if {[string compare $sourceParentKey $targetParentKey] == 0 &&
		$sourceChildIdx < $targetChildIdx} {
		incr targetChildIdx -1
	    }
	    set data($targetParentKey-children) \
		[linsert $data($targetParentKey-children) \
		 $targetChildIdx $sourceKey]
	}
	set data($sourceKey-parent) $targetParentKey

	#
	# If the list of children of the source's parent has become empty
	# then set the parent's indentation image to the indented one
	#
	if {[llength $data($sourceParentKey-children)] == 0 &&
	    [info exists data($sourceParentKey,$treeCol-indent)]} {
	    collapseSubCmd $win [list $sourceParentKey -partly]
	    set data($sourceParentKey,$treeCol-indent) [strMap \
		{"collapsed" "indented" "expanded" "indented"
		 "Act" "" "Sel" ""} $data($sourceParentKey,$treeCol-indent)]
	    if {[winfo exists $w.ind_$sourceParentKey,$treeCol]} {
		$w.ind_$sourceParentKey,$treeCol configure -image \
		    $data($sourceParentKey,$treeCol-indent)
	    }
	}

	#
	# Mark the target parent item as expanded if it was just indented
	#
	if {[info exists data($targetParentKey,$treeCol-indent)] &&
	    [string compare $data($targetParentKey,$treeCol-indent) \
	     tablelist_${treeStyle}_indentedImg$depth] == 0} {
	    set data($targetParentKey,$treeCol-indent) \
		tablelist_${treeStyle}_expandedImg$depth
	    if {[winfo exists $data(body).ind_$targetParentKey,$treeCol]} {
		$data(body).ind_$targetParentKey,$treeCol configure -image \
		    $data($targetParentKey,$treeCol-indent)
	    }
	}

	#
	# Update the indentation of the moved item
	#
	if {[regexp {^(.+Img)([0-9]+)$} $indentImg dummy base sourceDepth]} {
	    incr depth
	    variable maxIndentDepths
	    if {$depth > $maxIndentDepths($treeStyle)} {
		createTreeImgs $treeStyle $depth
		set maxIndentDepths($treeStyle) $depth
	    }
	    doCellConfig $target1 $treeCol $win -indent $base$depth
	}
    }

    #
    # Update the list variable if present
    #
    if {$data(hasListVar)} {
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
	set var [lreplace $var $source $source]
	set pureSourceItem [lrange $sourceItem 0 $data(lastCol)]
	if {$target == $data(itemCount)} {
	    lappend var $pureSourceItem		;# this works much faster
	} else {
	    set var [linsert $var $target1 $pureSourceItem]
	}
	trace variable var wu $data(listVarTraceCmd)
    }

    #
    # Update anchorRow and activeRow
    #
    if {$data(anchorRow) == $source} {
	set data(anchorRow) $target1
	adjustRowIndex $win data(anchorRow) 1
    } else {
	set anchorTextIdx [$w index anchorRowMark]
	set data(anchorRow) [expr {int($anchorTextIdx) - 1}]
    }
    if {$data(activeRow) == $source} {
	set activeRow $target1
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    } else {
	set activeTextIdx [$w index activeRowMark]
	set data(activeRow) [expr {int($activeTextIdx) - 1}]
    }

    #
    # Invalidate the list of row indices indicating the viewable rows
    #
    set data(viewableRowList) {-1}

    #
    # Select those source elements that were selected before
    #
    foreach col $selectedCols {
	cellSelection $win set $target1 $col $target1 $col
    }

    #
    # Restore the edit window if it was present before
    #
    if {$editCol >= 0} {
	if {$editRow == $source} {
	    doEditCell $win $target1 $editCol 1
	} else {
	    set data(editRow) [keyToRow $win $editKey]
	}
    }

    if {$withDescendants} {
	#
	# Save the source node's list of children and temporarily empty it
	#
	set sourceChildList $data($sourceKey-children)
	set data($sourceKey-children) {}

	#
	# Move the source item's descendants
	#
	if {$source < $target} {
	    set lastDescRow [expr {$source + $sourceDescCount - 1}]
	    set increment -1
	} else {
	    set lastDescRow [expr {$source + $sourceDescCount}]
	    set increment 0
	}
	for {set n 0; set descRow $lastDescRow} {$n < $sourceDescCount} \
	    {incr n; incr descRow $increment} {
	    set indentImg [doCellCget $descRow $treeCol $win -indent]
	    if {[regexp {^(.+Img)([0-9]+)$} $indentImg dummy base descDepth]} {
		incr descDepth [expr {$depth - $sourceDepth}]
		if {$descDepth > $maxIndentDepths($treeStyle)} {
		    for {set d $descDepth} {$d > $maxIndentDepths($treeStyle)} \
			{incr d -1} {
			createTreeImgs $treeStyle $d
		    }
		    set maxIndentDepths($treeStyle) $descDepth
		}
		set descKey [lindex $data(keyList) $descRow]
		set data($descKey,$treeCol-indent) $base$descDepth
	    }

	    moveNode $win $descRow $sourceKey end 0
	}

	#
	# Restore the source node's list of children
	#
	set data($sourceKey-children) $sourceChildList

	#
	# Adjust the columns, restore the stripes in the body text widget,
	# redisplay the line numbers (if any), and update the view
	#
	adjustColumns $win $treeCol 1
	adjustElidedText $win
	redisplayVisibleItems $win
	makeStripes $win
	showLineNumbersWhenIdle $win
	updateColorsWhenIdle $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
    }

    #
    # (Un)hide the newline character that ends the
    # last line if the line itself is (not) hidden
    #
    foreach tag {elidedRow hiddenRow} {
	if {[lsearch -exact [$w tag names end-1l] $tag] >= 0} {
	    $w tag add $tag end-1c
	} else {
	    $w tag remove $tag end-1c
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::moveCol
#
# Processes the tablelist movecolumn subcommand.
#------------------------------------------------------------------------------
proc tablelist::moveCol {win source target} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs
    if {$data(isDisabled)} {
	return ""
    }

    #
    # Check the indices
    #
    if {$target == $source || $target == $source + 1} {
	return ""
    }

    if {[winfo viewable $win]} {
	purgeWidgets $win
	update idletasks
	if {![array exists ::tablelist::ns${win}::data]} {
	    return ""
	}
    }

    #
    # Update the column list
    #
    set source3 [expr {3*$source}]
    set source3Plus2 [expr {$source3 + 2}]
    set target1 $target
    if {$source < $target} {
	incr target1 -1
    }
    set target3 [expr {3*$target1}]
    set sourceRange [lrange $data(-columns) $source3 $source3Plus2]
    set data(-columns) [lreplace $data(-columns) $source3 $source3Plus2]
    set data(-columns) [eval linsert {$data(-columns)} $target3 $sourceRange]

    #
    # Save some elements of data and attribs corresponding to source
    #
    array set tmpData [array get data $source-*]
    array set tmpData [array get data k*,$source-*]
    foreach specialCol {activeCol anchorCol editCol -treecolumn treeCol} {
	set tmpData($specialCol) $data($specialCol)
    }
    array set tmpAttribs [array get attribs $source-*]
    array set tmpAttribs [array get attribs k*,$source-*]
    set selCells [curCellSelection $win]
    set tmpRows [extractColFromCellList $selCells $source]

    #
    # Remove source from the list of stretchable columns
    # if it was explicitly specified as stretchable
    #
    if {[string compare $data(-stretch) "all"] != 0} {
	set sourceIsStretchable 0
	set stretchableCols {}
	foreach elem $data(-stretch) {
	    if {[string first $elem "end"] != 0 && $elem == $source} {
		set sourceIsStretchable 1
	    } else {
		lappend stretchableCols $elem
	    }
	}
	set data(-stretch) $stretchableCols
    }

    #
    # Build two lists of column numbers, needed
    # for shifting some elements of the data array
    #
    if {$source < $target} {
	for {set n $source} {$n < $target1} {incr n} {
	    lappend oldCols [expr {$n + 1}]
	    lappend newCols $n
	}
    } else {
	for {set n $source} {$n > $target} {incr n -1} {
	    lappend oldCols [expr {$n - 1}]
	    lappend newCols $n
	}
    }

    #
    # Remove the trace from the array element data(activeCol) because otherwise
    # the procedure moveColData won't work if the selection type is cell
    #
    trace vdelete data(activeCol) w [list tablelist::activeTrace $win]

    #
    # Move the elements of data and attribs corresponding
    # to the columns in oldCols to the elements corresponding
    # to the columns with the same indices in newCols
    #
    foreach oldCol $oldCols newCol $newCols {
	moveColData data data imgs $oldCol $newCol
	moveColAttribs attribs attribs $oldCol $newCol
	set selCells [replaceColInCellList $selCells $oldCol $newCol]
    }

    #
    # Move the elements of data and attribs corresponding
    # to source to the elements corresponding to target1
    #
    moveColData tmpData data imgs $source $target1
    moveColAttribs tmpAttribs attribs $source $target1
    set selCells [deleteColFromCellList $selCells $target1]
    foreach row $tmpRows {
	lappend selCells $row,$target1
    }

    #
    # If the column given by source was explicitly specified as
    # stretchable then add target1 to the list of stretchable columns
    #
    if {[string compare $data(-stretch) "all"] != 0 && $sourceIsStretchable} {
	lappend data(-stretch) $target1
	sortStretchableColList $win
    }

    #
    # Update the item list
    #
    set newItemList {}
    foreach item $data(itemList) {
	set sourceText [lindex $item $source]
	set item [lreplace $item $source $source]
	set item [linsert $item $target1 $sourceText]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Set up and adjust the columns, and rebuild
    # the lists of the column fonts and tag names
    #
    setupColumns $win $data(-columns) 0
    makeColFontAndTagLists $win
    makeSortAndArrowColLists $win
    adjustColumns $win {} 0

    #
    # Redisplay the items
    #
    redisplay $win 0 $selCells
    updateColorsWhenIdle $win

    #
    # Reconfigure the relevant column labels
    #
    foreach col [lappend newCols $target1] {
	reconfigColLabels $win imgs $col
    }

    #
    # Restore the trace set on the array element data(activeCol)
    # and enforce the execution of the activeTrace command
    #
    trace variable data(activeCol) w [list tablelist::activeTrace $win]
    set data(activeCol) $data(activeCol)

    return ""
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistSort.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
#==============================================================================
# Contains the implementation of the tablelist::sortByColumn and
# tablelist::addToSortColumns commands, as well as of the tablelist sort,
# sortbycolumn, and sortbycolumnlist subcommands.
#
# Structure of the module:
#   - Public procedures related to sorting
#   - Private procedures implementing the sorting
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Public procedures related to sorting
# ====================================
#

#------------------------------------------------------------------------------
# tablelist::sortByColumn
#
# Sorts the contents of the tablelist widget win by its col'th column.  Returns
# the sort order (increasing or decreasing).
#------------------------------------------------------------------------------
proc tablelist::sortByColumn {win col} {
    #
    # Check the arguments
    #
    if {![winfo exists $win]} {
	return -code error "bad window path name \"$win\""
    }
    if {[string compare [winfo class $win] "Tablelist"] != 0} {
	return -code error "window \"$win\" is not a tablelist widget"
    }
    if {[catch {::$win columnindex $col} result] != 0} {
	return -code error $result
    }
    if {$result < 0 || $result >= [::$win columncount]} {
	return -code error "column index \"$col\" out of range"
    }
    set col $result
    if {[::$win columncget $col -showlinenumbers]} {
	return ""
    }

    #
    # Determine the sort order
    #
    if {[set idx [lsearch -exact [::$win sortcolumnlist] $col]] >= 0 &&
	[string compare [lindex [::$win sortorderlist] $idx] "increasing"]
	== 0} {
	set sortOrder decreasing
    } else {
	set sortOrder increasing
    }

    #
    # Sort the widget's contents based on the given column
    #
    if {[catch {::$win sortbycolumn $col -$sortOrder} result] == 0} {
	set userData [list $col $sortOrder]
	genVirtualEvent $win <<TablelistColumnSorted>> $userData

	return $sortOrder
    } else {
	return -code error $result
    }
}

#------------------------------------------------------------------------------
# tablelist::addToSortColumns
#
# Adds the col'th column of the tablelist widget win to the latter's list of
# sort columns and sorts the contents of the widget by the modified column
# list.  Returns the specified column's sort order (increasing or decreasing).
#------------------------------------------------------------------------------
proc tablelist::addToSortColumns {win col} {
    #
    # Check the arguments
    #
    if {![winfo exists $win]} {
	return -code error "bad window path name \"$win\""
    }
    if {[string compare [winfo class $win] "Tablelist"] != 0} {
	return -code error "window \"$win\" is not a tablelist widget"
    }
    if {[catch {::$win columnindex $col} result] != 0} {
	return -code error $result
    }
    if {$result < 0 || $result >= [::$win columncount]} {
	return -code error "column index \"$col\" out of range"
    }
    set col $result
    if {[::$win columncget $col -showlinenumbers]} {
	return ""
    }

    #
    # Update the lists of sort columns and orders
    #
    set sortColList [::$win sortcolumnlist]
    set sortOrderList [::$win sortorderlist]
    if {[set idx [lsearch -exact $sortColList $col]] >= 0} {
	if {[string compare [lindex $sortOrderList $idx] "increasing"] == 0} {
	    set sortOrder decreasing
	} else {
	    set sortOrder increasing
	}
	set sortOrderList [lreplace $sortOrderList $idx $idx $sortOrder]
    } else {
	lappend sortColList $col
	lappend sortOrderList increasing
	set sortOrder increasing
    }

    #
    # Sort the widget's contents according to the
    # modified lists of sort columns and orders
    #
    if {[catch {::$win sortbycolumnlist $sortColList $sortOrderList} result]
	== 0} {
	set userData [list $sortColList $sortOrderList]
	genVirtualEvent $win <<TablelistColumnsSorted>> $userData

	return $sortOrder
    } else {
	return -code error $result
    }
}

#
# Private procedures implementing the sorting
# ===========================================
#

#------------------------------------------------------------------------------
# tablelist::sortItems
#
# Processes the tablelist sort, sortbycolumn, and sortbycolumnlist subcommands.
#------------------------------------------------------------------------------
proc tablelist::sortItems {win parentKey sortColList sortOrderList} {
    variable canElide
    variable snipSides
    upvar ::tablelist::ns${win}::data data

    set sortAllItems [expr {[string compare $parentKey "root"] == 0}]
    if {[winfo viewable $win] && $sortAllItems} {
	purgeWidgets $win
	update idletasks
	if {![array exists ::tablelist::ns${win}::data]} {
	    return ""
	}
    }

    #
    # Make sure sortOrderList has the same length as sortColList
    #
    set sortColCount [llength $sortColList]
    set sortOrderCount [llength $sortOrderList]
    if {$sortOrderCount < $sortColCount} {
	for {set n $sortOrderCount} {$n < $sortColCount} {incr n} {
	    lappend sortOrderList increasing
	}
    } else {
	set sortOrderList [lrange $sortOrderList 0 [expr {$sortColCount - 1}]]
    }

    #
    # Save the keys corresponding to anchorRow and activeRow,
    # as well as the indices of the selected cells
    #
    foreach type {anchor active} {
	set ${type}Key [lindex $data(keyList) $data(${type}Row)]
    }
    set selCells [curCellSelection $win 1]

    #
    # Save some data of the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editKey $data(editKey)
	saveEditData $win
    }

    #
    # Update the sort info and sort the item list
    #
    set descItemList {}
    if {[llength $sortColList] == 1 && [lindex $sortColList 0] == -1} {
	if {[string length $data(-sortcommand)] == 0} {
	    return -code error "value of the -sortcommand option is empty"
	}

	set order [lindex $sortOrderList 0]

	if {$sortAllItems} {
	    #
	    # Update the sort info
	    #
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set data($col-sortRank) 0
		set data($col-sortOrder) ""
	    }
	    set data(sortColList) {}
	    set data(arrowColList) {}
	    set data(sortOrder) $order
	}

	#
	# Sort the child item list
	#
	sortChildren $win $parentKey [list lsort -$order -command \
	    $data(-sortcommand)] descItemList
    } else {					;# sorting by a column (list)
	#
	# Check the specified column indices
	#
	set sortColCount2 $sortColCount
	foreach col $sortColList {
	    if {$data($col-showlinenumbers)} {
		incr sortColCount2 -1
	    }
	}
	if {$sortColCount2 == 0} {
	    return ""
	}

	if {$sortAllItems} {
	    #
	    # Update the sort info
	    #
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set data($col-sortRank) 0
		set data($col-sortOrder) ""
	    }
	    set rank 1
	    foreach col $sortColList order $sortOrderList {
		if {$data($col-showlinenumbers)} {
		    continue
		}

		set data($col-sortRank) $rank
		set data($col-sortOrder) $order
		incr rank
	    }
	    makeSortAndArrowColLists $win
	}

	#
	# Sort the child item list based on the specified columns
	#
	for {set idx [expr {$sortColCount - 1}]} {$idx >= 0} {incr idx -1} {
	    set col [lindex $sortColList $idx]
	    if {$data($col-showlinenumbers)} {
		continue
	    }

	    set descItemList {}
	    set order [lindex $sortOrderList $idx]
	    if {[string compare $data($col-sortmode) "command"] == 0} {
		if {![info exists data($col-sortcommand)]} {
		    return -code error "value of the -sortcommand option for\
					column $col is missing or empty"
		}

		sortChildren $win $parentKey [list lsort -$order -index $col \
		    -command $data($col-sortcommand)] descItemList
	    } elseif {[string compare $data($col-sortmode) "asciinocase"]
		== 0} {
		if {$::tcl_version >= 8.5} {
		    sortChildren $win $parentKey [list lsort -$order \
			-index $col -ascii -nocase] descItemList
		} else {
		    sortChildren $win $parentKey [list lsort -$order \
			-index $col -command compareNoCase] descItemList
		}
	    } else {
		sortChildren $win $parentKey [list lsort -$order -index $col \
		    -$data($col-sortmode)] descItemList
	    }
	}
    }

    if {$sortAllItems} {
	#
	# Cancel the execution of all delayed
	# redisplay and redisplayCol commands
	#
	foreach name [array names data *redispId] {
	    after cancel $data($name)
	    unset data($name)
	}

	set canvasWidth $data(arrowWidth)
	if {[llength $data(arrowColList)] > 1} {
	    incr canvasWidth 6
	}
	foreach col $data(arrowColList) {
	    #
	    # Make sure the arrow will fit into the column
	    #
	    set idx [expr {2*$col}]
	    set pixels [lindex $data(colList) $idx]
	    if {$pixels == 0 && $data($col-maxPixels) > 0 &&
		$data($col-reqPixels) > $data($col-maxPixels) &&
		$data($col-maxPixels) < $canvasWidth} {
		set data($col-maxPixels) $canvasWidth
		set data($col-maxwidth) -$canvasWidth
	    }
	    if {$pixels != 0 && $pixels < $canvasWidth} {
		set data(colList) \
		    [lreplace $data(colList) $idx $idx $canvasWidth]
		set idx [expr {3*$col}]
		set data(-columns) \
		    [lreplace $data(-columns) $idx $idx -$canvasWidth]
	    }
	}

	#
	# Adjust the columns; this will also place the
	# canvas widgets into the corresponding labels
	#
	adjustColumns $win allLabels 1
    }

    if {[llength $descItemList] == 0} {
	return ""
    }

    set parentRow [keyToRow $win $parentKey]
    set firstDescRow [expr {$parentRow + 1}]
    set lastDescRow [expr {$parentRow + [descCount $win $parentKey]}]
    set firstDescLine [expr {$firstDescRow + 1}]
    set lastDescLine [expr {$lastDescRow + 1}]

    #
    # Update the line numbers (if any)
    #
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {!$data($col-showlinenumbers)} {
	    continue
	}

	set newDescItemList {}
	set line $firstDescLine
	foreach item $descItemList {
	    set item [lreplace $item $col $col $line]
	    lappend newDescItemList $item
	    set key [lindex $item end]
	    if {![info exists data($key-hide)]} {
		incr line
	    }
	}
	set descItemList $newDescItemList
    }

    set data(itemList) [eval [list lreplace $data(itemList) \
	$firstDescRow $lastDescRow] $descItemList]

    #
    # Replace the contents of the list variable if present
    #
    condUpdateListVar $win

    #
    # Delete the items from the body text widget and insert the sorted ones.
    # Interestingly, for a large number of items it is much more efficient
    # to empty each line individually than to invoke a global delete command.
    #
    set w $data(body)
    $w tag remove hiddenRow $firstDescLine.0 $lastDescLine.end+1c
    $w tag remove elidedRow $firstDescLine.0 $lastDescLine.end+1c
    for {set line $firstDescLine} {$line <= $lastDescLine} {incr line} {
	$w delete $line.0 $line.end
    }
    set snipStr $data(-snipstring)
    set rowTagRefCount $data(rowTagRefCount)
    set cellTagRefCount $data(cellTagRefCount)
    set isSimple [expr {$data(imgCount) == 0 && $data(winCount) == 0 &&
			$data(indentCount) == 0}]
    set padY [expr {[$w cget -spacing1] == 0}]
    set descKeyList {}
    for {set row $firstDescRow; set line $firstDescLine} \
	{$row <= $lastDescRow} {set row $line; incr line} {
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	lappend descKeyList $key
	set data($key-row) $row
	set dispItem [lrange $item 0 $data(lastCol)]
	if {$data(hasFmtCmds)} {
	    set dispItem [formatItem $win $key $row $dispItem]
	}
	if {[string match "*\t*" $dispItem]} {
	    set dispItem [mapTabs $dispItem]
	}

	#
	# Clip the elements if necessary and
	# insert them with the corresponding tags
	#
	if {$rowTagRefCount == 0} {
	    set hasRowFont 0
	} else {
	    set hasRowFont [info exists data($key-font)]
	}
	set col 0
	if {$isSimple} {
	    set insertArgs {}
	    set multilineData {}
	    foreach text $dispItem \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    if {$multiline} {
			set list [split $text "\n"]
			set snipSide \
			    $snipSides($alignment,$data($col-changesnipside))
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $cellFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		lappend insertArgs "\t\t" $cellTags
		if {$multiline} {
		    lappend multilineData $col $text $cellFont $pixels \
					  $alignment
		}

		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    if {[llength $insertArgs] != 0} {
		eval [list $w insert $line.0] $insertArgs
	    }

	    #
	    # Embed the message widgets displaying multiline elements
	    #
	    foreach {col text font pixels alignment} $multilineData {
		findTabs $win $line $col $col tabIdx1 tabIdx2
		set msgScript [list ::tablelist::displayText $win $key \
			       $col $text $font $pixels $alignment]
		$w window create $tabIdx2 \
			  -align top -pady $padY -create $msgScript
		$w tag add elidedWin $tabIdx2
	    }

	} else {
	    foreach text $dispItem \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Insert the text and the label or window
		# (if any) into the body text widget
		#
		appendComplexElem $win $key $row $col $text $pixels \
				  $alignment $snipStr $cellFont $cellTags $line

		incr col
	    }
	}

	if {$rowTagRefCount != 0} {
	    if {[info exists data($key-font)]} {
		$w tag add row-font-$data($key-font) $line.0 $line.end
	    }
	}

	if {[info exists data($key-elide)]} {
	    $w tag add elidedRow $line.0 $line.end+1c
	}
	if {[info exists data($key-hide)]} {
	    $w tag add hiddenRow $line.0 $line.end+1c
	}
    }

    set data(keyList) [eval [list lreplace $data(keyList) \
	$firstDescRow $lastDescRow] $descKeyList]

    if {$sortAllItems} {
	#
	# Validate the key -> row mapping
	#
	set data(keyToRowMapValid) 1
	if {[info exists data(mapId)]} {
	    after cancel $data(mapId)
	    unset data(mapId)
	}
    }

    #
    # Invalidate the list of row indices indicating the viewable rows
    #
    set data(viewableRowList) {-1}

    #
    # Select the cells that were selected before
    #
    foreach {key col} $selCells {
	set row [keyToRow $win $key]
	cellSelection $win set $row $col $row $col
    }

    #
    # Disable the body text widget if it was disabled before
    #
    if {$data(isDisabled)} {
	$w tag add disabled 1.0 end
	$w tag configure select -borderwidth 0
    }

    #
    # Update anchorRow and activeRow
    #
    foreach type {anchor active} {
	upvar 0 ${type}Key key2
	if {[string length $key2] != 0} {
	    set data(${type}Row) [keyToRow $win $key2]
	}
    }

    #
    # Bring the "most important" row into view if appropriate
    #
    if {$editCol >= 0} {
	set editRow [keyToRow $win $editKey]
	if {$editRow >= $firstDescRow && $editRow <= $lastDescRow} {
	    doEditCell $win $editRow $editCol 1
	}
    } else {
	set selRows [curSelection $win]
	if {[llength $selRows] == 1} {
	    set selRow [lindex $selRows 0]
	    set selKey [lindex $data(keyList) $selRow]
	    if {$selRow >= $firstDescRow && $selRow <= $lastDescRow &&
		![info exists data($selKey-elide)]} {
		seeRow $win $selRow
	    }
	} elseif {[string compare [focus -lastfor $w] $w] == 0} {
	    set activeKey [lindex $data(keyList) $data(activeRow)]
	    if {$data(activeRow) >= $firstDescRow &&
		$data(activeRow) <= $lastDescRow &&
		![info exists data($activeKey-elide)]} {
		seeRow $win $data(activeRow)
	    }
	}
    }

    #
    # Adjust the elided text and restore the stripes in the body text widget
    #
    adjustElidedText $win
    redisplayVisibleItems $win
    makeStripes $win
    updateColorsWhenIdle $win
    adjustSepsWhenIdle $win
    updateVScrlbarWhenIdle $win

    #
    # Work around a Tk bug on Mac OS X Aqua
    #
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	foreach col $data(arrowColList) {
	    set canvas [list $data(hdrTxtFrCanv)$col]
	    after idle [list lower $canvas]
	    after idle [list raise $canvas]
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::sortChildren
#
# Sorts the children of a given parent within the tablelist widget win,
# recursively.
#------------------------------------------------------------------------------
proc tablelist::sortChildren {win parentKey sortCmd itemListName} {
    upvar $itemListName itemList ::tablelist::ns${win}::data data

    set childKeyList $data($parentKey-children)
    if {[llength $childKeyList] == 0} {
	return ""
    }

    #
    # Build and sort the list of child items
    #
    set childItemList {}
    foreach childKey $childKeyList {
	lappend childItemList [lindex $data(itemList) [keyToRow $win $childKey]]
    }
    set childItemList [eval $sortCmd [list $childItemList]]

    #
    # Update the lists and invoke the procedure recursively for the children
    #
    set data($parentKey-children) {}
    foreach item $childItemList {
	lappend itemList $item
	set childKey [lindex $item end]
	lappend data($parentKey-children) $childKey

	sortChildren $win $childKey $sortCmd itemList
    }
}

#------------------------------------------------------------------------------
# tablelist::sortList
#
# Sorts the specified list by the current sort columns of the tablelist widget
# win, using their current sort orders.
#------------------------------------------------------------------------------
proc tablelist::sortList {win list} {
    upvar ::tablelist::ns${win}::data data
    set sortColList $data(sortColList)
    set sortOrderList {}
    foreach col $sortColList {
	lappend sortOrderList $data($col-sortOrder)
    }

    if {[llength $sortColList] == 1 && [lindex $sortColList 0] == -1} {
	if {[string length $data(-sortcommand)] == 0} {
	    return -code error "value of the -sortcommand option is empty"
	}

	#
	# Sort the list
	#
	set order [lindex $sortOrderList 0]
	return [lsort -$order -command $data(-sortcommand) $list]
    } else {
	#
	# Sort the list based on the specified columns
	#
	set sortColCount [llength $sortColList]
	for {set idx [expr {$sortColCount - 1}]} {$idx >= 0} {incr idx -1} {
	    set col [lindex $sortColList $idx]
	    set order [lindex $sortOrderList $idx]

	    if {[string compare $data($col-sortmode) "command"] == 0} {
		if {![info exists data($col-sortcommand)]} {
		    return -code error "value of the -sortcommand option for\
					column $col is missing or empty"
		}

		set list [lsort -$order -index $col -command \
			  $data($col-sortcommand) $list]
	    } elseif {[string compare $data($col-sortmode) "asciinocase"]
		== 0} {
		if {$::tcl_version >= 8.5} {
		    set list [lsort -$order -index $col -ascii -nocase $list]
		} else {
		    set list [lsort -$order -index $col -command \
			      compareNoCase $list]
		}
	    } else {
		set list [lsort -$order -index $col -$data($col-sortmode) $list]
	    }
	}

	return $list
    }
}

#------------------------------------------------------------------------------
# tablelist::compareNoCase
#
# Compares the given strings in a case-insensitive manner.
#------------------------------------------------------------------------------
proc tablelist::compareNoCase {str1 str2} {
    return [string compare [string tolower $str1] [string tolower $str2]]
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistThemes.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
#==============================================================================
# Contains procedures that populate the array themeDefaults with theme-specific
# default values of some tablelist configuration options.
#
# Structure of the module:
#   - Public procedures related to tile themes
#   - Private procedures related to tile themes
#   - Private procedures performing RGB <-> HSV conversions
#   - Private procedures related to global KDE configuration options
#
# Copyright (c) 2005-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Public procedures related to tile themes
# ========================================
#

#------------------------------------------------------------------------------
# tablelist::getCurrentTheme
#
# Returns the current tile theme.
#------------------------------------------------------------------------------
proc tablelist::getCurrentTheme {} {
    if {[info exists ttk::currentTheme]} {
	return $ttk::currentTheme
    } else {
	return $tile::currentTheme
    }
}

#------------------------------------------------------------------------------
# tablelist::setThemeDefaults
#
# Populates the array themeDefaults with theme-specific default values of some
# tablelist configuration options and updates the array configSpecs.
#------------------------------------------------------------------------------
proc tablelist::setThemeDefaults {} {
    variable themeDefaults
    if {[catch {[getCurrentTheme]Theme}] != 0} {
	#
	# Fall back to the "default" theme (which is the root of all
	# themes) and then override the options set by the current one
	#
	defaultTheme 
	array set themeDefaults [style configure .]
    }

    if {[string length $themeDefaults(-arrowcolor)] == 0} {
	set themeDefaults(-arrowdisabledcolor) ""
    } else {
	set themeDefaults(-arrowdisabledcolor) $themeDefaults(-labeldisabledFg)
    }

    variable configSpecs
    foreach opt {-background -foreground -disabledforeground -stripebackground
		 -selectbackground -selectforeground -selectborderwidth -font
		 -labelforeground -labelfont -labelborderwidth -labelpady
		 -arrowcolor -arrowdisabledcolor -arrowstyle -treestyle} {
	if {[llength $configSpecs($opt)] < 4} {
	    lappend configSpecs($opt) $themeDefaults($opt)
	} else {
	    lset configSpecs($opt) 3 $themeDefaults($opt)
	}
    }
}

#
# Private procedures related to tile themes
# =========================================
#

#------------------------------------------------------------------------------
# tablelist::altTheme
#------------------------------------------------------------------------------
proc tablelist::altTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#d9d9d9 \
	-labeldeactivatedBg	#d9d9d9 \
	-labeldisabledBg	#d9d9d9 \
	-labelactiveBg		#ececec \
	-labelpressedBg		#ececec \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::aquaTheme
#------------------------------------------------------------------------------
proc tablelist::aquaTheme {} {
    scan $::tcl_platform(osVersion) "%d" majorOSVersion
    if {$majorOSVersion >= 14} {			;# OS X 10.10 or higher
	set labelBg		#f4f4f4
	set labeldeactivatedBg	#ffffff
	set labeldisabledBg	#ffffff
	set labelpressedBg	#e4e4e4
	set arrowColor		#404040
    } elseif {$majorOSVersion >= 11} {			;# OS X 10.7 or higher
	set labelBg		#efefef
	set labeldeactivatedBg	#efefef
	set labeldisabledBg	#efefef
	set labelpressedBg	#cbcbcb
	set arrowColor		#777777
    } else {
	set labelBg		#e9e8e8
	set labeldeactivatedBg	#e9e8e8
	set labeldisabledBg	#e9e8e8
	set labelpressedBg	#d2d2d2
	set arrowColor		#717171
    }

    switch [winfo rgb . systemMenuActive] {
	"13621 29041 52685" -
	"32256 44288 55552" {				;# Blue Cocoa/Carbon
	    if {$majorOSVersion >= 14} {		;# OS X 10.10 or higher
		set stripeBg			#f2f2f2
		set labelselectedBg		#f4f4f4
		set labelselectedpressedBg	#e4e4e4
	    } elseif {$majorOSVersion >= 11} {		;# OS X 10.7 or higher
		set stripeBg			#f0f4f9
		set labelselectedBg		#80b8f0
		set labelselectedpressedBg	#417ddc
	    } else {
		set stripeBg			#edf3fe
		set labelselectedBg		#7ab2e9
		set labelselectedpressedBg	#679ed5
	    }
	}

	"24415 27499 31354" -
	"39680 43776 48384" {				;# Graphite Cocoa/Carbon
	    if {$majorOSVersion >= 14} {		;# OS X 10.10 or higher
		set stripeBg			#f2f2f2
		set labelselectedBg		#f4f4f4
		set labelselectedpressedBg	#e4e4e4
	    } elseif {$majorOSVersion >= 11} {		;# OS X 10.7 or higher
		set stripeBg			#f4f5f7
		set labelselectedBg		#9ba7b5
		set labelselectedpressedBg	#636e88
	    } else {
		set stripeBg			#f0f0f0
		set labelselectedBg		#b6c2cd
		set labelselectedpressedBg	#a7b3be
	    }
	}
    }

    #
    # Get an approximation of alternateSelectedControlColor
    #
    switch [winfo rgb . systemHighlight] {
	"65535 48058 47288"	{ set selectBg #fc2125 }
	"65535 57311 46003"	{ set selectBg #fd8208 }
	"65535 61423 45231"	{ set selectBg #fec309 }
	"49343 63222 44460"	{ set selectBg #56d72b }
	"45746 55246 65535"	{ set selectBg #0950d0 }
	"63478 54484 65535"	{ set selectBg #bf57da }
	"65535 49087 53969"	{ set selectBg #7b0055 }
	"60909 57053 51914"	{ set selectBg #90714c }
	"55512 55512 56539"	{ set selectBg #5c5c60 }

	"51143 53456 56281"	{ set selectBg #738499 }
	"50887 50887 50887"	{ set selectBg #7f7f7f }
	"46516 54741 65535"	{ set selectBg #3875d7 }
	"64506 60908 29556"	{ set selectBg #ffc11f }
	"65535 45487 35978"	{ set selectBg #f34648 }
	"65535 53968 33154"	{ set selectBg #ff8a22 }
	"50114 63994 37263"	{ set selectBg #66c547 }
	"59879 47290 65535"	{ set selectBg #8c4eb8 }

	default {
	    set rgb [winfo rgb . systemHighlight]
	    foreach {h s v} [eval rgb2hsv $rgb] {}

	    set s [expr {$s*4.0/3.0}]
	    if {$s > 1.0} {
		set s 1.0
	    }

	    set v [expr {$v*3.0/4.0}]
	    if {$v > 1.0} {
		set v 1.0
	    }

	    set rgb [hsv2rgb $h $s $v]
	    set selectBg [eval format "#%04x%04x%04x" $rgb]
	}
    }

    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	$stripeBg \
	-selectbackground	$selectBg \
	-selectforeground	white \
	-selectborderwidth	0 \
	-font			{"Lucida Grande" 12} \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labeldeactivatedBg \
	-labeldisabledBg	$labeldisabledBg \
	-labelactiveBg		$labelBg \
	-labelpressedBg		$labelpressedBg \
	-labelselectedBg	$labelselectedBg \
	-labelselectedpressedBg	$labelselectedpressedBg \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelselectedFg	black \
	-labelselectedpressedFg	black \
	-labelfont		{"Lucida Grande" 11} \
	-labelborderwidth	1 \
	-labelpady		1 \
	-arrowcolor		$arrowColor \
	-treestyle		aqua \
    ]

    variable pngSupported
    if {$majorOSVersion >= 14} {			;# OS X 10.10 or higher
	set themeDefaults(-arrowstyle) flatAngle7x4
    } elseif {$pngSupported} {
	set themeDefaults(-arrowstyle) photo7x7
    } else {
	set themeDefaults(-arrowstyle) flat7x7
    }
}

#------------------------------------------------------------------------------
# tablelist::AquativoTheme
#------------------------------------------------------------------------------
proc tablelist::AquativoTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	black \
	-stripebackground	"" \
	-selectbackground	#000000 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#fafafa \
	-labeldeactivatedBg	#fafafa \
	-labeldisabledBg	#fafafa \
	-labelactiveBg		#fafafa \
	-labelpressedBg		#fafafa \
	-labelforeground	black \
	-labeldisabledFg	black \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		#717171 \
	-arrowstyle		flat8x5 \
	-treestyle		aqua \
    ]
}

#------------------------------------------------------------------------------
# tablelist::blueTheme
#------------------------------------------------------------------------------
proc tablelist::blueTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		#e6f3ff \
	-foreground		black \
	-disabledforeground	#666666 \
	-stripebackground	"" \
	-selectbackground	#ffff33 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#6699cc \
	-labeldeactivatedBg	#6699cc \
	-labeldisabledBg	#6699cc \
	-labelactiveBg		#6699cc \
	-labelpressedBg		#6699cc \
	-labelforeground	black \
	-labeldisabledFg	#666666 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		#2d2d66 \
	-arrowstyle		flat9x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::clamTheme
#------------------------------------------------------------------------------
proc tablelist::clamTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#999999 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#dcdad5 \
	-labeldeactivatedBg	#dcdad5 \
	-labeldisabledBg	#dcdad5 \
	-labelactiveBg		#eeebe7 \
	-labelpressedBg		#eeebe7 \
	-labelforeground	black \
	-labeldisabledFg	#999999 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::classicTheme
#------------------------------------------------------------------------------
proc tablelist::classicTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	"" \
	-selectbackground	#c3c3c3 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#d9d9d9 \
	-labeldeactivatedBg	#d9d9d9 \
	-labeldisabledBg	#d9d9d9 \
	-labelactiveBg		#ececec \
	-labelpressedBg		#ececec \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		"" \
	-arrowstyle		sunken10x9 \
	-treestyle		gtk \
    ]

    if {[info exists tile::version] &&
	[string compare $tile::version 0.8] < 0} {
	set themeDefaults(-font)	TkClassicDefaultFont
	set themeDefaults(-labelfont)	TkClassicDefaultFont
    }
}

#------------------------------------------------------------------------------
# tablelist::defaultTheme
#------------------------------------------------------------------------------
proc tablelist::defaultTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#d9d9d9 \
	-labeldeactivatedBg	#d9d9d9 \
	-labeldisabledBg	#d9d9d9 \
	-labelactiveBg		#ececec \
	-labelpressedBg		#ececec \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	1 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::keramikTheme
#------------------------------------------------------------------------------
proc tablelist::keramikTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#aaaaaa \
	-stripebackground	"" \
	-selectbackground	#0a5f89 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#e2e4e7 \
	-labeldeactivatedBg	#e2e4e7 \
	-labeldisabledBg	#e2e4e7 \
	-labelactiveBg		#e2e4e7 \
	-labelpressedBg		#c6c8cc \
	-labelforeground	black \
	-labeldisabledFg	#aaaaaa \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat8x5 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::keramik_altTheme
#------------------------------------------------------------------------------
proc tablelist::keramik_altTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#aaaaaa \
	-stripebackground	"" \
	-selectbackground	#0a5f89 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#e2e4e7 \
	-labeldeactivatedBg	#e2e4e7 \
	-labeldisabledBg	#e2e4e7 \
	-labelactiveBg		#e2e4e7 \
	-labelpressedBg		#c6c8cc \
	-labelforeground	black \
	-labeldisabledFg	#aaaaaa \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat8x5 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::krocTheme
#------------------------------------------------------------------------------
proc tablelist::krocTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#b2b2b2 \
	-stripebackground	"" \
	-selectbackground	#000000 \
	-selectforeground	#ffffff \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#fcb64f \
	-labeldeactivatedBg	#fcb64f \
	-labeldisabledBg	#fcb64f \
	-labelactiveBg		#694418 \
	-labelpressedBg		#694418 \
	-labelforeground	black \
	-labeldisabledFg	#b2b2b2 \
	-labelactiveFg		#ffe7cb \
	-labelpressedFg		#ffe7cb \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::plastikTheme
#------------------------------------------------------------------------------
proc tablelist::plastikTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#aaaaaa \
	-stripebackground	"" \
	-selectbackground	#657a9e \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#dcdde3 \
	-labeldeactivatedBg	#dcdde3 \
	-labeldisabledBg	#dcdde3 \
	-labelactiveBg		#dcdde3 \
	-labelpressedBg		#b9bcc0 \
	-labelforeground	black \
	-labeldisabledFg	#aaaaaa \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x4 \
	-treestyle		plastik \
    ]
}

#------------------------------------------------------------------------------
# tablelist::srivTheme
#------------------------------------------------------------------------------
proc tablelist::srivTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		#e6f3ff \
	-foreground		black \
	-disabledforeground	#666666 \
	-stripebackground	"" \
	-selectbackground	#ffff33 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#a0a0a0 \
	-labeldeactivatedBg	#a0a0a0 \
	-labeldisabledBg	#a0a0a0 \
	-labelactiveBg		#a0a0a0 \
	-labelpressedBg		#a0a0a0 \
	-labelforeground	black \
	-labeldisabledFg	#666666 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::srivlgTheme
#------------------------------------------------------------------------------
proc tablelist::srivlgTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		#e6f3ff \
	-foreground		black \
	-disabledforeground	#666666 \
	-stripebackground	"" \
	-selectbackground	#ffff33 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#6699cc \
	-labeldeactivatedBg	#6699cc \
	-labeldisabledBg	#6699cc \
	-labelactiveBg		#6699cc \
	-labelpressedBg		#6699cc \
	-labelforeground	black \
	-labeldisabledFg	#666666 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::stepTheme
#------------------------------------------------------------------------------
proc tablelist::stepTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#808080 \
	-stripebackground	"" \
	-selectbackground	#fdcd00 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#a0a0a0 \
	-labeldeactivatedBg	#a0a0a0 \
	-labeldisabledBg	#a0a0a0 \
	-labelactiveBg		#aeb2c3 \
	-labelpressedBg		#aeb2c3 \
	-labelforeground	black \
	-labeldisabledFg	#808080 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::tileqtTheme
#
# Tested with the following Qt styles:
#
#   Acqua              KDE Classic                Motif Plus     RISC OS
#   B3/KDE             KDE_XP                     MS Windows 9x  SGI
#   Baghira            Keramik                    Oxygen         System-Series
#   CDE                Light Style, 2nd revision  Phase          System++
#   Cleanlooks         Light Style, 3rd revision  Plastik        ThinKeramik
#   GTK+ Style         Lipstik                    Plastique
#   HighColor Classic  Marble                     Platinum
#   HighContrast       Motif                      QtCurve
#
# Supported KDE 1/2/3 color schemes:
#
#   Aqua Blue                     Ice (FreddyK)     Point Reyes Green
#   Aqua Graphite                 KDE 1             Pumpkin
#   Atlas Green                   KDE 2             Redmond 2000
#   BeOS                          Keramik           Redmond 95
#   Blue Slate                    Keramik Emerald   Redmond XP
#   CDE                           Keramik White     Solaris
#   Dark Blue                     Lipstik Noble     Storm
#   Desert Red                    Lipstik Standard  SuSE, old & new
#   Digital CDE                   Lipstik White     SUSE-kdm
#   EveX                          Media Peach       System
#   High Contrast Black Text      Next              Thin Keramik, old & new
#   High Contrast Yellow on Blue  Pale Gray         Thin Keramik II
#   High Contrast White Text      Plastik
#
# Supported KDE 4 color schemes:
#
#   Honeycomb       Oxygen (= Standard)  Steel       Zion (Reversed)
#   Norway          Oxygen Cold          Wonton Soup
#   Obsidian Coast  Oxygen-Molecule 3.0  Zion
#------------------------------------------------------------------------------
proc tablelist::tileqtTheme {} {
    set bg		[tileqt_currentThemeColour -background]
    set fg		[tileqt_currentThemeColour -foreground]
    set tableBg		[tileqt_currentThemeColour -base]
    set tableFg		[tileqt_currentThemeColour -text]
    set tableDisFg	[tileqt_currentThemeColour -disabled -text]
    set selectBg	[tileqt_currentThemeColour -highlight]
    set selectFg	[tileqt_currentThemeColour -highlightedText]
    set labelBg		[tileqt_currentThemeColour -button]
    set labelFg		[tileqt_currentThemeColour -buttonText]
    set labelDisFg	[tileqt_currentThemeColour -disabled -buttonText]
    set style		[string tolower [tileqt_currentThemeName]]
    set pressedBg	$labelBg

    #
    # For most Qt styles the label colors depend on the color scheme:
    #
    switch "$bg $labelBg" {
	"#fafafa #6188d7" {	;# color scheme "Aqua Blue"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #d0d0d0 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #9ec2fa }
		"highcolor"	{ set labelBg #628ada;  set pressedBg #6188d7 }
		"keramik"	{ set labelBg #8fabe4;  set pressedBg #7390cc }
		"phase"		{ set labelBg #6188d7;  set pressedBg #d0d0d0 }
		"plastik"	{ set labelBg #666bd6;  set pressedBg #5c7ec2 }
		"qtcurve"	{ set labelBg #f4f4f4;  set pressedBg #d0d0d0 }
		"thinkeramik"	{ set labelBg #f4f4f4;  set pressedBg #dedede }
	    }
	}

	"#ffffff #89919b" {	;# color scheme "Aqua Graphite"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #d4d4d4 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #c3c7cd }
		"highcolor"	{ set labelBg #8b949e;  set pressedBg #89919b }
		"keramik"	{ set labelBg #acb1b8;  set pressedBg #91979e }
		"phase"		{ set labelBg #89919b;  set pressedBg #d4d4d4 }
		"plastik"	{ set labelBg #8c949d;  set pressedBg #7f868e }
		"qtcurve"	{ set labelBg #f6f6f6;  set pressedBg #d4d4d4 }
		"thinkeramik"	{ set labelBg #f4f4f4;  set pressedBg #e2e2e2 }
	    }
	}

	"#afb49f #afb49f" {	;# color scheme "Atlas Green"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #c1c6af }
		"platinum"			      { set pressedBg #929684 }
		"baghira"	{ set labelBg #e5e8dc;  set pressedBg #dadcd0 }
		"highcolor"	{ set labelBg #b2b6a1;  set pressedBg #afb49f }
		"keramik"	{ set labelBg #c7cabb;  set pressedBg #adb1a1 }
		"phase"		{ set labelBg #a7b49f;  set pressedBg #929684 }
		"plastik"	{ set labelBg #acb19c;  set pressedBg #959987 }
		"qtcurve"	{ set labelBg #adb19e;  set pressedBg #939881 }
		"thinkeramik"	{ set labelBg #c1c4b6;  set pressedBg #a5a999 }
	    }
	}

	"#d9d9d9 #d9d9d9" {	;# color scheme "BeOS"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #eeeeee }
		"platinum"			      { set pressedBg #b4b4b4 }
		"baghira"	{ set labelBg #f2f2f2;  set pressedBg #e9e9e9 }
		"highcolor"	{ set labelBg #dcdcdc;  set pressedBg #d9d9d9 }
		"keramik"	{ set labelBg #e5e5e5;  set pressedBg #cdcdcd }
		"phase"		{ set labelBg #dadada;  set pressedBg #b4b4b4 }
		"plastik"	{ set labelBg #d6d6d6;  set pressedBg #b6b6b6 }
		"qtcurve"	{ set labelBg #d6d6d6;  set pressedBg #b5b5b5 }
		"thinkeramik"	{ set labelBg #dddddd;  set pressedBg #c5c5c5 }
	    }
	}

	"#9db9c8 #9db9c8" {	;# color scheme "Blue Slate"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #adcbdc }
		"platinum"			      { set pressedBg #8299a6 }
		"baghira"	{ set labelBg #ddeff6;  set pressedBg #d0e1ea }
		"highcolor"	{ set labelBg #9fbbcb;  set pressedBg #9db9c8 }
		"keramik"	{ set labelBg #baced9;  set pressedBg #a0b5c1 }
		"phase"		{ set labelBg #9db9c9;  set pressedBg #8299a6 }
		"plastik"	{ set labelBg #99b6c5;  set pressedBg #869fab }
		"qtcurve"	{ set labelBg #9bb7c6;  set pressedBg #7c9cad }
		"thinkeramik"	{ set labelBg #b5c8d2;  set pressedBg #98adb8 }
	    }
	}

	"#999999 #999999" {	;# color scheme "CDE"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #a8a8a8 }
		"platinum"			      { set pressedBg #7f7f7f }
		"baghira"	{ set labelBg #d5d5d5;  set pressedBg #cccccc }
		"highcolor"	{ set labelBg #9b9b9b;  set pressedBg #999999 }
		"keramik"	{ set labelBg #b7b7b7;  set pressedBg #9d9d9d }
		"phase"		{ set labelBg #999999;  set pressedBg #7f7f7f }
		"plastik"	{ set labelBg #979797;  set pressedBg #808080 }
		"qtcurve"	{ set labelBg #979797;  set pressedBg #7f7f7f }
		"thinkeramik"	{ set labelBg #b3b3b3;  set pressedBg #959595 }
	    }
	}

	"#426794 #426794" {	;# color scheme "Dark Blue"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #4871a2 }
		"platinum"			      { set pressedBg #37567b }
		"baghira"	{ set labelBg #8aafdc;  set pressedBg #82a3cc }
		"highcolor"	{ set labelBg #436895;  set pressedBg #426794 }
		"keramik"	{ set labelBg #7994b4;  set pressedBg #5b7799 }
		"phase"		{ set labelBg #426795;  set pressedBg #37567b }
		"plastik"	{ set labelBg #406592;  set pressedBg #36547a }
		"qtcurve"	{ set labelBg #416692;  set pressedBg #3c5676 }
		"thinkeramik"	{ set labelBg #7991af;  set pressedBg #546f91 }
	    }
	}

	"#d6cdbb #d6cdbb" {	;# color scheme "Desert Red"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #ebe1ce }
		"platinum"			      { set pressedBg #b2ab9c }
		"baghira"	{ set labelBg #f7f4ec;  set pressedBg #edeae0 }
		"highcolor"	{ set labelBg #d9d0be;  set pressedBg #d6cdbb }
		"keramik"	{ set labelBg #e3dcd0;  set pressedBg #cbc5b7 }
		"phase"		{ set labelBg #d6cdbb;  set pressedBg #b2ab9c }
		"plastik"	{ set labelBg #d3cbb8;  set pressedBg #bab3a3 }
		"qtcurve"	{ set labelBg #d4cbb8;  set pressedBg #b8ac94 }
		"thinkeramik"	{ set labelBg #dbd5ca;  set pressedBg #c2bbae }
	    }
	}

	"#4b7b82 #4b7b82" {	;# color scheme "Digital CDE"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #52878f }
		"platinum"			      { set pressedBg #3e666c }
		"baghira"	{ set labelBg #97c3c9;  set pressedBg #8eb6bc }
		"highcolor"	{ set labelBg #4b7d84;  set pressedBg #4b7b82 }
		"keramik"	{ set labelBg #80a2a7;  set pressedBg #62868c }
		"phase"		{ set labelBg #4b7b82;  set pressedBg #3e666c }
		"plastik"	{ set labelBg #49787f;  set pressedBg #3d666c }
		"qtcurve"	{ set labelBg #4a7980;  set pressedBg #416468 }
		"thinkeramik"	{ set labelBg #7f97a3;  set pressedBg #5a7e83 }
	    }
	}

	"#e6dedc #e4e4e4" {	;# color scheme "EveX"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #fdf4f2 }
		"platinum"			      { set pressedBg #bfb8b7 }
		"baghira"	{ set labelBg #f6f5f5;  set pressedBg #ededed }
		"highcolor"	{ set labelBg #e7e7e7;  set pressedBg #e4e4e4 }
		"keramik"	{ set labelBg #ededed;  set pressedBg #d6d6d6 }
		"phase"		{ set labelBg #e7e0dd;  set pressedBg #bfb8b7 }
		"plastik"	{ set labelBg #e2e2e2;  set pressedBg #c0bfbf }
		"qtcurve"	{ set labelBg #e4dcd9;  set pressedBg #c5b7b4 }
		"thinkeramik"	{ set labelBg #e6e1df;  set pressedBg #c7c9c7 }
	    }
	}

	"#ffffff #ffffff" {	;# color scheme "High Contrast Black Text"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #d4d4d4 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f2f2f2 }
		"highcolor"	{ set labelBg #f5f5f5;  set pressedBg #ffffff }
		"keramik"	{ set labelBg #fbfbfb;  set pressedBg #e8e8e8 }
		"phase"		{ set labelBg #f7f7f7;  set pressedBg #d4d4d4 }
		"plastik"	{ set labelBg #f8f8f8;  set pressedBg #d8d8d8 }
		"qtcurve"	{ set labelBg #f6f6f6;  set pressedBg #d6d6d6 }
		"thinkeramik"	{ set labelBg #f4f4f4;  set pressedBg #e2e2e2 }
	    }
	}

	"#0000ff #0000ff" {	;# color scheme "High Contrast Yellow on Blue"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #1919ff }
		"platinum"			      { set pressedBg #0000d4 }
		"baghira"	{ set labelBg #4848ff;  set pressedBg #4646ff }
		"highcolor"	{ set labelBg #0e0ef5;  set pressedBg #0000ff }
		"keramik"	{ set labelBg #4949fb;  set pressedBg #2929e8 }
		"phase"		{ set labelBg #0909f7;  set pressedBg #0000d4 }
		"plastik"	{ set labelBg #0505f8;  set pressedBg #0000d8 }
		"qtcurve"	{ set labelBg #0909f2;  set pressedBg #0f0fc5 }
		"thinkeramik"	{ set labelBg #5151f4;  set pressedBg #2222e2 }
	    }
	}

	"#000000 #000000" {	;# color scheme "High Contrast White Text"
	    switch -- $style {  
		"light, 3rd revision"		      { set pressedBg #000000 }
		"platinum"			      { set pressedBg #000000 }
		"baghira"	{ set labelBg #818181;  set pressedBg #7f7f7f }
		"highcolor"	{ set labelBg #000000;  set pressedBg #000000 }
		"keramik"	{ set labelBg #494949;  set pressedBg #292929 }
		"phase"		{ set labelBg #000000;  set pressedBg #000000 }
		"plastik"	{ set labelBg #000000;  set pressedBg #000000 }
		"qtcurve"	{ set labelBg #000000;  set pressedBg #000000 }
		"thinkeramik"	{ set labelBg #4d4d4d;  set pressedBg #222222 }
	    }
	}

	"#f6f6ff #e4eeff" {	;# color scheme "Ice (FreddyK)"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #cdcdd4 }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f2f4f6 }
		"highcolor"	{ set labelBg #e8edf5;  set pressedBg #e4eeff }
		"keramik"	{ set labelBg #edf3fb;  set pressedBg #d6dde8 }
		"phase"		{ set labelBg #f3f3f7;  set pressedBg #cdcdd4 }
		"plastik"	{ set labelBg #e3eaf8;  set pressedBg #c0c9d8 }
		"qtcurve"	{ set labelBg #ebebfc;  set pressedBg #b3b3f0 }
		"thinkeramik"	{ set labelBg #f1f1f4;  set pressedBg #dbdbe2 }
	    }
	}

	"#c0c0c0 #c0c0c0" {	;# color schemes "KDE 1" and "Storm"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #d3d3d3 }
		"platinum"			      { set pressedBg #a0a0a0 }
		"baghira"	{ set labelBg #e9e9e9;  set pressedBg #dedede }
		"highcolor"	{ set labelBg #c2c2c2;  set pressedBg #c0c0c0 }
		"keramik"	{ set labelBg #d3d3d3;  set pressedBg #bababa }
		"phase"		{ set labelBg #c1c1c1;  set pressedBg #a0a0a0 }
		"plastik"	{ set labelBg #bebebe;  set pressedBg #a2a2a2 }
		"qtcurve"	{ set labelBg #bebebe;  set pressedBg #a0a0a0 }
		"thinkeramik"	{ set labelBg #cccccc;  set pressedBg #b2b2b2 }
	    }
	}

	"#dcdcdc #e4e4e4" {	;# color scheme "KDE 2"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #d3d3d3 }
		"platinum"			      { set pressedBg #b7b7b7 }
		"baghira"	{ set labelBg #f3f3f3;  set pressedBg #ededed }
		"highcolor"	{ set labelBg #e7e7e7;  set pressedBg #e4e4e4 }
		"keramik"	{ set labelBg #ededed;  set pressedBg #d6d6d6 }
		"phase"		{ set labelBg #dddddd;  set pressedBg #b7b7b7 }
		"plastik"	{ set labelBg #e2e2e2;  set pressedBg #c0c0c0 }
		"qtcurve"	{ set labelBg #d9d9d9;  set pressedBg #b8b8b8 }
		"thinkeramik"	{ set labelBg #dfdfdf;  set pressedBg #c7c7c7 }
	    }
	}

	"#eae9e8 #e6f0f9" {	;# color scheme "Keramik"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c3c2c1 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #f1f3f5 }
		"highcolor"	{ set labelBg #eaeef2;  set pressedBg #e6f0f9 }
		"keramik"	{ set labelBg #eef4f8;  set pressedBg #d7dfe5 }
		"phase"		{ set labelBg #ebeae9;  set pressedBg #c3c2c1 }
		"plastik"	{ set labelBg #e3ecf3;  set pressedBg #c0c9d2 }
		"qtcurve"	{ set labelBg #e8e6e6;  set pressedBg #c5c3c1 }
		"thinkeramik"	{ set labelBg #e8e8e7;  set pressedBg #d2d1d0 }
	    }
	}

	"#eeeee6 #eeeade" {	;# color scheme "Keramik Emerald"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffffc }
		"platinum"			      { set pressedBg #c6c6bf }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #efefef;  set pressedBg #c6c6bf }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #c9c6bc }
		"qtcurve"	{ set labelBg #ecece3;  set pressedBg #cdcdbb }
		"thinkeramik"	{ set labelBg #ebebe5;  set pressedBg #d5d5cf }
	    }
	}

	"#e9e9e9 #f6f6f6" {	;# color scheme "Keramik White"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c2c2c2 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #f1f1f1 }
		"highcolor"	{ set labelBg #f1f1f1;  set pressedBg #f6f6f6 }
		"keramik"	{ set labelBg #f7f7f7;  set pressedBg #e3e3e3 }
		"phase"		{ set labelBg #eaeaea;  set pressedBg #c2c2c2 }
		"plastik"	{ set labelBg #f1f1f1;  set pressedBg #cfcfcf }
		"qtcurve"	{ set labelBg #e6e6e6;  set pressedBg #c3c3c3 }
		"thinkeramik"	{ set labelBg #e8e8e8;  set pressedBg #d1d1d1 }
	    }
	}

	"#ebe9e9 #f6f4f4" {	;# color scheme "Lipstik Noble"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c3c1c1 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #f1f1f1 }
		"highcolor"	{ set labelBg #f1f0f0;  set pressedBg #f6f4f4 }
		"keramik"	{ set labelBg #f7f6f6;  set pressedBg #e3e1e1 }
		"phase"		{ set labelBg #f5f4f4;  set pressedBg #c3c1c1 }
		"plastik"	{ set labelBg #f2f2f2;  set pressedBg #d3d2d2 }
		"qtcurve"	{ set labelBg #e9e6e6;  set pressedBg #c5c1c1 }
		"thinkeramik"	{ set labelBg #e9e8e8;  set pressedBg #d3d1d1 }
	    }
	}

	"#eeeee6 #eeeade" {	;# color scheme "Lipstik Standard"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffffc }
		"platinum"			      { set pressedBg #c6c6bf }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #eeeade;  set pressedBg #c6c6bf }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #ccc9c0 }
		"qtcurve"	{ set labelBg #ecece3;  set pressedBg #ccccba }
		"thinkeramik"	{ set labelBg #ebebe5;  set pressedBg #d5d5cf }
	    }
	}

	"#eeeff2 #f7faff" {	;# color scheme "Lipstik White"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c6c7c9 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f2f2f3 }
		"highcolor"	{ set labelBg #f1f2f5;  set pressedBg #f1faff }
		"keramik"	{ set labelBg #f8f9fb;  set pressedBg #e3e5e8 }
		"phase"		{ set labelBg #f4f5f7;  set pressedBg #c6c7c9 }
		"plastik"	{ set labelBg #f3f4f7;  set pressedBg #d0d3d8 }
		"qtcurve"	{ set labelBg #ebecf0;  set pressedBg #c4c7ce }
		"thinkeramik"	{ set labelBg #ebecee;  set pressedBg #d5d6d8 }
	    }
	}

	"#f4ddb2 #f4ddb2" {	;# color scheme "Media Peach"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffebc7 }
		"platinum"			      { set pressedBg #cbb894 }
		"baghira"	{ set labelBg #fcfced;  set pressedBg #faf6df }
		"highcolor"	{ set labelBg #f0dbb6;  set pressedBg #f4ddb2 }
		"keramik"	{ set labelBg #f6e8c9;  set pressedBg #e1d0b0 }
		"phase"		{ set labelBg #f4ddb2;  set pressedBg #cbb894 }
		"plastik"	{ set labelBg #ffdbaf;  set pressedBg #d5c19c }
		"qtcurve"	{ set labelBg #f2dbaf;  set pressedBg #e0bd7f }
		"thinkeramik"	{ set labelBg #efe0c3;  set pressedBg #d9c8a7 }
	    }
	}

	"#a8a8a8 #a8a8a8" {	;# color scheme "Next"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #b8b8b8 }
		"platinum"			      { set pressedBg #8c8c8c }
		"baghira"	{ set labelBg #dedede;  set pressedBg #d3d3d3 }
		"highcolor"	{ set labelBg #aaaaaa;  set pressedBg #a8a8a8 }
		"keramik"	{ set labelBg #c2c2c2;  set pressedBg #a8a8a8 }
		"phase"		{ set labelBg #a9a9a9;  set pressedBg #8c8c8c }
		"plastik"	{ set labelBg #a5a5a5;  set pressedBg #898989 }
		"qtcurve"	{ set labelBg #a6a6a6;  set pressedBg #8d8d8d }
		"thinkeramik"	{ set labelBg #bdbdbd;  set pressedBg #a0a0a0 }
	    }
	}

	"#d6d6d6 #d6d6d6" {	;# color scheme "Pale Gray"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ebebeb }
		"platinum"			      { set pressedBg #b2b2b2 }
		"baghira"	{ set labelBg #f2f2f2;  set pressedBg #e8e8e8 }
		"highcolor"	{ set labelBg #d9d9d9;  set pressedBg #d6d6d6 }
		"keramik"	{ set labelBg #e3e3e3;  set pressedBg #cbcbcb }
		"phase"		{ set labelBg #d6d6d6;  set pressedBg #b2b2b2 }
		"plastik"	{ set labelBg #d3d3d3;  set pressedBg #bababa }
		"qtcurve"	{ set labelBg #d4d4d4;  set pressedBg #b1b1b1 }
		"thinkeramik"	{ set labelBg #dbdbdb;  set pressedBg #c2c2c2 }
	    }
	}

	"#efefef #dddfe4" {	;# color scheme "Plastik"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c7c7c7 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #ececee }
		"highcolor"	{ set labelBg #e0e1e7;  set pressedBg #dddfe4 }
		"keramik"	{ set labelBg #e8e9ed;  set pressedBg #d0d2d6 }
		"phase"		{ set labelBg #dee0e5;  set pressedBg #c7c7c7 }
		"plastik"	{ set labelBg #dbdde2;  set pressedBg #babcc0 }
		"qtcurve"	{ set labelBg #ececec;  set pressedBg #c9c9c9 }
		"thinkeramik"	{ set labelBg #ececec;  set pressedBg #d6d6d6 }
	    }
	}

	"#d3c5be #aba09a" {	;# color scheme "Point Reyes Green"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #e8d9d1 }
		"platinum"			      { set pressedBg #afa49e }
		"baghira"	{ set labelBg #f5efed;  set pressedBg #d7d0cd }
		"highcolor"	{ set labelBg #ada29d;  set pressedBg #aba09a }
		"keramik"	{ set labelBg #c4bcb8;  set pressedBg #aba29e }
		"phase"		{ set labelBg #d3c5be;  set pressedBg #afa49e }
		"plastik"	{ set labelBg #ab9f99;  set pressedBg #9b908a }
		"qtcurve"	{ set labelBg #d1c3bc;  set pressedBg #b3a197 }
		"thinkeramik"	{ set labelBg #d9d0cc;  set pressedBg #c0b6b1 }
	    }
	}

	"#eed8ae #eed8ae" {	;# color scheme "Pumpkin"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffe0c0 }
		"platinum"			      { set pressedBg #c6b390 }
		"baghira"	{ set labelBg #fcfbea;  set pressedBg #f9f4dd }
		"highcolor"	{ set labelBg #eed8b1;  set pressedBg #eed8ae }
		"keramik"	{ set labelBg #f3e4c6;  set pressedBg #ddcdad }
		"phase"		{ set labelBg #eed8ae;  set pressedBg #c6b390 }
		"plastik"	{ set labelBg #ebd5ac;  set pressedBg #cfbc96 }
		"qtcurve"	{ set labelBg #ebd6ab;  set pressedBg #d7b980 }
		"thinkeramik"	{ set labelBg #ebdcc0;  set pressedBg #d5c4a4 }
	    }
	}

	"#d4d0c8 #d4d0c8" {	;# color scheme "Redmond 2000"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #e9e5dc }
		"platinum"			      { set pressedBg #b0ada6 }
		"baghira"	{ set labelBg #f3f2ef;  set pressedBg #eae8e4 }
		"highcolor"	{ set labelBg #d7d3cb;  set pressedBg #d4d0c8 }
		"keramik"	{ set labelBg #e1ded9;  set pressedBg #cac7c1 }
		"phase"		{ set labelBg #d5d1c9;  set pressedBg #b0ada6 }
		"plastik"	{ set labelBg #d2cdc5;  set pressedBg #b2afa7 }
		"qtcurve"	{ set labelBg #d2cdc6;  set pressedBg #b4afa4 }
		"thinkeramik"	{ set labelBg #dad7d2;  set pressedBg #c1beb8 }
	    }
	}

	"#c3c3c3 #c3c3c3" {	;# color scheme "Redmond 95"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #d6d6d6 }
		"platinum"			      { set pressedBg #a2a2a2 }
		"baghira"	{ set labelBg #eaeaea;  set pressedBg #dfdfdf }
		"highcolor"	{ set labelBg #c5c5c5;  set pressedBg #c3c3c3 }
		"keramik"	{ set labelBg #d5d5d5;  set pressedBg #bdbdbd }
		"phase"		{ set labelBg #c4c4c4;  set pressedBg #a2a2a2 }
		"plastik"	{ set labelBg #c1c1c1;  set pressedBg #a3a3a3 }
		"qtcurve"	{ set labelBg #c1c1c1;  set pressedBg #a3a3a3 }
		"thinkeramik"	{ set labelBg #cecece;  set pressedBg #b5b5b5 }
	    }
	}

	"#eeeee6 #eeeade" {	;# color scheme "Redmond XP"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffffc }
		"platinum"			      { set pressedBg #c6c6bf }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #efefe7;  set pressedBg #c6c6bf }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #c9c6bc }
		"qtcurve"	{ set labelBg #ecece3;  set pressedBg #cdcdbb }
		"thinkeramik"	{ set labelBg #ebebe5;  set pressedBg #d5d5cf }
	    }
	}

	"#aeb2c3 #aeb2c3" {	;# color scheme "Solaris"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #bfc3d6 }
		"platinum"			      { set pressedBg #9194a2 }
		"baghira"	{ set labelBg #e4e7ef;  set pressedBg #d9dbe4 }
		"highcolor"	{ set labelBg #b0b4c5;  set pressedBg #aeb2c3 }
		"keramik"	{ set labelBg #c6c9d5;  set pressedBg #adb0bd }
		"phase"		{ set labelBg #aeb2c3;  set pressedBg #9194a2 }
		"plastik"	{ set labelBg #abafc0;  set pressedBg #969aa9 }
		"qtcurve"	{ set labelBg #acb0c1;  set pressedBg #8d91a5 }
		"thinkeramik"	{ set labelBg #c0c3ce;  set pressedBg #a5a7b5 }
	    }
	}

	"#eeeaee #e6f0f9" {	;# color scheme "SuSE" old
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c6c3c6 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f1f3f5 }
		"highcolor"	{ set labelBg #eaeef2;  set pressedBg #e6f0f9 }
		"keramik"	{ set labelBg #eef4f8;  set pressedBg #d7dfe5 }
		"phase"		{ set labelBg #efecef;  set pressedBg #c6c3c6 }
		"plastik"	{ set labelBg #e3ecf3;  set pressedBg #c0c9d2 }
		"qtcurve"	{ set labelBg #ebe7eb;  set pressedBg #cac1ca }
		"thinkeramik"	{ set labelBg #ebe8eb;  set pressedBg #d5d2d5 }
	    }
	}

	"#eeeeee #f4f4f4" {	;# color scheme "SuSE" new
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c6c6c6 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f1f1f1 }
		"highcolor"	{ set labelBg #f0f0f0;  set pressedBg #f4f4f4 }
		"keramik"	{ set labelBg #f6f6f6;  set pressedBg #e1e1e1 }
		"phase"		{ set labelBg #efefef;  set pressedBg #c6c6c6 }
		"plastik"	{ set labelBg #f0f0f0;  set pressedBg #cdcdcd }
		"qtcurve"	{ set labelBg #ebebeb;  set pressedBg #c7c7c7 }
		"thinkeramik"	{ set labelBg #ebebeb;  set pressedBg #d5d5d5 }
	    }
	}

	"#eaeaea #eaeaea" {	;# color scheme "SUSE-kdm"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c3c3c3 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #efefef }
		"highcolor"	{ set labelBg #ececec;  set pressedBg #eaeaea }
		"keramik"	{ set labelBg #f1f1f1;  set pressedBg #dadada }
		"phase"		{ set labelBg #ebebeb;  set pressedBg #c3c3c3 }
		"plastik"	{ set labelBg #e7e7e7;  set pressedBg #c6c6c6 }
		"qtcurve"	{ set labelBg #e7e7e7;  set pressedBg #c4c4c4 }
		"thinkeramik"	{ set labelBg #e8e8e8;  set pressedBg #d2d2d2 }
	    }
	}

	"#d3d3d3 #d3d3d3" {	;# color scheme "System"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #e8e8e8 }
		"platinum"			      { set pressedBg #afafaf }
		"baghira"	{ set labelBg #f0f0f0;  set pressedBg #e6e6e6 }
		"highcolor"	{ set labelBg #d6d6d6;  set pressedBg #d3d3d3 }
		"keramik"	{ set labelBg #e1e1e1;  set pressedBg #c9c9c9 }
		"phase"		{ set labelBg #d2d2d2;  set pressedBg #afafaf }
		"plastik"	{ set labelBg #d0d0d0;  set pressedBg #b9b9b9 }
		"qtcurve"	{ set labelBg #d1d1d1;  set pressedBg #aeaeae }
		"thinkeramik"	{ set labelBg #d9d9d9;  set pressedBg #c0c0c0 }
	    }
	}

	"#e6e6de #f0f0ef" {	;# color scheme "Thin Keramik" old
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fdfdf4 }
		"platinum"			      { set pressedBg #bfbfb8 }
		"baghira"	{ set labelBg #f6f6f5;  set pressedBg #f0f0f0 }
		"highcolor"	{ set labelBg #eeeeee;  set pressedBg #f0f0ef }
		"keramik"	{ set labelBg #f4f4f4;  set pressedBg #dfdfde }
		"phase"		{ set labelBg #e7e7df;  set pressedBg #bfbfb8 }
		"plastik"	{ set labelBg #ededeb;  set pressedBg #cbcbc9 }
		"qtcurve"	{ set labelBg #e3e3db;  set pressedBg #c4c4b6 }
		"thinkeramik"	{ set labelBg #e6e6e1;  set pressedBg #cfcfc9 }
	    }
	}

	"#edede1 #f6f6e9" {	;# color scheme "Thin Keramik" new
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffff7 }
		"platinum"			      { set pressedBg #c5c5bb }
		"baghira"	{ set labelBg #f6f6f5;  set pressedBg #f3f3f1 }
		"highcolor"	{ set labelBg #f1f1ec;  set pressedBg #f6f6e9 }
		"keramik"	{ set labelBg #f7f7f0;  set pressedBg #e3e3da }
		"phase"		{ set labelBg #edede1;  set pressedBg #c5c5bb }
		"plastik"	{ set labelBg #f4f4e6;  set pressedBg #ddddd0 }
		"qtcurve"	{ set labelBg #ebebde;  set pressedBg #cbcbb3 }
		"thinkeramik"	{ set labelBg #eaeae3;  set pressedBg #d4d4cb }
	    }
	}

	"#f6f5e8 #eeeade" {	;# color scheme "Thin Keramik II"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #cdccc1 }
		"baghira"	{ set labelBg #f7f7f7;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #f3f2e9;  set pressedBg #cdccc1 }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #c9c6bc }
		"qtcurve"	{ set labelBg #f4f2e5;  set pressedBg #dbd8b6 }
		"thinkeramik"	{ set labelBg #f1f1e8;  set pressedBg #dbdad0 }
	    }
	}

	"#d4d7d0 #babdb7" {	;# color scheme "Honeycomb"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #b1b4ae }
		"plastique"	{ set labelBg #b8bbb5;  set pressedBg #c1c4be }
	    }
	}

	"#ebe2d2 #f7f2e8" {	;# color scheme "Norway"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #c8bba3 }
		"plastique"	{ set labelBg #f4f0e6;  set pressedBg #d6cfbf }
	    }
	}

	"#302f2f #403f3e" {	;# color scheme "Obsidian Coast"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #2a2929 }
		"plastique"	{ set labelBg #3f3e3d;  set pressedBg #2b2a2a }
	    }
	}

	"#d6d2d0 #dfdcd9" {	;# color schemes "Oxygen" and "Standard"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #b6aeaa }
		"plastique"	{ set labelBg #dddad7;  set pressedBg #c3bfbe }
	    }
	}

	"#e0dfde #e8e7e6" {	;# c. s. "Oxygen Cold" and "Oxygen-Molecule 3.0"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #bbb9b8 }
		"plastique"	{ set labelBg #e6e5e4;  set pressedBg #cdcccb }
	    }
	}

	"#e0dfd8 #e8e7df" {	;# color scheme "Steel"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #babab4 }
		"plastique"	{ set labelBg #e6e5dd;  set pressedBg #cdccc5 }
	    }
	}

	"#494e58 #525863" {	;# color scheme "Wonton Soup"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #3f444c }
		"plastique"	{ set labelBg #515762;  set pressedBg #424650 }
	    }
	}

	"#fcfcfc #ffffff" {	;# color scheme "Zion"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #dedede }
		"plastique"	{ set labelBg #f9f9f9;  set pressedBg #e5e5e5 }
	    }
	}

	"#101010 #000000" {	;# color scheme "Zion (Reversed)"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #5e5e5e }
		"plastique"	{ set labelBg #000000;  set pressedBg #0e0e0e }
	    }
	}
    }

    #
    # For some Qt styles the label colors are independent of the color scheme:
    #
    switch -- $style {
	"acqua" {
	    set labelBg #e7e7e7;  set labelFg #000000;  set pressedBg #8fbeec
	}

	"gtk+" {
	    set labelBg #e8e7e6;			set pressedBg $labelBg
	}

	"kde_xp" {
	    set labelBg #ebeadb;  set labelFg #000000;  set pressedBg #faf8f3
	}

	"lipstik" -
	"oxygen" {
	    set labelBg $bg;				set pressedBg $labelBg
	}

	"marble" {
	    set labelBg #cccccc;  set labelFg $fg;      set pressedBg $labelBg
	}

	"riscos" {
	    set labelBg #dddddd;  set labelFg #000000;  set pressedBg $labelBg
	}

	"system" -
	"systemalt" {
	    set labelBg #cbcbcb;  set labelFg #000000;  set pressedBg $labelBg
	}
    }

    #
    # The stripe background color is specified
    # by a global KDE configuration option:
    #
    if {[info exists ::env(KDE_SESSION_VERSION)] &&
	$::env(KDE_SESSION_VERSION) ne ""} {
	set val [getKdeConfigVal "Colors:View" "BackgroundAlternate"]
    } else {
	set val [getKdeConfigVal "General" "alternateBackground"]
    }
    if {$val eq "" || [string index $val 0] eq "#"} {
	set stripeBg $val
    } elseif {[scan $val "%d,%d,%d" r g b] == 3} {
	set stripeBg [format "#%02x%02x%02x" $r $g $b]
    } else {
	set stripeBg ""
    }

    #
    # The arrow color and style depend mainly on the current Qt style:
    #
    switch -- $style {
	"highcontrast" -
	"light, 2nd revision" -
	"light, 3rd revision" -
	"lipstik" -
	"phase" -
	"plastik"	{ set arrowColor $labelFg; set arrowStyle flat7x4 }

	"baghira"	{ set arrowColor $labelFg; set arrowStyle flat7x7 }

	"cleanlooks" -
	"gtk+" -
	"oxygen"	{ set arrowColor $labelFg; set arrowStyle flatAngle9x6 }

	"phase"		{ set arrowColor $labelFg; set arrowStyle flat6x4 }

	"qtcurve"	{ set arrowColor $labelFg; set arrowStyle flatAngle7x5 }

	"keramik" -
	"thinkeramik"	{ set arrowColor $labelFg; set arrowStyle flat8x5 }

	default		{ set arrowColor "";	   set arrowStyle sunken12x11 }
    }

    #
    # The tree style depends on the current Qt style:
    #
    switch -- $style {
	"baghira" -
	"cde" -
	"motif"		{ set treeStyle baghira }
	"gtk+"		{ set treeStyle gtk }
	"oxygen"	{ set treeStyle oxygen2 }
	"phase"		{ set treeStyle phase }
	"plastik"	{ set treeStyle plastik }
	"plastique"	{ set treeStyle plastique }
	"qtcurve"	{ set treeStyle klearlooks }
	default		{ set treeStyle winnative }
    }

    variable themeDefaults
    array set themeDefaults [list \
	-background		$tableBg \
	-foreground		$tableFg \
	-disabledforeground	$tableDisFg \
	-stripebackground	$stripeBg \
	-selectbackground	$selectBg \
	-selectforeground	$selectFg \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labelBg \
	-labeldisabledBg	$labelBg \
	-labelactiveBg		$labelBg \
	-labelpressedBg		$pressedBg \
	-labelforeground	$labelFg \
	-labeldisabledFg	$labelDisFg \
	-labelactiveFg		$labelFg \
	-labelpressedFg		$labelFg \
	-labelfont		TkDefaultFont \
	-labelborderwidth	4 \
	-labelpady		0 \
	-arrowcolor		$arrowColor \
	-arrowstyle		$arrowStyle \
	-treestyle		$treeStyle \
    ]
}

#------------------------------------------------------------------------------
# tablelist::vistaTheme
#------------------------------------------------------------------------------
proc tablelist::vistaTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		SystemWindow \
	-foreground		SystemWindowText \
	-disabledforeground	SystemDisabledText \
	-stripebackground	"" \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelforeground	SystemButtonText \
	-labeldisabledFg	SystemDisabledText \
	-labelactiveFg		SystemButtonText \
	-labelpressedFg		SystemButtonText \
	-labelfont		TkDefaultFont \
    ]

    switch [winfo rgb . SystemHighlight] {
	"13107 39321 65535" {					;# Aero
	    set selectFg	SystemWindowText
	    set labelBd		4
	    set labelPadY	4

	    variable scalingpct
	    if {$::tcl_platform(osVersion) < 6.2} {		;# Win Vista/7
		set labelBg	#ffffff
		set activeBg	#e3f7ff
		set pressedBg	#Bce4f9
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set labelBg	#fcfcfc
		set activeBg	#f4f9ff
		set pressedBg	#f9fafb
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } else {						;# Win 10
		set labelBg	#ffffff
		set activeBg	#d9ebf9
		set pressedBg	#bcdcf4
		set arrowColor	#595959

		switch $scalingpct {
		    100 { set arrowStyle	flatAngle7x4 }
		    125 { set arrowStyle	flatAngle9x5 }
		    150 { set arrowStyle	flatAngle11x6 }
		    200 { set arrowStyle	flatAngle15x8 }
		}
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set selectBg	#d8effb
		set treeStyle	vistaAero
	    } elseif {$::tcl_platform(osVersion) == 6.1} {	;# Win 7
		set selectBg	#cee2fc
		set treeStyle	win7Aero
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set selectBg	#cbe8f6
		set treeStyle	win7Aero
	    } else {						;# Win 10
		set selectBg	#cce8ff
		set treeStyle	win10
	    }
	}

	default {						;# Win Classic
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		SystemButtonFace
	    set activeBg	SystemButtonFace
	    set pressedBg	SystemButtonFace
	    set labelBd		2
	    set labelPadY	0
	    set arrowColor	SystemButtonShadow

	    variable scalingpct
	    switch $scalingpct {
		100 { set arrowStyle	flat7x4 }
		125 { set arrowStyle	flat9x5 }
		150 { set arrowStyle	flat11x6 }
		200 { set arrowStyle	flat15x8 }
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set treeStyle	vistaClassic
	    } else {						;# Win 7/8
		set treeStyle	win7Classic
	    }
	}
    }

    array set themeDefaults [list \
	-selectbackground	$selectBg \
	-selectforeground	$selectFg \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labelBg \
	-labeldisabledBg	$labelBg \
	-labelactiveBg		$activeBg \
	-labelpressedBg		$pressedBg \
	-labelborderwidth	$labelBd \
	-labelpady		$labelPadY \
	-arrowcolor		$arrowColor \
	-arrowstyle		$arrowStyle \
	-treestyle		$treeStyle \
    ]
}

#------------------------------------------------------------------------------
# tablelist::winnativeTheme
#------------------------------------------------------------------------------
proc tablelist::winnativeTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		SystemWindow \
	-foreground		SystemWindowText \
	-disabledforeground	SystemDisabledText \
	-stripebackground	"" \
	-selectbackground	SystemHighlight \
	-selectforeground	SystemHighlightText \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	SystemButtonFace \
	-labeldeactivatedBg	SystemButtonFace \
	-labeldisabledBg	SystemButtonFace \
	-labelactiveBg		SystemButtonFace \
	-labelpressedBg		SystemButtonFace \
	-labelforeground	SystemButtonText \
	-labeldisabledFg	SystemDisabledText \
	-labelactiveFg		SystemButtonText \
	-labelpressedFg		SystemButtonText \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		0 \
	-arrowcolor		"" \
	-arrowstyle		sunken8x7 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::winxpblueTheme
#------------------------------------------------------------------------------
proc tablelist::winxpblueTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#565248 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#ece9d8 \
	-labeldeactivatedBg	#ece9d8 \
	-labeldisabledBg	#e3e1dd \
	-labelactiveBg		#c1d2ee \
	-labelpressedBg		#bab5ab \
	-labelforeground	black \
	-labeldisabledFg	#565248 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		#4d6185 \
	-arrowstyle		flat7x4 \
	-treestyle		winxpBlue \
    ]
}

#------------------------------------------------------------------------------
# tablelist::xpnativeTheme
#------------------------------------------------------------------------------
proc tablelist::xpnativeTheme {} {
    variable xpStyle
    variable themeDefaults
    array set themeDefaults [list \
	-background		SystemWindow \
	-foreground		SystemWindowText \
	-disabledforeground	SystemDisabledText \
	-stripebackground	"" \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelforeground	SystemButtonText \
	-labeldisabledFg	SystemDisabledText \
	-labelactiveFg		SystemButtonText \
	-labelpressedFg		SystemButtonText \
	-labelfont		TkDefaultFont \
    ]

    switch [winfo rgb . SystemHighlight] {
	"12593 27242 50629" {					;# Win XP Blue
	    set xpStyle		1
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		#ebeadb
	    set activeBg	#faf8f3
	    set pressedBg	#dedfd8
	    set labelBd		4
	    set labelPadY	4
	    set arrowColor	#aca899
	    set arrowStyle	flat9x5
	    set treeStyle	winxpBlue

	    if {[info exists tile::version] &&
		[string compare $tile::version 0.7] < 0} {
		set labelBd 0
	    }
	}

	"37779 41120 28784" {					;# Win XP Olive
	    set xpStyle		1
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		#ebeadb
	    set activeBg	#faf8f3
	    set pressedBg	#dedfd8
	    set labelBd		4
	    set labelPadY	4
	    set arrowColor	#aca899
	    set arrowStyle	flat9x5
	    set treeStyle	winxpOlive

	    if {[info exists tile::version] &&
		[string compare $tile::version 0.7] < 0} {
		set labelBd 0
	    }
	}

	"45746 46260 49087" {					;# Win XP Silver
	    set xpStyle		1
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		#f9fafd
	    set activeBg	#fefefe
	    set pressedBg	#ececf3
	    set labelBd		4
	    set labelPadY	4
	    set arrowColor	#aca899
	    set arrowStyle	flat9x5
	    set treeStyle	winxpSilver

	    if {[info exists tile::version] &&
		[string compare $tile::version 0.7] < 0} {
		set labelBd 0
	    }
	}

	"13107 39321 65535" {					;# Aero
	    set selectFg	SystemWindowText
	    set xpStyle		0
	    set labelBd		4
	    set labelPadY	4

	    variable scalingpct
	    if {$::tcl_platform(osVersion) < 6.2} {		;# Win Vista/7
		set labelBg	#ffffff
		set activeBg	#e3f7ff
		set pressedBg	#Bce4f9
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set labelBg	#fcfcfc
		set activeBg	#f4f9ff
		set pressedBg	#f9fafb
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } else {						;# Win 10
		set labelBg	#ffffff
		set activeBg	#d9ebf9
		set pressedBg	#bcdcf4
		set arrowColor	#595959

		switch $scalingpct {
		    100 { set arrowStyle	flatAngle7x4 }
		    125 { set arrowStyle	flatAngle9x5 }
		    150 { set arrowStyle	flatAngle11x6 }
		    200 { set arrowStyle	flatAngle15x8 }
		}
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set selectBg	#d8effb
		set treeStyle	vistaAero
	    } elseif {$::tcl_platform(osVersion) == 6.1} {	;# Win 7
		set selectBg	#cee2fc
		set treeStyle	win7Aero
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set selectBg	#cbe8f6
		set treeStyle	win7Aero
	    } else {						;# Win 10
		set selectBg	#cce8ff
		set treeStyle	win10
	    }
	}

	default {						;# Win Classic
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set xpStyle		0
	    set labelBg		SystemButtonFace
	    set activeBg	SystemButtonFace
	    set pressedBg	SystemButtonFace
	    set labelBd		2
	    set labelPadY	0
	    set arrowColor	SystemButtonShadow

	    variable scalingpct
	    switch $scalingpct {
		100 { set arrowStyle	flat7x4 }
		125 { set arrowStyle	flat9x5 }
		150 { set arrowStyle	flat11x6 }
		200 { set arrowStyle	flat15x8 }
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set treeStyle	vistaClassic
	    } else {						;# Win 7/8
		set treeStyle	win7Classic
	    }
	}
    }

    array set themeDefaults [list \
	-selectbackground	$selectBg \
	-selectforeground	$selectFg \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labelBg \
	-labeldisabledBg	$labelBg \
	-labelactiveBg		$activeBg \
	-labelpressedBg		$pressedBg \
	-labelborderwidth	$labelBd \
	-labelpady		$labelPadY \
	-arrowcolor		$arrowColor \
	-arrowstyle		$arrowStyle \
	-treestyle		$treeStyle \
    ]
}

#
# Private procedures performing RGB <-> HSV conversions
# =====================================================
#

#------------------------------------------------------------------------------
# tablelist::rgb2hsv
#
# Converts the specified RGB value to HSV.  The arguments are assumed to be
# integers in the interval [0, 65535].  The return value is a list of the form
# {h s v}, where h in [0.0, 360.0) and s, v in [0.0, 1.0].
#------------------------------------------------------------------------------
proc tablelist::rgb2hsv {r g b} {
    set r [expr {$r/65535.0}]
    set g [expr {$g/65535.0}]
    set b [expr {$b/65535.0}]

    #
    # Compute the value component
    #
    set sortedLst [lsort -real [list $r $g $b]]
    set v [lindex $sortedLst end]
    set dist [expr {$v - [lindex $sortedLst 0]}]

    #
    # Compute the saturation component
    #
    if {$v == 0.0} {
	set s 0.0
    } else {
	set s [expr {$dist/$v}]
    }

    #
    # Compute the hue component
    #
    if {$s == 0.0} {
	set h 0.0
    } else {
	set rc [expr {($v - $r)/$dist}]
	set gc [expr {($v - $g)/$dist}]
	set bc [expr {($v - $b)/$dist}]

	if {$v == $r} {
	    set h [expr {$bc - $gc}]
	} elseif {$v == $g} {
	    set h [expr {2 + $rc - $bc}]
	} else {
	    set h [expr {4 + $gc - $rc}]
	}
	set h [expr {$h*60}]
	if {$h < 0.0} {
	    set h [expr {$h + 360.0}]
	} elseif {$h >= 360.0} {
	    set h 0.0
	}
    }

    return [list $h $s $v]
}

#------------------------------------------------------------------------------
# tablelist::hsv2rgb
#
# Converts the specified HSV value to RGB.  The arguments are assumed to fulfil
# the conditions: h in [0.0, 360.0) and s, v in [0.0, 1.0].  The return value
# is a list of the form {r g b}, where r, g, and b are integers in the interval
# [0, 65535].
#------------------------------------------------------------------------------
proc tablelist::hsv2rgb {h s v} {
    set h [expr {$h/60.0}]
    set f [expr {$h - floor($h)}]

    set p1 [expr {round(65535.0*$v*(1 - $s))}]
    set p2 [expr {round(65535.0*$v*(1 - $s*$f))}]
    set p3 [expr {round(65535.0*$v*(1 - $s*(1 - $f)))}]

    set v  [expr {round(65535.0*$v)}]

    switch [expr {int($h)}] {
	0 { return [list $v  $p3 $p1] }
	1 { return [list $p2 $v  $p1] }
	2 { return [list $p1 $v  $p3] }
	3 { return [list $p1 $p2 $v ] }
	4 { return [list $p3 $p1 $v ] }
	5 { return [list $v  $p1 $p2] }
    }
}

#
# Private procedures related to global KDE configuration options
# ==============================================================
#

#------------------------------------------------------------------------------
# tablelist::getKdeConfigVal
#
# Returns the value of the global KDE configuration option identified by the
# given group (section) and key.
#------------------------------------------------------------------------------
proc tablelist::getKdeConfigVal {group key} {
    variable kdeDirList

    if {![info exists kdeDirList]} {
	makeKdeDirList 
    }

    #
    # Search for the entry corresponding to the given group and key in
    # the file "share/config/kdeglobals" within the KDE directories
    #
    foreach dir $kdeDirList {
	set fileName [file join $dir "share/config/kdeglobals"]
	if {[set val [readKdeConfigVal $fileName $group $key]] ne ""} {
	    return $val
	}
    }
    return ""
}

#------------------------------------------------------------------------------
# tablelist::makeKdeDirList
#
# Builds the list of the directories to be considered when searching for global
# KDE configuration options.
#------------------------------------------------------------------------------
proc tablelist::makeKdeDirList {} {
    variable kdeDirList {}

    if {[info exists ::env(KDE_SESSION_VERSION)]} {
	set ver $::env(KDE_SESSION_VERSION)
    } else {
	set ver ""
    }

    if {[info exists ::env(USER)] && $::env(USER) eq "root"} {
	set name "KDEROOTHOME"
    } else {
	set name "KDEHOME"
    }
    if {[info exists ::env($name)] && $::env($name) ne ""} {
	set localKdeDir [file normalize $::env($name)]
    } elseif {[info exists ::env(HOME)] && $::env(HOME) ne ""} {
	set localKdeDir [file normalize [file join $::env(HOME) ".kde$ver"]]
    }
    if {[info exists localKdeDir] && $localKdeDir ne "-"} {
	lappend kdeDirList $localKdeDir
    }

    if {[info exists ::env(KDEDIRS)] && $::env(KDEDIRS) ne ""} {
	foreach dir [split $::env(KDEDIRS) ":"] {
	    if {$dir ne ""} {
		lappend kdeDirList $dir
	    }
	}
    } elseif {[info exists ::env(KDEDIR)] && $::env(KDEDIR) ne ""} {
	lappend kdeDirList $::env(KDEDIR)
    }

    set prefix [exec kde$ver-config --expandvars --prefix]
    lappend kdeDirList $prefix

    set execPrefix [exec kde$ver-config --expandvars --exec-prefix]
    if {$execPrefix ne $prefix} {
	lappend kdeDirList $execPrefix
    }
}

#------------------------------------------------------------------------------
# tablelist::readKdeConfigVal
#
# Reads the value of the global KDE configuration option identified by the
# given group (section) and key from the specified file.  Note that the
# procedure performs a case-sensitive search and only works as expected for
# "simple" group and key names.
#------------------------------------------------------------------------------
proc tablelist::readKdeConfigVal {fileName group key} {
    if {[catch {open $fileName r} chan] != 0} {
	return ""
    }

    #
    # Search for the specified group
    #
    set groupFound 0
    while {[gets $chan line] >= 0} {
	set line [string trim $line]
	if {$line eq "\[$group\]"} {
	    set groupFound 1
	    break
	}
    }
    if {!$groupFound} {
	close $chan
	return ""
    }

    #
    # Search for the specified key within the group
    #
    set pattern "^$key\\s*=\\s*(.+)$"
    set keyFound 0
    while {[gets $chan line] >= 0} {
	set line [string trim $line]
	if {[string index $line 0] eq "\["} {
	    break
	}

	if {[regexp $pattern $line dummy val]} {
	    set keyFound 1
	    break
	}
    }

    close $chan
    return [expr {$keyFound ? $val : ""}]
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistUtil.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
#==============================================================================
# Contains private utility procedures for tablelist widgets.
#
# Structure of the module:
#   - Namespace initialization
#   - Private utility procedures
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Namespace initialization
# ========================
#

namespace eval tablelist {
    #
    # alignment -> anchor mapping
    #
    variable anchors
    array set anchors {
	left	w
	right	e
	center	center
    }

    #
    # <alignment, changeSnipSide> -> snipSide mapping
    #
    variable snipSides
    array set snipSides {
	left,0		r
	left,1		l
	right,0		l
	right,1		r
	center,0	r
	center,1	l
    }

    #
    # <incrArrowType, sortOrder> -> direction mapping
    #
    variable directions
    array set directions {
	up,increasing	Up
	up,decreasing	Dn
	down,increasing	Dn
	down,decreasing	Up
    }
}

#
# Private utility procedures
# ==========================
#

#------------------------------------------------------------------------------
# tablelist::rowIndex
#
# Checks the row index idx and returns either its numerical value or an error.
# endIsSize must be a boolean value: if true, end refers to the number of items
# in the tablelist, i.e., to the element just after the last one; if false, end
# refers to 1 less than the number of items, i.e., to the last element in the
# tablelist.  checkRange must be a boolean value: if true, it is additionally
# checked whether the numerical value corresponding to idx is within the
# allowed range.
#------------------------------------------------------------------------------
proc tablelist::rowIndex {win idx endIsSize {checkRange 0}} {
    upvar ::tablelist::ns${win}::data data

    if {[isInteger $idx]} {
	set index [expr {int($idx)}]
    } elseif {[string first $idx "end"] == 0} {
	if {$endIsSize} {
	    set index $data(itemCount)
	} else {
	    set index $data(lastRow)
	}
    } elseif {[string first $idx "last"] == 0} {
	set index $data(lastRow)
    } elseif {[string first $idx "top"] == 0} {
	displayItems $win
	set textIdx [$data(body) index @0,0]
	set index [expr {int($textIdx) - 1}]
    } elseif {[string first $idx "bottom"] == 0} {
	displayItems $win
	set textIdx [$data(body) index @0,$data(btmY)]
	set index [expr {int($textIdx) - 1}]
	if {$index > $data(lastRow)} {			;# text widget bug
	    set index $data(lastRow)
	}
    } elseif {[string first $idx "active"] == 0 && [string length $idx] >= 2} {
	set index $data(activeRow)
    } elseif {[string first $idx "anchor"] == 0 && [string length $idx] >= 2} {
	set index $data(anchorRow)
    } elseif {[scan $idx "@%d,%d" x y] == 2} {
	displayItems $win
	incr x -[winfo x $data(body)]
	incr y -[winfo y $data(body)]
	set textIdx [$data(body) index @$x,$y]
	set index [expr {int($textIdx) - 1}]
	if {$index > $data(lastRow)} {			;# text widget bug
	    set index $data(lastRow)
	}
    } elseif {[scan $idx "k%d" num] == 1} {
	set index [keyToRow $win k$num]
    } else {
	set idxIsEmpty [expr {[string length $idx] == 0}]
	for {set row 0} {$row < $data(itemCount)} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set hasName [info exists data($key-name)]
	    if {($hasName && [string compare $idx $data($key-name)] == 0) ||
		(!$hasName && $idxIsEmpty)} {
		set index $row
		break
	    }
	}
	if {$row == $data(itemCount)} {
	    return -code error \
		   "bad row index \"$idx\": must be active, anchor, end, last,\
		    top, bottom, @x,y, a number, a full key, or a name"
	}
    }

    if {$checkRange && ($index < 0 || $index > $data(lastRow))} {
	return -code error "row index \"$idx\" out of range"
    } else {
	return $index
    }
}

#------------------------------------------------------------------------------
# tablelist::colIndex
#
# Checks the column index idx and returns either its numerical value or an
# error.  checkRange must be a boolean value: if true, it is additionally
# checked whether the numerical value corresponding to idx is within the
# allowed range.
#------------------------------------------------------------------------------
proc tablelist::colIndex {win idx checkRange {decrX 1}} {
    upvar ::tablelist::ns${win}::data data

    if {[isInteger $idx]} {
	set index [expr {int($idx)}]
    } elseif {[string first $idx "end"] == 0 ||
	      [string first $idx "last"] == 0} {
	set index $data(lastCol)
    } elseif {[string first $idx "left"] == 0} {
	return [colIndex $win @0,0 $checkRange 0]
    } elseif {[string first $idx "right"] == 0} {
	return [colIndex $win @$data(rightX),0 $checkRange 0]
    } elseif {[string first $idx "active"] == 0 && [string length $idx] >= 2} {
	set index $data(activeCol)
    } elseif {[string first $idx "anchor"] == 0 && [string length $idx] >= 2} {
	set index $data(anchorCol)
    } elseif {[scan $idx "@%d,%d" x y] == 2} {
	synchronize $win
	displayItems $win
	if {$decrX} {
	    incr x -[winfo x $data(body)]
	    if {$x > $data(rightX)} {
		set x $data(rightX)
	    } elseif {$x < 0} {
		set x 0
	    }
	}
	set x [expr {$x + [winfo rootx $data(body)]}]

	set lastVisibleCol -1
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    if {$data($col-hide) || $data($col-elide)} {
		continue
	    }

	    set lastVisibleCol $col
	    set w $data(hdrTxtFrLbl)$col
	    set wX [winfo rootx $w]
	    if {$x >= $wX && $x < $wX + [winfo width $w]} {
		return $col
	    }
	}
	set index $lastVisibleCol
    } else {
	set idxIsEmpty [expr {[string length $idx] == 0}]
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    set hasName [info exists data($col-name)]
	    if {($hasName && [string compare $idx $data($col-name)] == 0) ||
		(!$hasName && $idxIsEmpty)} {
		set index $col
		break
	    }
	}
	if {$col == $data(colCount)} {
	    return -code error \
		   "bad column index \"$idx\": must be active, anchor,\
		    end, last, left, right, @x,y, a number, or a name"
	}
    }

    if {$checkRange && ($index < 0 || $index > $data(lastCol))} {
	return -code error "column index \"$idx\" out of range"
    } else {
	return $index
    }
}

#------------------------------------------------------------------------------
# tablelist::cellIndex
#
# Checks the cell index idx and returns either a list of the form {row col} or
# an error.  checkRange must be a boolean value: if true, it is additionally
# checked whether the two numerical values corresponding to idx are within the
# respective allowed ranges.
#------------------------------------------------------------------------------
proc tablelist::cellIndex {win idx checkRange} {
    upvar ::tablelist::ns${win}::data data

    set lst [split $idx ","]
    if {[llength $lst] == 2 &&
	[catch {rowIndex $win [lindex $lst 0] 0} row] == 0 &&
	[catch {colIndex $win [lindex $lst 1] 0} col] == 0} {
	# nothing
    } elseif {[string first $idx "end"] == 0 ||
	      [string first $idx "last"] == 0} {
	set row [rowIndex $win $idx 0]
	set col [colIndex $win $idx 0]
    } elseif {[string first $idx "active"] == 0 && [string length $idx] >= 2} {
	set row $data(activeRow)
	set col $data(activeCol)
    } elseif {[string first $idx "anchor"] == 0 && [string length $idx] >= 2} {
	set row $data(anchorRow)
	set col $data(anchorCol)
    } elseif {[string compare [string index $idx 0] "@"] == 0 &&
	      [catch {rowIndex $win $idx 0} row] == 0 &&
	      [catch {colIndex $win $idx 0} col] == 0} {
	# nothing
    } else {
	return -code error \
	       "bad cell index \"$idx\": must be active, anchor, end, last,\
	        @x,y, or row,col, where row must be active, anchor, end, last,\
		top, bottom, a number, a full key, or a name, and col must be\
		active, anchor, end, last, left, right, a number, or a name"
    }

    if {$checkRange && ($row < 0 || $row > $data(lastRow) ||
	$col < 0 || $col > $data(lastCol))} {
	return -code error "cell index \"$idx\" out of range"
    } else {
	return [list $row $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustRowIndex
#
# Sets the row index specified by $rowName to the index of the nearest
# (viewable) row.
#------------------------------------------------------------------------------
proc tablelist::adjustRowIndex {win rowName {forceViewable 0}} {
    upvar ::tablelist::ns${win}::data data $rowName row

    #
    # Don't operate on row directly, because $rowName might
    # be data(activeRow), in which case any temporary changes
    # made on row would trigger the activeTrace procedure
    #
    set _row $row
    if {$_row > $data(lastRow)} {
	set _row $data(lastRow)
    }
    if {$_row < 0} {
	set _row 0
    }

    if {$forceViewable} {
	set _rowSav $_row
	for {} {$_row < $data(itemCount)} {incr _row} {
	    set key [lindex $data(keyList) $_row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set row $_row
		return ""
	    }
	}
	for {set _row [expr {$_rowSav - 1}]} {$_row >= 0} {incr _row -1} {
	    set key [lindex $data(keyList) $_row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set row $_row
		return ""
	    }
	}
	set row 0
    } else {
	set row $_row
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustColIndex
#
# Sets the column index specified by $colName to the index of the nearest
# (viewable) column.
#------------------------------------------------------------------------------
proc tablelist::adjustColIndex {win colName {forceViewable 0}} {
    upvar ::tablelist::ns${win}::data data $colName col

    #
    # Don't operate on col directly, because $colName might
    # be data(activeCol), in which case any temporary changes
    # made on col would trigger the activeTrace procedure
    #
    set _col $col
    if {$_col > $data(lastCol)} {
	set _col $data(lastCol)
    }
    if {$_col < 0} {
	set _col 0
    }

    if {$forceViewable} {
	set _colSav $_col
	for {} {$_col < $data(colCount)} {incr _col} {
	    if {!$data($_col-hide)} {
		set col $_col
		return ""
	    }
	}
	for {set _col [expr {$_colSav - 1}]} {$_col >= 0} {incr _col -1} {
	    if {!$data($_col-hide)} {
		set col $_col
		return ""
	    }
	}
	set _col 0
    } else {
	set col $_col
    }
}

#------------------------------------------------------------------------------
# tablelist::nodeIndexToKey
#
# Checks the node index idx and returns either the corresponding full key or
# "root", or an error.
#------------------------------------------------------------------------------
proc tablelist::nodeIndexToKey {win idx} {
    if {[string first $idx "root"] == 0} {
	return "root"
    } elseif {[catch {rowIndex $win $idx 0} row] == 0} {
	upvar ::tablelist::ns${win}::data data
	if {$row < 0 || $row > $data(lastRow)} {
	    return -code error "node index \"$idx\" out of range"
	} else {
	    return [lindex $data(keyList) $row]
	}
    } else {
	return -code error \
	       "bad node index \"$idx\": must be root, active, anchor, end,\
		last, top, bottom, @x,y, a number, a full key, or a name"
    }
}

#------------------------------------------------------------------------------
# tablelist::depth
#
# Returns the number of steps from the node with the given full key to the root
# node of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::depth {win key} {
    upvar ::tablelist::ns${win}::data data

    set depth 0
    while {[string compare $key "root"] != 0} {
	incr depth
	set key $data($key-parent)
    }

    return $depth
}

#------------------------------------------------------------------------------
# tablelist::topLevelKey
#
# Returns the full key of the top-level item of the tablelist widget win having
# the item with the given key as descendant.
#------------------------------------------------------------------------------
proc tablelist::topLevelKey {win key} {
    upvar ::tablelist::ns${win}::data data

    set parentKey $data($key-parent)
    while {[string compare $parentKey "root"] != 0} {
	set key $data($key-parent)
	set parentKey $data($key-parent)
    }

    return $key
}

#------------------------------------------------------------------------------
# tablelist::descCount
#
# Returns the number of descendants of the node with the given full key of the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::descCount {win key} {
    upvar ::tablelist::ns${win}::data data

    if {[string compare $key "root"] == 0} {
	return $data(itemCount)
    } else {
	set count [llength $data($key-children)]
	foreach child $data($key-children) {
	    incr count [descCount $win $child]
	}
	return $count
    }
}

#------------------------------------------------------------------------------
# tablelist::nodeRow
#
# Returns the row of the child item identified by childIdx of the node given by
# parentKey within the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::nodeRow {win parentKey childIdx} {
    upvar ::tablelist::ns${win}::data data

    if {[isInteger $childIdx]} {
	if {$childIdx < [llength $data($parentKey-children)]} {
	    set childKey [lindex $data($parentKey-children) $childIdx]
	    return [keyToRow $win $childKey]
	} else {
	    return [expr {[keyToRow $win $parentKey] +
			  [descCount $win $parentKey] + 1}]
	}
    } elseif {[string first $childIdx "end"] == 0} {
	return [expr {[keyToRow $win $parentKey] +
		      [descCount $win $parentKey] + 1}]
    } elseif {[string first $childIdx "last"] == 0} {
	set childKey [lindex $data($parentKey-children) end]
	return [keyToRow $win $childKey]
    } else {
	return -code error \
	       "bad child index \"$childIdx\": must be end, last, or a number"
    }
}

#------------------------------------------------------------------------------
# tablelist::keyToRow
#
# Returns the row corresponding to the given full key within the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::keyToRow {win key} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $key "root"] == 0} {
	return -1
    } elseif {$data(keyToRowMapValid) && [info exists data($key-row)]} {
	return $data($key-row)
    } else {
	if {$::tcl_version >= 8.4} {
	    #
	    # Speed up the search by starting at the last found position
	    #
	    set row [lsearch -exact -start $data(searchStartIdx) \
		     $data(keyList) $key]
	    if {$row < 0 && $data(searchStartIdx) != 0} {
		set row [lsearch -exact $data(keyList) $key]
	    }
	    if {$row >= 0} {
		set data(searchStartIdx) $row
	    }

	    return $row
	} else {
	    return [lsearch -exact $data(keyList) $key]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateKeyToRowMap
#
# Updates the key -> row map associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::updateKeyToRowMap win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(mapId)]} {
	after cancel $data(mapId)
	unset data(mapId)
    }

    set row 0
    foreach key $data(keyList) {
	set data($key-row) $row
	incr row
    }

    set data(keyToRowMapValid) 1
}

#------------------------------------------------------------------------------
# tablelist::findTabs
#
# Searches for the first and last occurrences of the tab character in the cell
# range specified by firstCol and lastCol in the given line of the body text
# child of the tablelist widget win.  Assigns the index of the first tab to
# $idx1Name and the index of the last tab to $idx2Name.  It is assumed that
# both columns are non-hidden (but there may be hidden ones between them).
#------------------------------------------------------------------------------
proc tablelist::findTabs {win line firstCol lastCol idx1Name idx2Name} {
    upvar ::tablelist::ns${win}::data data $idx1Name idx1 $idx2Name idx2

    set w $data(body)
    set endIdx $line.end
    variable canElide
    variable elide

    set idx $line.1
    for {set col 0} {$col < $firstCol} {incr col} {
	if {!$data($col-hide) || $canElide} {
	    set idx [$w search $elide "\t" $idx $endIdx]+2c
	    if {[string compare $idx "+2c"] == 0} {
		return 0
	    }
	}
    }
    set idx1 [$w index $idx-1c]

    for {} {$col < $lastCol} {incr col} {
	if {!$data($col-hide) || $canElide} {
	    set idx [$w search $elide "\t" $idx $endIdx]+2c
	    if {[string compare $idx "+2c"] == 0} {
		return 0
	    }
	}
    }
    set idx2 [$w search $elide "\t" $idx $endIdx]
    if {[string length $idx2] == 0} {
	return 0
    }

    return 1
}

#------------------------------------------------------------------------------
# tablelist::sortStretchableColList
#
# Replaces the column indices different from end in the list of the stretchable
# columns of the tablelist widget win with their numerical equivalents and
# sorts the resulting list.
#------------------------------------------------------------------------------
proc tablelist::sortStretchableColList win {
    upvar ::tablelist::ns${win}::data data
    if {[llength $data(-stretch)] == 0 ||
	[string compare $data(-stretch) "all"] == 0} {
	return ""
    }

    set containsEnd 0
    foreach elem $data(-stretch) {
	if {[string first $elem "end"] == 0 ||
	    [string first $elem "last"] == 0} {
	    set containsEnd 1
	} else {
	    set tmp([colIndex $win $elem 0]) ""
	}
    }

    set data(-stretch) [lsort -integer [array names tmp]]
    if {$containsEnd} {
	lappend data(-stretch) end
    }
}

#------------------------------------------------------------------------------
# tablelist::deleteColData
#
# Cleans up the data associated with the col'th column of the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::deleteColData {win col} {
    upvar ::tablelist::ns${win}::data data
    if {$data(editCol) == $col} {
	set data(editCol) -1
	set data(editRow) -1
    }

    #
    # Remove the elements with names of the form $col-*
    #
    if {[info exists data($col-redispId)]} {
	after cancel $data($col-redispId)
    }
    foreach name [array names data $col-*] {
	unset data($name)
    }

    #
    # Remove the elements with names of the form k*,$col-*
    #
    foreach name [array names data k*,$col-*] {
	unset data($name)
	if {[string match "k*,$col-font" $name]} {
	    incr data(cellTagRefCount) -1
	} elseif {[string match "k*,$col-image" $name]} {
	    incr data(imgCount) -1
	} elseif {[string match "k*,$col-window" $name]} {
	    incr data(winCount) -1
	} elseif {[string match "k*,$col-indent" $name]} {
	    incr data(indentCount) -1
	}
    }

    #
    # Remove col from the list of stretchable columns if explicitly specified
    #
    if {[string compare $data(-stretch) "all"] != 0} {
	set stretchableCols {}
	foreach elem $data(-stretch) {
	    if {$elem != $col} {
		lappend stretchableCols $elem
	    }
	}
	set data(-stretch) $stretchableCols
    }
}

#------------------------------------------------------------------------------
# tablelist::deleteColAttribs
#
# Cleans up the attributes associated with the col'th column of the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::deleteColAttribs {win col} {
    upvar ::tablelist::ns${win}::attribs attribs

    #
    # Remove the elements with names of the form $col-*
    #
    foreach name [array names attribs $col-*] {
	unset attribs($name)
    }

    #
    # Remove the elements with names of the form k*,$col-*
    #
    foreach name [array names attribs k*,$col-*] {
	unset attribs($name)
    }
}

#------------------------------------------------------------------------------
# tablelist::moveColData
#
# Moves the elements of oldArrName corresponding to oldCol to those of
# newArrName corresponding to newCol.
#------------------------------------------------------------------------------
proc tablelist::moveColData {oldArrName newArrName imgArrName oldCol newCol} {
    upvar $oldArrName oldArr $newArrName newArr $imgArrName imgArr

    foreach specialCol {editCol -treecolumn treeCol} {
	if {$oldArr($specialCol) == $oldCol} {
	    set newArr($specialCol) $newCol
	}
    }

    set callerProc [lindex [info level -1] 0]
    if {[string compare $callerProc "moveCol"] == 0} {
	foreach specialCol {activeCol anchorCol} {
	    if {$oldArr($specialCol) == $oldCol} {
		set newArr($specialCol) $newCol
	    }
	}
    }

    if {$newCol < $newArr(colCount)} {
	foreach l [getSublabels $newArr(hdrTxtFrLbl)$newCol] {
	    destroy $l
	}
	set newArr(fmtCmdFlagList) \
	    [lreplace $newArr(fmtCmdFlagList) $newCol $newCol 0]
    }

    #
    # Move the elements of oldArr with names of the form $oldCol-*
    # to those of newArr with names of the form $newCol-*
    #
    foreach newName [array names newArr $newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr $oldCol-*] {
	regsub "$oldCol-" $oldName "$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)

	set tail [lindex [split $newName "-"] 1]
	switch $tail {
	    formatcommand {
		if {$newCol < $newArr(colCount)} {
		    set newArr(fmtCmdFlagList) \
			[lreplace $newArr(fmtCmdFlagList) $newCol $newCol 1]
		}
	    }
	    labelimage {
		set imgArr($newCol-$tail) $newArr($newName)
		unset newArr($newName)
	    }
	}
    }

    #
    # Move the elements of oldArr with names of the form k*,$oldCol-*
    # to those of newArr with names of the form k*,$newCol-*
    #
    foreach newName [array names newArr k*,$newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr k*,$oldCol-*] {
	regsub -- ",$oldCol-" $oldName ",$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }

    #
    # Replace oldCol with newCol in the list of
    # stretchable columns if explicitly specified
    #
    if {[info exists oldArr(-stretch)] &&
	[string compare $oldArr(-stretch) "all"] != 0} {
	set stretchableCols {}
	foreach elem $oldArr(-stretch) {
	    if {$elem == $oldCol} {
		lappend stretchableCols $newCol
	    } else {
		lappend stretchableCols $elem
	    }
	}
	set newArr(-stretch) $stretchableCols
    }
}

#------------------------------------------------------------------------------
# tablelist::moveColAttribs
#
# Moves the elements of oldArrName corresponding to oldCol to those of
# newArrName corresponding to newCol.
#------------------------------------------------------------------------------
proc tablelist::moveColAttribs {oldArrName newArrName oldCol newCol} {
    upvar $oldArrName oldArr $newArrName newArr

    #
    # Move the elements of oldArr with names of the form $oldCol-*
    # to those of newArr with names of the form $newCol-*
    #
    foreach newName [array names newArr $newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr $oldCol-*] {
	regsub "$oldCol-" $oldName "$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }

    #
    # Move the elements of oldArr with names of the form k*,$oldCol-*
    # to those of newArr with names of the form k*,$newCol-*
    #
    foreach newName [array names newArr k*,$newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr k*,$oldCol-*] {
	regsub -- ",$oldCol-" $oldName ",$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }
}

#------------------------------------------------------------------------------
# tablelist::deleteColFromCellList
#
# Returns the list obtained from a given list of cell indices by removing the
# elements whose column component equals a given column number.
#------------------------------------------------------------------------------
proc tablelist::deleteColFromCellList {cellList col} {
    set newCellList {}
    foreach cellIdx $cellList {
	scan $cellIdx "%d,%d" cellRow cellCol
	if {$cellCol != $col} {
	    lappend newCellList $cellIdx
	}
    }

    return $newCellList
}

#------------------------------------------------------------------------------
# tablelist::extractColFromCellList
#
# Returns the list of row indices obtained from those elements of a given list
# of cell indices whose column component equals a given column number.
#------------------------------------------------------------------------------
proc tablelist::extractColFromCellList {cellList col} {
    set rowList {}
    foreach cellIdx $cellList {
	scan $cellIdx "%d,%d" cellRow cellCol
	if {$cellCol == $col} {
	    lappend rowList $cellRow
	}
    }

    return $rowList
}

#------------------------------------------------------------------------------
# tablelist::replaceColInCellList
#
# Returns the list obtained from a given list of cell indices by replacing the
# occurrences of oldCol in the column components with newCol.
#------------------------------------------------------------------------------
proc tablelist::replaceColInCellList {cellList oldCol newCol} {
    set cellList [deleteColFromCellList $cellList $newCol]
    set newCellList {}
    foreach cellIdx $cellList {
	scan $cellIdx "%d,%d" cellRow cellCol
	if {$cellCol == $oldCol} {
	    lappend newCellList $cellRow,$newCol
	} else {
	    lappend newCellList $cellIdx
	}
    }

    return $newCellList
}

#------------------------------------------------------------------------------
# tablelist::condUpdateListVar
#
# Updates the list variable of the tablelist widget win if present.
#------------------------------------------------------------------------------
proc tablelist::condUpdateListVar win {
    upvar ::tablelist::ns${win}::data data
    if {$data(hasListVar)} {
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
	set var {}
	foreach item $data(itemList) {
	    lappend var [lrange $item 0 $data(lastCol)]
	}
	trace variable var wu $data(listVarTraceCmd)
    }
}

#------------------------------------------------------------------------------
# tablelist::reconfigColLabels
#
# Reconfigures the labels of the col'th column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::reconfigColLabels {win imgArrName col} {
    upvar ::tablelist::ns${win}::data data $imgArrName imgArr

    set optList {-labelalign -labelborderwidth -labelfont
		 -labelforeground -labelpady -labelrelief}
    variable usingTile
    if {!$usingTile} {
	lappend optList -labelbackground -labelheight
    }

    foreach opt $optList {
	if {[info exists data($col$opt)]} {
	    doColConfig $col $win $opt $data($col$opt)
	} else {
	    doColConfig $col $win $opt ""
	}
    }

    if {[info exists imgArr($col-labelimage)]} {
	doColConfig $col $win -labelimage $imgArr($col-labelimage)
    }
}

#------------------------------------------------------------------------------
# tablelist::charsToPixels
#
# Returns the width in pixels of the string consisting of a given number of "0"
# characters.
#------------------------------------------------------------------------------
proc tablelist::charsToPixels {win font charCount} {
    ### set str [string repeat "0" $charCount]
    set str ""
    for {set n 0} {$n < $charCount} {incr n} {
	append str 0
    }

    return [font measure $font -displayof $win $str]
}

#------------------------------------------------------------------------------
# tablelist::strRange
#
# Gets the largest initial (for snipSide = r) or final (for snipSide = l) range
# of characters from str whose width, when displayed in the given font, is no
# greater than pixels decremented by the width of snipStr.  Returns a string
# obtained from this substring by appending (for snipSide = r) or prepending
# (for snipSide = l) (part of) snipStr to it.
#------------------------------------------------------------------------------
proc tablelist::strRange {win str font pixels snipSide snipStr} {
    if {$pixels < 0} {
	return ""
    }

    if {[string length $snipSide] == 0} {
	return $str
    }


    set width [font measure $font -displayof $win $str]
    if {$width <= $pixels} {
	return $str
    }

    set snipWidth [font measure $font -displayof $win $snipStr]
    if {$pixels <= $snipWidth} {
	set str $snipStr
	set snipStr ""
    } else {
	incr pixels -$snipWidth
    }

    if {[string compare $snipSide "r"] == 0} {
	set idx [expr {[string length $str]*$pixels/$width - 1}]
	set subStr [string range $str 0 $idx]
	set width [font measure $font -displayof $win $subStr]
	if {$width < $pixels} {
	    while 1 {
		incr idx
		set subStr [string range $str 0 $idx]
		set width [font measure $font -displayof $win $subStr]
		if {$width > $pixels} {
		    incr idx -1
		    set subStr [string range $str 0 $idx]
		    return $subStr$snipStr
		} elseif {$width == $pixels} {
		    return $subStr$snipStr
		}
	    }
	} elseif {$width == $pixels} {
	    return $subStr$snipStr
	} else {
	    while 1 {
		incr idx -1
		set subStr [string range $str 0 $idx]
		set width [font measure $font -displayof $win $subStr]
		if {$width <= $pixels} {
		    return $subStr$snipStr
		}
	    }
	}

    } else {
	set idx [expr {[string length $str]*($width - $pixels)/$width}]
	set subStr [string range $str $idx end]
	set width [font measure $font -displayof $win $subStr]
	if {$width < $pixels} {
	    while 1 {
		incr idx -1
		set subStr [string range $str $idx end]
		set width [font measure $font -displayof $win $subStr]
		if {$width > $pixels} {
		    incr idx
		    set subStr [string range $str $idx end]
		    return $snipStr$subStr
		} elseif {$width == $pixels} {
		    return $snipStr$subStr
		}
	    }
	} elseif {$width == $pixels} {
	    return $snipStr$subStr
	} else {
	    while 1 {
		incr idx
		set subStr [string range $str $idx end]
		set width [font measure $font -displayof $win $subStr]
		if {$width <= $pixels} {
		    return $snipStr$subStr
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustItem
#
# Returns the list obtained by adjusting the list specified by item to the
# length expLen.
#------------------------------------------------------------------------------
proc tablelist::adjustItem {item expLen} {
    set len [llength $item]
    if {$len == $expLen} {
	return $item
    } elseif {$len > $expLen} {
	return [lrange $item 0 [expr {$expLen - 1}]]
    } else {
	for {set n $len} {$n < $expLen} {incr n} {
	    lappend item ""
	}
	return $item
    }
}

#------------------------------------------------------------------------------
# tablelist::formatElem
#
# Returns the string obtained by formatting the last argument.
#------------------------------------------------------------------------------
proc tablelist::formatElem {win key row col text} {
    upvar ::tablelist::ns${win}::data data
    array set data [list fmtKey $key fmtRow $row fmtCol $col]

    return [uplevel #0 $data($col-formatcommand) [list $text]]
}

#------------------------------------------------------------------------------
# tablelist::formatItem
#
# Returns the list obtained by formatting the elements of the last argument.
#------------------------------------------------------------------------------
proc tablelist::formatItem {win key row item} {
    upvar ::tablelist::ns${win}::data data
    array set data [list fmtKey $key fmtRow $row]
    set formattedItem {}
    set col 0
    foreach text $item fmtCmdFlag $data(fmtCmdFlagList) {
	if {$fmtCmdFlag} {
	    set data(fmtCol) $col
	    set text [uplevel #0 $data($col-formatcommand) [list $text]]
	}
	lappend formattedItem $text
	incr col
    }

    return $formattedItem
}

#------------------------------------------------------------------------------
# tablelist::hasChars
#
# Checks whether at least one element of the given list is a nonempty string.
#------------------------------------------------------------------------------
proc tablelist::hasChars list {
    foreach str $list {
	if {[string length $str] != 0} {
	    return 1
	}
    }

    return 0
}

#------------------------------------------------------------------------------
# tablelist::getListWidth
#
# Returns the max. number of pixels that the elements of the given list would
# use in the specified font when displayed in the window win.
#------------------------------------------------------------------------------
proc tablelist::getListWidth {win list font} {
    set width 0
    foreach str $list {
	set strWidth [font measure $font -displayof $win $str]
	if {$strWidth > $width} {
	    set width $strWidth
	}
    }

    return $width
}

#------------------------------------------------------------------------------
# tablelist::joinList
#
# Returns the string formed by joining together with "\n" the strings obtained 
# by applying strRange to the elements of the given list, with the specified
# arguments.
#------------------------------------------------------------------------------
proc tablelist::joinList {win list font pixels snipSide snipStr} {
    set list2 {}
    foreach str $list {
	lappend list2 [strRange $win $str $font $pixels $snipSide $snipStr]
    }

    return [join $list2 "\n"]
}

#------------------------------------------------------------------------------
# tablelist::displayIndent
#
# Displays an indentation image in a label widget to be embedded into the
# specified cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::displayIndent {win key col width} {
    #
    # Create a label widget and replace the binding tag Label with
    # $data(bodyTag) and TablelistBody in the list of its binding tags
    #
    upvar ::tablelist::ns${win}::data data
    set w $data(body).ind_$key,$col
    if {![winfo exists $w]} {
	tk::label $w -anchor w -borderwidth 0 -height 0 -highlightthickness 0 \
		     -image $data($key,$col-indent) -padx 0 -pady 0 \
		     -relief flat -takefocus 0 -width $width
	bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]
    }

    updateColorsWhenIdle $win
    return $w
}

#------------------------------------------------------------------------------
# tablelist::displayImage
#
# Displays an image in a label widget to be embedded into the specified cell of
# the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::displayImage {win key col anchor width} {
    #
    # Create a label widget and replace the binding tag Label with
    # $data(bodyTag) and TablelistBody in the list of its binding tags
    #
    upvar ::tablelist::ns${win}::data data
    set w $data(body).img_$key,$col
    if {![winfo exists $w]} {
	tk::label $w -anchor $anchor -borderwidth 0 -height 0 \
		     -highlightthickness 0 -image $data($key,$col-image) \
		     -padx 0 -pady 0 -relief flat -takefocus 0 -width $width
	bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]
    }

    updateColorsWhenIdle $win
    return $w
}

#------------------------------------------------------------------------------
# tablelist::displayText
#
# Displays the given text in a message widget to be embedded into the specified
# cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::displayText {win key col text font pixels alignment} {
    upvar ::tablelist::ns${win}::data data
    set w $data(body).msg_$key,$col
    if {![winfo exists $w]} {
	#
	# Create a message widget and replace the binding tag Message with
	# $data(bodyTag) and TablelistBody in the list of its binding tags
	#
	message $w -borderwidth 0 -highlightthickness 0 -padx 0 -pady 0 \
		   -relief flat -takefocus 0
	bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]
    }

    variable anchors
    set width $pixels
    if {$pixels == 0} {
	set width 1000000
    }
    $w configure -anchor $anchors($alignment) -font $font \
		 -justify $alignment -text $text -width $width

    updateColorsWhenIdle $win
    return $w
}

#------------------------------------------------------------------------------
# tablelist::getAuxData
#
# Gets the name, type, and width of the image or window associated with the
# specified cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getAuxData {win key col auxTypeName auxWidthName {pixels 0}} {
    upvar ::tablelist::ns${win}::data data \
	  $auxTypeName auxType $auxWidthName auxWidth

    if {[info exists data($key,$col-window)]} {
	if {$pixels != 0 && [info exists data($key,$col-stretchwindow)]} {
	    set auxType 3				;# dynamic-width window
	    set auxWidth [expr {$pixels + $data($col-delta)}]
	} else {
	    set auxType 2				;# static-width window
	    set auxWidth $data($key,$col-reqWidth)
	}
	return $data(body).frm_$key,$col
    } elseif {[info exists data($key,$col-image)]} {
	set auxType 1					;# image
	set auxWidth [image width $data($key,$col-image)]
	return [list ::tablelist::displayImage $win $key $col w 0]
    } else {
	set auxType 0					;# none
	set auxWidth 0
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::getIndentData
#
# Gets the creation script and width of the label displaying the indentation
# image associated with the specified cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getIndentData {win key col indentWidthName} {
    upvar ::tablelist::ns${win}::data data $indentWidthName indentWidth

    if {[info exists data($key,$col-indent)]} {
	set indentWidth [image width $data($key,$col-indent)]
	return [list ::tablelist::displayIndent $win $key $col 0]
    } else {
	set indentWidth 0
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::getMaxTextWidth
#
# Returns the number of pixels available for displaying the text of a static-
# width tablelist cell.
#------------------------------------------------------------------------------
proc tablelist::getMaxTextWidth {pixels auxWidth indentWidth} {
    if {$indentWidth != 0} {
	incr pixels -$indentWidth
	if {$pixels <= 0} {
	    set pixels 1
	}
    }

    if {$auxWidth == 0} {
	return $pixels
    } else {
	set lessPixels [expr {$pixels - $auxWidth - 5}]
	if {$lessPixels > 0} {
	    return $lessPixels
	} else {
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustElem
#
# Prepares the text specified by $textName and the auxiliary object width
# specified by $auxWidthName for insertion into a cell of the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::adjustElem {win textName auxWidthName indentWidthName font
			    pixels snipSide snipStr} {
    upvar $textName text $auxWidthName auxWidth $indentWidthName indentWidth

    if {$pixels == 0} {				;# convention: dynamic width
	if {$auxWidth != 0 && [string length $text] != 0} {
	    incr auxWidth 3
	}
    } elseif {$indentWidth >= $pixels} {
	set indentWidth $pixels
	set text ""				;# can't display the text
	set auxWidth 0				;# can't display the aux. object
    } else {
	incr pixels -$indentWidth
	if {$auxWidth == 0} {			;# no image or window
	    set text [strRange $win $text $font $pixels $snipSide $snipStr]
	} elseif {[string length $text] == 0} {	;# aux. object w/o text
	    if {$auxWidth > $pixels} {
		set auxWidth $pixels
	    }
	} else {				;# both aux. object and text
	    if {$auxWidth + 5 <= $pixels} {
		incr auxWidth 3
		incr pixels -[expr {$auxWidth + 2}]
		set text [strRange $win $text $font $pixels $snipSide $snipStr]
	    } elseif {$auxWidth <= $pixels} {
		set text ""			;# can't display the text
	    } else {
		set auxWidth $pixels
		set text ""			;# can't display the text
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustMlElem
#
# Prepares the list specified by $listName and the auxiliary object width
# specified by $auxWidthName for insertion into a multiline cell of the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::adjustMlElem {win listName auxWidthName indentWidthName font
			      pixels snipSide snipStr} {
    upvar $listName list $auxWidthName auxWidth $indentWidthName indentWidth

    set list2 {}
    if {$pixels == 0} {				;# convention: dynamic width
	if {$auxWidth != 0 && [hasChars $list]} {
	    incr auxWidth 3
	}
    } elseif {$indentWidth >= $pixels} {
	set indentWidth $pixels
	foreach str $list {
	    lappend list2 ""
	}
	set list $list2				;# can't display the text
	set auxWidth 0				;# can't display the aux. object
    } else {
	incr pixels -$indentWidth
	if {$auxWidth == 0} {			;# no image or window
	    foreach str $list {
		lappend list2 \
		    [strRange $win $str $font $pixels $snipSide $snipStr]
	    }
	    set list $list2
	} elseif {![hasChars $list]} {		;# aux. object w/o text
	    if {$auxWidth > $pixels} {
		set auxWidth $pixels
	    }
	} else {				;# both aux. object and text
	    if {$auxWidth + 5 <= $pixels} {
		incr auxWidth 3
		incr pixels -[expr {$auxWidth + 2}]
		foreach str $list {
		    lappend list2 \
			[strRange $win $str $font $pixels $snipSide $snipStr]
		}
		set list $list2
	    } elseif {$auxWidth <= $pixels} {
		foreach str $list {
		    lappend list2 ""
		}
		set list $list2			;# can't display the text
	    } else {
		set auxWidth $pixels
		foreach str $list {
		    lappend list2 ""
		}
		set list $list2			;# can't display the text
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::getElemWidth
#
# Returns the number of pixels that the given text together with the aux.
# object (image or window) of the specified width would use when displayed in a
# cell of a dynamic-width column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getElemWidth {win text auxWidth indentWidth cellFont} {
    if {[string match "*\n*" $text]} {
	set list [split $text "\n"]
	if {$auxWidth != 0 && [hasChars $list]} {
	    incr auxWidth 5
	}
	return [expr {[getListWidth $win $list $cellFont] +
		      $auxWidth + $indentWidth}]
    } else {
	if {$auxWidth != 0 && [string length $text] != 0} {
	    incr auxWidth 5
	}
	return [expr {[font measure $cellFont -displayof $win $text] +
		      $auxWidth + $indentWidth}]
    }
}

#------------------------------------------------------------------------------
# tablelist::insertOrUpdateIndent
#
# Sets the width of the indentation label embedded into the text widget w at
# the given index to the specified value, after inserting the label if needed.
# Returns 1 if the label had to be inserted and 0 otherwise.
#------------------------------------------------------------------------------
proc tablelist::insertOrUpdateIndent {w index indent indentWidth} {
    if {[catch {$w window cget $index -create} script] == 0 &&
	[string match "::tablelist::displayIndent *" $script]} {
	if {$indentWidth != [lindex $script end]} {
	    set padY [expr {[$w cget -spacing1] == 0}]
	    set script [lreplace $script end end $indentWidth]
	    $w window configure $index -pady $padY -create $script

	    set path [lindex [$w dump -window $index] 1]
	    if {[string length $path] != 0} {
		$path configure -width $indentWidth
	    }
	}
	return 0
    } else {
	set padY [expr {[$w cget -spacing1] == 0}]
	set indent [lreplace $indent end end $indentWidth]
	$w window create $index -pady $padY -create $indent
	$w tag add elidedWin $index
	return 1
    }
}

#------------------------------------------------------------------------------
# tablelist::insertElem
#
# Inserts the given text and auxiliary object (image or window) into the text
# widget w, just before the character position specified by index.  The object
# will follow the text if alignment is "right", and will precede it otherwise.
#------------------------------------------------------------------------------
proc tablelist::insertElem {w index text aux auxType alignment valignment} {
    set index [$w index $index]

    if {$auxType == 0} {				;# no image or window
	$w insert $index $text
    } elseif {[string compare $alignment "right"] == 0} {
	set padY [expr {[$w cget -spacing1] == 0}]
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 e]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor ne -relwidth "" -relx 1.0
	    } else {						;# dynamic width
		place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
	$w insert $index $text
    } else {
	$w insert $index $text
	set padY [expr {[$w cget -spacing1] == 0}]
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 w]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor nw -relwidth "" -relx 0.0
	    } else {						;# dynamic width
		place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::insertMlElem
#
# Inserts the given message widget and auxiliary object (image or window) into
# the text widget w, just before the character position specified by index.
# The object will follow the message widget if alignment is "right", and will
# precede it otherwise.
#------------------------------------------------------------------------------
proc tablelist::insertMlElem {w index msgScript aux auxType alignment
			      valignment} {
    set index [$w index $index]
    set padY [expr {[$w cget -spacing1] == 0}]

    if {$auxType == 0} {				;# no image or window
	$w window create $index -align top -pady $padY -create $msgScript
	$w tag add elidedWin $index
    } elseif {[string compare $alignment "right"] == 0} {
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 e]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor ne -relwidth "" -relx 1.0
	    } else {						;# dynamic width
		place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
	$w window create $index -align top -pady $padY -create $msgScript
	$w tag add elidedWin $index
    } else {
	$w window create $index -align top -pady $padY -create $msgScript
	$w tag add elidedWin $index
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 w]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor nw -relwidth "" -relx 0.0
	    } else {						;# dynamic width
		place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateCell
#
# Updates the contents of the text widget w starting at index1 and ending just
# before index2 by keeping the auxiliary object (image or window) (if any) and
# replacing only the text between the two character positions.
#------------------------------------------------------------------------------
proc tablelist::updateCell {w index1 index2 text aux auxType auxWidth
			    indent indentWidth alignment valignment} {
    set tagNames [$w tag names $index2]
    if {[lsearch -exact $tagNames select] >= 0} {		;# selected
	$w tag add select $index1 $index2
    }

    if {$indentWidth != 0} {
	if {[insertOrUpdateIndent $w $index1 $indent $indentWidth]} {
	    set index2 $index2+1c
	}
	set index1 $index1+1c
    }

    if {$auxWidth == 0} {				;# no image or window
	#
	# Work around a Tk peculiarity on Windows, related to deleting
	# an embedded window while resizing a text widget interactively
	#
	set path [lindex [$w dump -window $index1] 1]
	if {[string length $path] != 0 &&
	    [string compare [winfo class $path] "Message"] == 0} {
	    $path configure -text ""
	    $w window configure $index1 -window ""
	}

	if {$::tk_version >= 8.5} {
	    $w replace $index1 $index2 $text
	} else {
	    $w delete $index1 $index2
	    $w insert $index1 $text
	}
    } else {
	#
	# Check whether the image label or the frame containing a
	# window is mapped at the first or last position of the cell
	#
	if {$auxType == 1} {					;# image
	    if {[setImgLabelWidth $w $index1 $auxWidth]} {
		set auxFound 1
		set fromIdx $index1+1c
		set toIdx $index2
	    } elseif {[setImgLabelWidth $w $index2-1c $auxWidth]} {
		set auxFound 1
		set fromIdx $index1
		set toIdx $index2-1c
	    } else {
		set auxFound 0
		set fromIdx $index1
		set toIdx $index2
	    }
	} else {						;# window
	    if {[$aux cget -width] != $auxWidth} {
		$aux configure -width $auxWidth
	    }

	    if {[string compare [lindex [$w dump -window $index1] 1] \
		 $aux] == 0} {
		set auxFound 1
		set fromIdx $index1+1c
		set toIdx $index2
	    } elseif {[string compare [lindex [$w dump -window $index2-1c] 1] \
		       $aux] == 0} {
		set auxFound 1
		set fromIdx $index1
		set toIdx $index2-1c
	    } else {
		set auxFound 0
		set fromIdx $index1
		set toIdx $index2
	    }
	}

	#
	# Work around a Tk peculiarity on Windows, related to deleting
	# an embedded window while resizing a text widget interactively
	#
	set path [lindex [$w dump -window $fromIdx] 1]
	if {[string length $path] != 0 &&
	    [string compare [winfo class $path] "Message"] == 0} {
	    $path configure -text ""
	    $w window configure $fromIdx -window ""
	}

	$w delete $fromIdx $toIdx

	if {$auxFound} {
	    #
	    # Adjust the aux. window and insert the text
	    #
	    if {[string compare $alignment "right"] == 0} {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w $index1 e
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor ne -relwidth "" -relx 1.0
		    } else {					;# dynamic width
			place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
		    }
		}
		set index $index1
	    } else {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w $index1 w
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor nw -relwidth "" -relx 0.0
		    } else {					;# dynamic width
			place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
		    }
		}
		set index $index1+1c
	    }
	    if {[string compare $valignment [$w window cget $index1 -align]]
		!= 0} {
		$w window configure $index1 -align $valignment
	    }
	    $w insert $index $text
	} else {
	    #
	    # Insert the text and the aux. window
	    #
	    if {$auxType == 1} {				;# image
		set aux [lreplace $aux end end $auxWidth]
	    } else {						;# window
		if {[$aux cget -width] != $auxWidth} {
		    $aux configure -width $auxWidth
		}
	    }
	    insertElem $w $index1 $text $aux $auxType $alignment $valignment
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateMlCell
#
# Updates the contents of the text widget w starting at index1 and ending just
# before index2 by keeping the auxiliary object (image or window) (if any) and
# replacing only the multiline text between the two character positions.
#------------------------------------------------------------------------------
proc tablelist::updateMlCell {w index1 index2 msgScript aux auxType auxWidth
			      indent indentWidth alignment valignment} {
    set tagNames [$w tag names $index2]
    if {[lsearch -exact $tagNames select] >= 0} {		;# selected
	$w tag add select $index1 $index2
    }

    if {$indentWidth != 0} {
	if {[insertOrUpdateIndent $w $index1 $indent $indentWidth]} {
	    set index2 $index2+1c
	}
	set index1 $index1+1c
    }

    if {$auxWidth == 0} {				;# no image or window
	set areEqual [$w compare $index1 == $index2]
	$w delete $index1+1c $index2
	set padY [expr {[$w cget -spacing1] == 0}]
	if {[catch {$w window cget $index1 -create} script] == 0 &&
	    [string match "::tablelist::displayText*" $script]} {
	    $w window configure $index1 \
		      -align top -pady $padY -create $msgScript

	    set path [lindex [$w dump -window $index1] 1]
	    if {[string length $path] != 0 &&
		[string compare [winfo class $path] "Message"] == 0} {
		eval $msgScript
	    }
	} else {
	    if {!$areEqual} {
		$w delete $index1
	    }
	    $w window create $index1 -align top -pady $padY -create $msgScript
	    $w tag add elidedWin $index1
	}
    } else {
	#
	# Check whether the image label or the frame containing a
	# window is mapped at the first or last position of the cell
	#
	$w mark set index2Mark $index2
	if {$auxType == 1} {					;# image
	    if {[setImgLabelWidth $w $index1 $auxWidth]} {
		set auxFound 1
		if {[string compare $alignment "right"] == 0} {
		    $w delete $index1+1c $index2
		}
	    } elseif {[setImgLabelWidth $w $index2-1c $auxWidth]} {
		set auxFound 1
		if {[string compare $alignment "right"] != 0} {
		    $w delete $index1 $index2-1c
		}
	    } else {
		set auxFound 0
		$w delete $index1 $index2
	    }
	} else {						;# window
	    if {[$aux cget -width] != $auxWidth} {
		$aux configure -width $auxWidth
	    }

	    if {[string compare [lindex [$w dump -window $index1] 1] \
		 $aux] == 0} {
		set auxFound 1
		if {[string compare $alignment "right"] == 0} {
		    $w delete $index1+1c $index2
		}
	    } elseif {[string compare [lindex [$w dump -window $index2-1c] 1] \
		       $aux] == 0} {
		set auxFound 1
		if {[string compare $alignment "right"] != 0} {
		    $w delete $index1 $index2-1c
		}
	    } else {
		set auxFound 0
		$w delete $index1 $index2
	    }
	}

	if {$auxFound} {
	    #
	    # Adjust the aux. window and insert the message widget
	    #
	    if {[string compare $alignment "right"] == 0} {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w index2Mark-1c e
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor ne -relwidth "" -relx 1.0
		    } else {					;# dynamic width
			place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
		    }
		}
		set auxIdx index2Mark-1c
		set msgIdx index2Mark-2c
	    } else {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w $index1 w
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor nw -relwidth "" -relx 0.0
		    } else {					;# dynamic width
			place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
		    }
		}
		set auxIdx $index1
		set msgIdx $index1+1c
	    }
	    if {[string compare $valignment [$w window cget $auxIdx -align]]
		!= 0} {
		$w window configure $auxIdx -align $valignment
	    }

	    set padY [expr {[$w cget -spacing1] == 0}]
	    if {[catch {$w window cget $msgIdx -create} script] == 0 &&
		[string match "::tablelist::displayText*" $script]} {
		$w window configure $msgIdx \
			  -align top -pady $padY -create $msgScript

		set path [lindex [$w dump -window $msgIdx] 1]
		if {[string length $path] != 0 &&
		    [string compare [winfo class $path] "Message"] == 0} {
		    eval $msgScript
		}
	    } elseif {[string compare $alignment "right"] == 0} {
		$w window create index2Mark-1c \
			  -align top -pady $padY -create $msgScript
		$w tag add elidedWin index2Mark-1c
		$w delete $index1 index2Mark-2c
	    } else {
		$w window create $index1+1c \
			  -align top -pady $padY -create $msgScript
		$w tag add elidedWin $index1+1c
		$w delete $index1+2c index2Mark
	    }
	} else {
	    #
	    # Insert the message and aux. windows
	    #
	    if {$auxType == 1} {				;# image
		set aux [lreplace $aux end end $auxWidth]
	    } else {						;# window
		if {[$aux cget -width] != $auxWidth} {
		    $aux configure -width $auxWidth
		}
	    }
	    insertMlElem $w $index1 $msgScript $aux $auxType $alignment \
			 $valignment
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::setImgLabelWidth
#
# Sets the width of the image label embedded into the text widget w at the
# given index to the specified value.
#------------------------------------------------------------------------------
proc tablelist::setImgLabelWidth {w index width} {
    if {[catch {$w window cget $index -create} script] == 0 &&
	[string match "::tablelist::displayImage *" $script]} {
	if {$width != [lindex $script end]} {
	    set padY [expr {[$w cget -spacing1] == 0}]
	    set script [lreplace $script end end $width]
	    $w window configure $index -pady $padY -create $script

	    set path [lindex [$w dump -window $index] 1]
	    if {[string length $path] != 0} {
		$path configure -width $width
	    }
	}

	return 1
    } else {
	return 0
    }
}

#------------------------------------------------------------------------------
# tablelist::setImgLabelAnchor
#
# Sets the anchor of the image label embedded into the text widget w at the
# given index to the specified value.
#------------------------------------------------------------------------------
proc tablelist::setImgLabelAnchor {w index anchor} {
    set script [$w window cget $index -create]
    if {[string compare $anchor [lindex $script 4]] != 0} {
	set padY [expr {[$w cget -spacing1] == 0}]
	set script [lreplace $script 4 4 $anchor]
	$w window configure $index -pady $padY -create $script

	set path [lindex [$w dump -window $index] 1]
	if {[string length $path] != 0} {
	    $path configure -anchor $anchor
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::appendComplexElem
#
# Adjusts the given text and the width of the auxiliary object (image or
# window) corresponding to the specified cell of the tablelist widget win, and
# inserts the text and the auxiliary object (if any) just before the newline
# character at the end of the specified line of the tablelist's body.
#------------------------------------------------------------------------------
proc tablelist::appendComplexElem {win key row col text pixels alignment
				   snipStr cellFont cellTags line} {
    #
    # Adjust the cell text and the image or window width
    #
    set multiline [string match "*\n*" $text]
    upvar ::tablelist::ns${win}::data data
    if {$pixels == 0} {				;# convention: dynamic width
	if {$data($col-maxPixels) > 0} {
	    if {$data($col-reqPixels) > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
	    }
	}
    }
    set aux [getAuxData $win $key $col auxType auxWidth $pixels]
    set indent [getIndentData $win $key $col indentWidth]
    set maxTextWidth $pixels
    if {$pixels != 0} {
	incr pixels $data($col-delta)
	set maxTextWidth [getMaxTextWidth $pixels $auxWidth $indentWidth]

	if {$data($col-wrap) && !$multiline} {
	    if {[font measure $cellFont -displayof $win $text] >
		$maxTextWidth} {
		set multiline 1
	    }
	}
    }
    variable snipSides
    set snipSide $snipSides($alignment,$data($col-changesnipside))
    if {$multiline} {
	set list [split $text "\n"]
	if {$data($col-wrap)} {
	    set snipSide ""
	}
	adjustMlElem $win list auxWidth indentWidth $cellFont $pixels \
		     $snipSide $snipStr
	set msgScript [list ::tablelist::displayText $win $key $col \
		       [join $list "\n"] $cellFont $maxTextWidth $alignment]
    } else {
	adjustElem $win text auxWidth indentWidth $cellFont $pixels \
		   $snipSide $snipStr
    }

    #
    # Insert the text and the auxiliary object (if any) just before the newline
    #
    set w $data(body)
    set idx [$w index $line.end]
    if {$auxWidth == 0} {				;# no image or window
	if {$multiline} {
	    $w insert $line.end "\t\t" $cellTags
	    set padY [expr {[$w cget -spacing1] == 0}]
	    $w window create $line.end-1c \
		      -align top -pady $padY -create $msgScript
	    $w tag add elidedWin $line.end-1c
	} else {
	    $w insert $line.end "\t$text\t" $cellTags
	}
    } else {
	$w insert $line.end "\t\t" $cellTags
	if {$auxType == 1} {					;# image
	    #
	    # Update the creation script for the image label
	    #
	    set aux [lreplace $aux end end $auxWidth]
	} else {						;# window
	    #
	    # Create a frame and evaluate the script that
	    # creates a child window within the frame
	    #
	    tk::frame $aux -borderwidth 0 -class TablelistWindow -container 0 \
			   -height $data($key,$col-reqHeight) \
			   -highlightthickness 0 -relief flat \
			   -takefocus 0 -width $auxWidth
	    catch {$aux configure -padx 0 -pady 0}
	    bindtags $aux [linsert [bindtags $aux] 1 \
			   $data(bodyTag) TablelistBody]
	    uplevel #0 $data($key,$col-window) [list $win $row $col $aux.w]
	}
	if {$multiline} {
	    insertMlElem $w $line.end-1c $msgScript $aux $auxType $alignment \
			 [getVAlignment $win $key $col]
	} else {
	    insertElem $w $line.end-1c $text $aux $auxType $alignment \
		       [getVAlignment $win $key $col]
	}
    }

    #
    # Insert the indentation image, if any
    #
    if {$indentWidth != 0} {
	insertOrUpdateIndent $w $idx+1c $indent $indentWidth
    }
}

#------------------------------------------------------------------------------
# tablelist::makeColFontAndTagLists
#
# Builds the lists data(colFontList) of the column fonts and data(colTagsList)
# of the column tag names for the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeColFontAndTagLists win {
    upvar ::tablelist::ns${win}::data data
    set widgetFont $data(-font)
    set data(colFontList) {}
    set data(colTagsList) {}
    set data(hasColTags) 0
    set viewable [winfo viewable $win]
    variable canElide

    for {set col 0} {$col < $data(colCount)} {incr col} {
	set tagNames {}

	if {[info exists data($col-font)]} {
	    lappend data(colFontList) $data($col-font)
	    lappend tagNames col-font-$data($col-font)
	    set data(hasColTags) 1
	} else {
	    lappend data(colFontList) $widgetFont
	}

	if {$viewable && $data($col-hide) && $canElide} {
	    lappend tagNames hiddenCol
	    set data(hasColTags) 1
	}

	lappend data(colTagsList) $tagNames
    }
}

#------------------------------------------------------------------------------
# tablelist::makeSortAndArrowColLists
#
# Builds the lists data(sortColList) of the sort columns and data(arrowColList)
# of the arrow columns for the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeSortAndArrowColLists win {
    upvar ::tablelist::ns${win}::data data
    set data(sortColList) {}
    set data(arrowColList) {}

    #
    # Build a list of {col sortRank} pairs and sort it based on sortRank
    #
    set pairList {}
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {$data($col-sortRank) > 0} {
	    lappend pairList [list $col $data($col-sortRank)]
	}
    }
    set pairList [lsort -integer -index 1 $pairList]

    #
    # Build data(sortColList) and data(arrowColList), and update
    # the sort ranks to have values from 1 to [llength $pairList]
    #
    set sortRank 1
    foreach pair $pairList {
	set col [lindex $pair 0]
	lappend data(sortColList) $col
	set data($col-sortRank) $sortRank
	if {$sortRank < 10 && $data(-showarrow) && $data($col-showarrow)} {
	    lappend data(arrowColList) $col
	    configCanvas $win $col
	    raiseArrow $win $col
	}
	incr sortRank
    }

    #
    # Special handling for the "aqua" theme if Cocoa is being used:
    # Deselect all header labels and select that of the main sort column
    #
    variable specialAquaHandling
    if {$specialAquaHandling &&
	[string compare [getCurrentTheme] "aqua"] == 0} {
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    configLabel $data(hdrTxtFrLbl)$col -selected 0
	}

	if {[llength $data(sortColList)] != 0} {
	    set col [lindex $data(sortColList) 0]
	    configLabel $data(hdrTxtFrLbl)$col -selected 1
	    raise $data(hdrTxtFrLbl)$col
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::setupColumns
#
# Updates the value of the -colums configuration option for the tablelist
# widget win by using the width, title, and alignment specifications given in
# the columns argument, and creates the corresponding label (and separator)
# widgets if createLabels is true.
#------------------------------------------------------------------------------
proc tablelist::setupColumns {win columns createLabels} {
    variable usingTile
    variable configSpecs
    variable configOpts
    variable alignments
    upvar ::tablelist::ns${win}::data data

    set argCount [llength $columns]
    set colConfigVals {}

    #
    # Check the syntax of columns before performing any changes
    #
    for {set n 0} {$n < $argCount} {incr n} {
	#
	# Get the column width
	#
	set width [lindex $columns $n]
	set width [format "%d" $width]	;# integer check with error message

	#
	# Get the column title
	#
	if {[incr n] == $argCount} {
	    return -code error "column title missing"
	}
	set title [lindex $columns $n]

	#
	# Get the column alignment
	#
	set alignment left
	if {[incr n] < $argCount} {
	    set next [lindex $columns $n]
	    if {[isInteger $next]} {
		incr n -1
	    } else {
		set alignment [mwutil::fullOpt "alignment" $next $alignments]
	    }
	}

	#
	# Append the properly formatted values of width,
	# title, and alignment to the list colConfigVals
	#
	lappend colConfigVals $width $title $alignment
    }

    #
    # Save the value of colConfigVals in data(-columns)
    #
    set data(-columns) $colConfigVals

    #
    # Delete the labels, canvases, and separators if requested
    #
    if {$createLabels} {
	foreach w [winfo children $data(hdrTxtFr)] {
	    destroy $w
	}
	foreach w [winfo children $win] {
	    if {[regexp {^(sep[0-9]+|hsep)$} [winfo name $w]]} {
		destroy $w
	    }
	}
	set data(fmtCmdFlagList) {}
	set data(hiddenColCount) 0
    }

    #
    # Build the list data(colList), and create
    # the labels and canvases if requested
    #
    regexp {^(flat|flatAngle|sunken|photo)([0-9]+)x([0-9]+)$} \
	   $data(-arrowstyle) dummy arrowRelief arrowWidth arrowHeight
    set widgetFont $data(-font)
    set oldColCount $data(colCount)
    set data(colList) {}
    set data(colCount) 0
    set data(lastCol) -1
    set col 0
    foreach {width title alignment} $data(-columns) {
	#
	# Append the width in pixels and the
	# alignment to the list data(colList)
	#
	if {$width > 0} {		;# convention: width in characters
	    set pixels [charsToPixels $win $widgetFont $width]
	    set data($col-lastStaticWidth) $pixels
	} elseif {$width < 0} {		;# convention: width in pixels
	    set pixels [expr {(-1)*$width}]
	    set data($col-lastStaticWidth) $pixels
	} else {			;# convention: dynamic width
	    set pixels 0
	}
	lappend data(colList) $pixels $alignment
	incr data(colCount)
	set data(lastCol) $col

	if {$createLabels} {
	    set data($col-elide) 0
	    foreach {name val} {delta 0  lastStaticWidth 0  maxPixels 0
				sortOrder ""  sortRank 0  isSnipped 0
				changesnipside 0  changetitlesnipside 0
				editable 0  editwindow entry  hide 0
				maxwidth 0  resizable 1  showarrow 1
				showlinenumbers 0  sortmode ascii
				valign center  wrap 0} {
		if {![info exists data($col-$name)]} {
		    set data($col-$name) $val
		}
	    }
	    lappend data(fmtCmdFlagList) [info exists data($col-formatcommand)]
	    incr data(hiddenColCount) $data($col-hide)

	    #
	    # Create the label
	    #
	    set w $data(hdrTxtFrLbl)$col
	    if {$usingTile} {
		ttk::label $w -style TablelistHeader.TLabel -image "" \
			      -padding {1 1 1 1} -takefocus 0 -text "" \
			      -textvariable "" -underline -1 -wraplength 0
	    } else {
		tk::label $w -bitmap "" -highlightthickness 0 -image "" \
			     -takefocus 0 -text "" -textvariable "" \
			     -underline -1 -wraplength 0
	    }

	    #
	    # Apply to it the current configuration options
	    #
	    foreach opt $configOpts {
		set optGrp [lindex $configSpecs($opt) 2]
		if {[string compare $optGrp "l"] == 0} {
		    set optTail [string range $opt 6 end]
		    if {[info exists data($col$opt)]} {
			configLabel $w -$optTail $data($col$opt)
		    } else {
			configLabel $w -$optTail $data($opt)
		    }
		} elseif {[string compare $optGrp "c"] == 0} {
		    configLabel $w $opt $data($opt)
		}
	    }
	    catch {configLabel $w -state $data(-state)}

	    #
	    # Replace the binding tag (T)Label with $data(labelTag) and
	    # TablelistLabel in the list of binding tags of the label
	    #
	    bindtags $w [lreplace [bindtags $w] 1 1 \
			 $data(labelTag) TablelistLabel]

	    #
	    # Create a canvas containing the sort arrows
	    #
	    set w $data(hdrTxtFrCanv)$col
	    canvas $w -borderwidth 0 -highlightthickness 0 \
		      -relief flat -takefocus 0
	    createArrows $w $arrowWidth $arrowHeight $arrowRelief

	    #
	    # Apply to it the current configuration options
	    #
	    foreach opt $configOpts {
		if {[string compare [lindex $configSpecs($opt) 2] "c"] == 0} {
		    $w configure $opt $data($opt)
		}
	    }

	    #
	    # Replace the binding tag Canvas with $data(labelTag) and
	    # TablelistArrow in the list of binding tags of the canvas
	    #
	    bindtags $w [lreplace [bindtags $w] 1 1 \
			 $data(labelTag) TablelistArrow]

	    if {[info exists data($col-labelimage)]} {
		doColConfig $col $win -labelimage $data($col-labelimage)
	    }
	}

	#
	# Configure the edit window if present
	#
	if {$col == $data(editCol) &&
	    [string compare [winfo class $data(bodyFrEd)] "Mentry"] != 0} {
	    catch {$data(bodyFrEd) configure -justify $alignment}
	}

	incr col
    }
    set data(hasFmtCmds) [expr {[lsearch -exact $data(fmtCmdFlagList) 1] >= 0}]

    #
    # Clean up the images, data, and attributes
    # associated with the deleted columns
    #
    set imgNames [image names]
    for {set col $data(colCount)} {$col < $oldColCount} {incr col} {
	set w $data(hdrTxtFrCanv)$col
	foreach shape {triangleUp darkLineUp lightLineUp
		       triangleDn darkLineDn lightLineDn} {
	    if {[lsearch -exact $imgNames $shape$w] >= 0} {
		image delete $shape$w
	    }
	}

	deleteColData $win $col
	deleteColAttribs $win $col
    }

    #
    # Update data(-treecolumn) and data(treeCol) if needed
    #
    if {$createLabels} {
	set treeCol $data(-treecolumn)
	adjustColIndex $win treeCol
	set data(treeCol) $treeCol
	if {$data(colCount) != 0} { 
	    set data(-treecolumn) $treeCol
	}
    }

    #
    # Create the separators if needed
    #
    if {$createLabels && $data(-showseparators)} {
	createSeps $win
    }
}

#------------------------------------------------------------------------------
# tablelist::createSeps
#
# Creates and manages the separators in the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::createSeps win {
    upvar ::tablelist::ns${win}::data data
    variable usingTile
    set sepX [getSepX]

    for {set col 0} {$col < $data(colCount)} {incr col} {
	#
	# Create the col'th separator and attach it to
	# the right edge of the col'th header label
	#
	set w $data(sep)$col
	if {$usingTile} {
	    ttk::separator $w -style Seps$win.TSeparator \
			      -cursor $data(-cursor) -orient vertical \
			      -takefocus 0
	} else {
	    tk::frame $w -background $data(-background) -borderwidth 1 \
			 -container 0 -cursor $data(-cursor) \
			 -highlightthickness 0 -relief sunken \
			 -takefocus 0 -width 2
	}
	place $w -in $data(hdrTxtFrLbl)$col -anchor ne -bordermode outside \
		 -relx 1.0 -x $sepX

	#
	# Replace the binding tag TSeparator or Frame with $data(bodyTag)
	# and TablelistBody in the list of binding tags of the separator
	#
	bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]
    }

    #
    # Create the horizontal separator
    #
    set w $data(hsep)
    if {$usingTile} {
	ttk::separator $w -style Seps$win.TSeparator -cursor $data(-cursor) \
			  -takefocus 0
    } else {
	tk::frame $w -background $data(-background) -borderwidth 1 \
		     -container 0 -cursor $data(-cursor) -height 2 \
		     -highlightthickness 0 -relief sunken -takefocus 0
    }

    #
    # Replace the binding tag TSeparator or Frame with $data(bodyTag) and
    # TablelistBody in the list of binding tags of the horizontal separator
    #
    bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]
    
    adjustSepsWhenIdle $win
}

#------------------------------------------------------------------------------
# tablelist::adjustSepsWhenIdle
#
# Arranges for the height and vertical position of each separator in the
# tablelist widget win to be adjusted at idle time.
#------------------------------------------------------------------------------
proc tablelist::adjustSepsWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(sepsId)]} {
	return ""
    }

    set data(sepsId) [after idle [list tablelist::adjustSeps $win]]
}

#------------------------------------------------------------------------------
# tablelist::adjustSeps
#
# Adjusts the height and vertical position of each separator in the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::adjustSeps win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(sepsId)]} {
	after cancel $data(sepsId)
	unset data(sepsId)
    }

    variable winSys
    set onWindows [expr {[string compare $winSys "win32"] == 0}]
    variable usingTile
    set sepX [getSepX]

    #
    # Get the height to be applied to the column separators
    # and place or unmanage the horizontal separator
    #
    set w $data(body)
    if {$data(-fullseparators)} {
	set sepHeight [winfo height $w]

	if {[winfo exists $data(hsep)]} {
	    place forget $data(hsep)
	}
    } else {
	set btmTextIdx [$w index @0,$data(btmY)]
	set btmLine [expr {int($btmTextIdx)}]
	if {$btmLine > $data(itemCount)} {		;# text widget bug
	    set btmLine $data(itemCount)
	    set btmTextIdx [expr {double($btmLine)}]
	}
	set dlineinfo [$w dlineinfo $btmTextIdx]
	if {$data(itemCount) == 0 || [llength $dlineinfo] == 0} {
	    set sepHeight 0
	} else {
	    foreach {x y width height baselinePos} $dlineinfo {}
	    set sepHeight [expr {$y + $height}]
	}

	if {$data(-showhorizseparator) && $data(-showseparators) &&
	    $sepHeight > 0 && $sepHeight < [winfo height $w]} {
	    set width [expr {[winfo reqwidth $data(hdrTxtFr)] + $sepX -
			     [winfo reqheight $data(hsep)] + 1}]
	    if {$onWindows && !$usingTile} {
		incr width
	    }
	    place $data(hsep) -in $w -y $sepHeight -width $width
	} elseif {[winfo exists $data(hsep)]} {
	    place forget $data(hsep)
	}
    }

    #
    # Set the height of the main separator (if any) and attach the
    # latter to the right edge of the last non-hidden title column
    #
    set startCol [expr {$data(-titlecolumns) - 1}]
    if {$startCol > $data(lastCol)} {
	set startCol $data(lastCol)
    }
    for {set col $startCol} {$col >= 0} {incr col -1} {
	if {!$data($col-hide)} {
	    break
	}
    }
    set mainSepHeight [expr {$sepHeight + [winfo height $data(hdr)] - 1}]
    set w $data(sep)
    if {$col < 0 || $mainSepHeight == 0} {
	if {[winfo exists $w]} {
	    place forget $w
	}
    } else {
	if {!$data(-showlabels)} {
	    incr mainSepHeight
	}
	place $w -in $data(hdrTxtFrLbl)$col -anchor ne -bordermode outside \
		 -height $mainSepHeight -relx 1.0 -x $sepX -y 1
	raise $w
    }

    #
    # Set the height and vertical position of the other column separators
    #
    if {$sepHeight == 0} {
	set relY 0.0
	set y -10
    } elseif {$data(-showlabels)} {
	set relY 1.0
	if {$usingTile || $onWindows} {
	    set y 0
	    incr sepHeight 1
	} else {
	    set y -1
	    incr sepHeight 2
	}
    } else {
	set relY 0.0
	if {$usingTile || $onWindows} {
	    set y 1
	    incr sepHeight 2
	} else {
	    set y 0
	    incr sepHeight 3
	}
    }
    foreach w [winfo children $win] {
	if {[regexp {^sep[0-9]+$} [winfo name $w]]} {
	    place configure $w -height $sepHeight -rely $relY -y $y
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::getSepX
#
# Returns the value of the -x option to be used when placing a separator
# relative to the corresponding header label, with -anchor ne.
#------------------------------------------------------------------------------
proc tablelist::getSepX {} {
    set x 1
    variable usingTile
    if {$usingTile} {
	set currentTheme [getCurrentTheme]
	variable xpStyle
	if {([string compare $currentTheme "aqua"] == 0) ||
	    ([string compare $currentTheme "xpnative"] == 0 && $xpStyle)} {
	    set x 0
	} elseif {[string compare $currentTheme "tileqt"] == 0} {
	    switch -- [string tolower [tileqt_currentThemeName]] {
		cleanlooks -
		gtk+ -
		oxygen	{ set x 0 }
		qtcurve	{ set x 2 }
	    }
	}
    }

    return $x
}

#------------------------------------------------------------------------------
# tablelist::adjustColumns
#
# Applies some configuration options to the labels of the tablelist widget win,
# places them in the header frame, computes and sets the tab stops for the body
# text widget, and adjusts the width and height of the header frame.  The
# whichWidths argument specifies the dynamic-width columns or labels whose
# widths are to be computed when performing these operations.  The stretchCols
# argument specifies whether to stretch the stretchable columns.
#------------------------------------------------------------------------------
proc tablelist::adjustColumns {win whichWidths stretchCols} {
    set compAllColWidths [expr {[string compare $whichWidths "allCols"] == 0}]
    set compAllLabelWidths \
	[expr {[string compare $whichWidths "allLabels"] == 0}]

    variable usingTile
    set usingAquaTheme \
	[expr {$usingTile && [string compare [getCurrentTheme] "aqua"] == 0}]

    #
    # Configure the labels and compute the positions of
    # the tab stops to be set in the body text widget
    #
    upvar ::tablelist::ns${win}::data data
    set data(hdrPixels) 0
    variable canElide
    variable centerArrows
    set tabs {}
    set col 0
    set x 0
    foreach {pixels alignment} $data(colList) {
	set w $data(hdrTxtFrLbl)$col
	if {$data($col-hide) && !$canElide} {
	    place forget $w
	    incr col
	    continue
	}

	#
	# Adjust the col'th label
	#
	if {[info exists data($col-labelalign)]} {
	    set labelAlignment $data($col-labelalign)
	} else {
	    set labelAlignment $alignment
	}
	if {$pixels != 0} {			;# convention: static width
	    incr pixels $data($col-delta)
	}
	adjustLabel $win $col $pixels $labelAlignment

	if {$pixels == 0} {			;# convention: dynamic width
	    #
	    # Compute the column or label width if requested
	    #
	    if {$compAllColWidths || [lsearch -exact $whichWidths $col] >= 0} {
		computeColWidth $win $col
	    } elseif {$compAllLabelWidths ||
		      [lsearch -exact $whichWidths l$col] >= 0} {
		computeLabelWidth $win $col
	    }

	    set pixels $data($col-reqPixels)
	    if {$data($col-maxPixels) > 0 && $pixels > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
		incr pixels $data($col-delta)
		adjustLabel $win $col $pixels $labelAlignment
	    } else {
		incr pixels $data($col-delta)
	    }
	}

	if {$col == $data(editCol) &&
	    ![string match "*Checkbutton" [winfo class $data(bodyFrEd)]]} {
	    adjustEditWindow $win $pixels
	}

	set canvas $data(hdrTxtFrCanv)$col
	if {[lsearch -exact $data(arrowColList) $col] >= 0 &&
	    !$data($col-elide) && !$data($col-hide)} {
	    #
	    # Center the canvas horizontally just below the upper edge of
	    # the label, or place it to the left side of the label if the
	    # latter is right-justified and to its right side otherwise
	    #
	    if {$centerArrows} {
		place $canvas -in $w -anchor n -bordermode outside \
			      -relx 0.5 -y 1
	    } else {
		set y 0
		if {([winfo reqheight $w] - [winfo reqheight $canvas]) % 2 == 0
		    && $data(arrowHeight) == 5} {
		    set y -1
		}
		if {[string compare $labelAlignment "right"] == 0} {
		    place $canvas -in $w -anchor w -bordermode outside \
				  -relx 0.0 -x $data(charWidth) \
				  -rely 0.49 -y $y
		} else {
		    place $canvas -in $w -anchor e -bordermode outside \
				  -relx 1.0 -x -$data(charWidth) \
				  -rely 0.49 -y $y
		}
	    }
	    raise $canvas
	} else {
	    place forget $canvas
	}

	#
	# Place the label in the header frame
	#
	if {$data($col-elide) || $data($col-hide)} {
	    foreach l [getSublabels $w] {
		place forget $l
	    }
	    place $w -x [expr {$x - 1}] -relheight 1.0 -width 1
	    lower $w
	} else {
	    set x2 $x
	    set labelPixels [expr {$pixels + 2*$data(charWidth)}]
	    if {$usingAquaTheme} {
		incr x2 -1
		incr labelPixels
		if {$col == 0} {
		    incr x2 -1
		    incr labelPixels
		}
	    }
	    place $w -x $x2 -relheight 1.0 -width $labelPixels
	}

	#
	# Append a tab stop and the alignment to the tabs list
	#
	if {!$data($col-elide) && !$data($col-hide)} {
	    incr x $data(charWidth)
	    switch $alignment {
		left {
		    lappend tabs $x left
		    incr x $pixels
		}
		right {
		    incr x $pixels
		    lappend tabs $x right
		}
		center {
		    lappend tabs [expr {$x + $pixels/2}] center
		    incr x $pixels
		}
	    }
	    incr x $data(charWidth)
	    lappend tabs $x left
	}

	incr col
    }
    place configure $data(hdrFr) -x $x

    #
    # Apply the value of tabs to the body text widget
    #
    if {[info exists data(colBeingResized)]} {
	$data(body) tag configure visibleLines -tabs $tabs
    } else {
	$data(body) configure -tabs $tabs
    }

    #
    # Adjust the width and height of the frames data(hdrTxtFr) and data(hdr)
    #
    $data(hdrTxtFr) configure -width $x
    if {$data(-width) <= 0} {
	if {$stretchCols} {
	    $data(hdr) configure -width $x
	    $data(lb) configure -width [expr {$x / $data(charWidth)}]
	}
    } else {
	$data(hdr) configure -width 0
    }
    set data(hdrPixels) $x
    adjustHeaderHeight $win

    #
    # Stretch the stretchable columns if requested, and update
    # the scrolled column offset and the horizontal scrollbar
    #
    if {$stretchCols} {
	stretchColumnsWhenIdle $win
    }
    if {![info exists data(colBeingResized)]} {
	updateScrlColOffsetWhenIdle $win
    }
    updateHScrlbarWhenIdle $win
}

#------------------------------------------------------------------------------
# tablelist::adjustLabel
#
# Applies some configuration options to the col'th label of the tablelist
# widget win as well as to the label's sublabels (if any), and places the
# sublabels.
#------------------------------------------------------------------------------
proc tablelist::adjustLabel {win col pixels alignment} {
    variable usingTile
    set usingAquaTheme \
	[expr {$usingTile && [string compare [getCurrentTheme] "aqua"] == 0}]

    #
    # Apply some configuration options to the label and its sublabels (if any)
    #
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrLbl)$col
    variable anchors
    set anchor $anchors($alignment)
    set borderWidth [winfo pixels $w [$w cget -borderwidth]]
    if {$borderWidth < 0} {
	set borderWidth 0
    }
    set padX [expr {$data(charWidth) - $borderWidth}]
    if {$padX < 0} {
	set padX 0
    }
    set padL $padX
    set padR $padX
    set marginL $data(charWidth)
    set marginR $data(charWidth)
    if {$usingAquaTheme} {
	incr padL
	incr marginL
	if {$col == 0} {
	    incr padL
	    incr marginL
	}
	set padding [$w cget -padding]
	lset padding 0 $padL
	lset padding 2 $padR
	$w configure -anchor $anchor -justify $alignment -padding $padding
    } else {
	configLabel $w -anchor $anchor -justify $alignment -padx $padX
    }
    if {[info exists data($col-labelimage)]} {
	set imageWidth [image width $data($col-labelimage)]
	$w-tl configure -anchor $anchor -justify $alignment
    } else {
	set imageWidth 0
    }

    #
    # Make room for the canvas displaying an up- or down-arrow if needed
    #
    set title [lindex $data(-columns) [expr {3*$col + 1}]]
    set labelFont [$w cget -font]
    set spaces ""
    set spacePixels 0
    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
	set canvas $data(hdrTxtFrCanv)$col
	set canvasWidth $data(arrowWidth)
	if {[llength $data(arrowColList)] > 1} {
	    incr canvasWidth 6
	    $canvas itemconfigure sortRank \
		    -image sortRank$data($col-sortRank)$win
	}
	$canvas configure -width $canvasWidth

	variable centerArrows
	if {!$centerArrows} {
	    set spaceWidth [font measure $labelFont -displayof $w " "]
	    set spaces "  "
	    set n 2
	    while {$n*$spaceWidth < $canvasWidth + $data(charWidth)} {
		append spaces " "
		incr n
	    }
	    set spacePixels [expr {$n * $spaceWidth}]
	}
    }

    set data($col-isSnipped) 0
    if {$pixels == 0} {				;# convention: dynamic width
	#
	# Set the label text
	#
	if {$imageWidth == 0} {				;# no image
	    if {[string length $title] == 0} {
		set text $spaces
	    } else {
		set lines {}
		foreach line [split $title "\n"] {
		    if {[string compare $alignment "right"] == 0} {
			lappend lines $spaces$line
		    } else {
			lappend lines $line$spaces
		    }
		}
		set text [join $lines "\n"]
	    }
	    $w configure -text $text
	} elseif {[string length $title] == 0} {	;# image w/o text
	    $w configure -text ""
	    set text $spaces
	    $w-tl configure -text $text
	    $w-il configure -width $imageWidth
	} else {					;# both image and text
	    $w configure -text ""
	    set lines {}
	    foreach line [split $title "\n"] {
		if {[string compare $alignment "right"] == 0} {
		    lappend lines "$spaces$line "
		} else {
		    lappend lines " $line$spaces"
		}
	    }
	    set text [join $lines "\n"]
	    $w-tl configure -text $text
	    $w-il configure -width $imageWidth
	}
    } else {
	#
	# Clip each line of title according to pixels and alignment
	#
	set lessPixels [expr {$pixels - $spacePixels}]
	variable snipSides
	set snipSide $snipSides($alignment,$data($col-changetitlesnipside))
	if {$imageWidth == 0} {				;# no image
	    if {[string length $title] == 0} {
		set text $spaces
	    } else {
		set lines {}
		foreach line [split $title "\n"] {
		    set lineSav $line
		    set line [strRange $win $line $labelFont \
			      $lessPixels $snipSide $data(-snipstring)]
		    if {[string compare $line $lineSav] != 0} {
			set data($col-isSnipped) 1
		    }
		    if {[string compare $alignment "right"] == 0} {
			lappend lines $spaces$line
		    } else {
			lappend lines $line$spaces
		    }
		}
		set text [join $lines "\n"]
	    }
	    $w configure -text $text
	} elseif {[string length $title] == 0} {	;# image w/o text
	    $w configure -text ""
	    if {$imageWidth + $spacePixels <= $pixels} {
		set text $spaces
		$w-tl configure -text $text
		$w-il configure -width $imageWidth
	    } elseif {$spacePixels < $pixels} {
		set text $spaces
		$w-tl configure -text $text
		$w-il configure -width [expr {$pixels - $spacePixels}]
	    } else {
		set imageWidth 0			;# can't disp. the image
		set text ""
	    }
	} else {					;# both image and text
	    $w configure -text ""
	    set gap [font measure $labelFont -displayof $win " "]
	    if {$imageWidth + $gap + $spacePixels <= $pixels} {
		incr lessPixels -[expr {$imageWidth + $gap}]
		set lines {}
		foreach line [split $title "\n"] {
		    set lineSav $line
		    set line [strRange $win $line $labelFont \
			      $lessPixels $snipSide $data(-snipstring)]
		    if {[string compare $line $lineSav] != 0} {
			set data($col-isSnipped) 1
		    }
		    if {[string compare $alignment "right"] == 0} {
			lappend lines "$spaces$line "
		    } else {
			lappend lines " $line$spaces"
		    }
		}
		set text [join $lines "\n"]
		$w-tl configure -text $text
		$w-il configure -width $imageWidth
	    } elseif {$imageWidth + $spacePixels <= $pixels} {	
		set data($col-isSnipped) 1
		set text $spaces		;# can't display the orig. text
		$w-tl configure -text $text
		$w-il configure -width $imageWidth
	    } elseif {$spacePixels < $pixels} {
		set data($col-isSnipped) 1
		set text $spaces		;# can't display the orig. text
		$w-tl configure -text $text
		$w-il configure -width [expr {$pixels - $spacePixels}]
	    } else {
		set data($col-isSnipped) 1
		set imageWidth 0		;# can't display the image
		set text ""			;# can't display the text
	    }
	}
    }

    #
    # Place the label's sublabels (if any)
    #
    if {$imageWidth == 0} {
	if {[info exists data($col-labelimage)]} {
	    place forget $w-il
	    place forget $w-tl
	}
    } else {
	if {[string length $text] == 0} {
	    place forget $w-tl
	}

	variable usingTile
	switch $alignment {
	    left {
		place $w-il -in $w -anchor w -bordermode outside \
			    -relx 0.0 -x $marginL -rely 0.49
		raise $w-il
		if {$usingTile} {
		    set padding [$w cget -padding]
		    lset padding 0 [incr padL [winfo reqwidth $w-il]]
		    $w configure -padding $padding -text $text
		} elseif {[string length $text] != 0} {
		    set textX [expr {$marginL + [winfo reqwidth $w-il]}]
		    place $w-tl -in $w -anchor w -bordermode outside \
				-relx 0.0 -x $textX -rely 0.49
		}
	    }

	    right {
		place $w-il -in $w -anchor e -bordermode outside \
			    -relx 1.0 -x -$marginR -rely 0.49
		raise $w-il
		if {$usingTile} {
		    set padding [$w cget -padding]
		    lset padding 2 [incr padR [winfo reqwidth $w-il]]
		    $w configure -padding $padding -text $text
		} elseif {[string length $text] != 0} {
		    set textX [expr {-$marginR - [winfo reqwidth $w-il]}]
		    place $w-tl -in $w -anchor e -bordermode outside \
				-relx 1.0 -x $textX -rely 0.49
		}
	    }

	    center {
		if {$usingTile} {
		    set padding [$w cget -padding]
		    lset padding 0 [incr padL [winfo reqwidth $w-il]]
		    $w configure -padding $padding -text $text
		}

		if {[string length $text] == 0} {
		    place $w-il -in $w -anchor center -relx 0.5 -x 0 -rely 0.49
		} else {
		    set reqWidth [expr {[winfo reqwidth $w-il] +
					[winfo reqwidth $w-tl]}]
		    set iX [expr {-$reqWidth/2}]
		    place $w-il -in $w -anchor w -relx 0.5 -x $iX -rely 0.49
		    if {!$usingTile} {
			set tX [expr {$reqWidth + $iX}]
			place $w-tl -in $w -anchor e -relx 0.5 -x $tX -rely 0.49
		    }
		}
		raise $w-il
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::computeColWidth
#
# Computes the width of the col'th column of the tablelist widget win to be just
# large enough to hold all the elements of the column (including its label).
#------------------------------------------------------------------------------
proc tablelist::computeColWidth {win col} {
    upvar ::tablelist::ns${win}::data data
    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
    set data($col-elemWidth) 0
    set data($col-widestCount) 0

    #
    # Column elements
    #
    set row -1
    foreach item $data(itemList) {
	incr row

	if {$col >= [llength $item] - 1} {
	    continue
	}

	set key [lindex $item end]
	if {[info exists data($key-elide)] || [info exists data($key-hide)]} {
	    continue
	}

	set text [lindex $item $col]
	if {$fmtCmdFlag} {
	    set text [formatElem $win $key $row $col $text]
	}
	if {[string match "*\t*" $text]} {
	    set text [mapTabs $text]
	}
	getAuxData $win $key $col auxType auxWidth
	getIndentData $win $key $col indentWidth
	set cellFont [getCellFont $win $key $col]
	set elemWidth [getElemWidth $win $text $auxWidth $indentWidth $cellFont]
	if {$elemWidth == $data($col-elemWidth)} {
	    incr data($col-widestCount)
	} elseif {$elemWidth > $data($col-elemWidth)} {
	    set data($col-elemWidth) $elemWidth
	    set data($col-widestCount) 1
	}
    }
    set data($col-reqPixels) $data($col-elemWidth)

    #
    # Column label
    #
    computeLabelWidth $win $col
}

#------------------------------------------------------------------------------
# tablelist::computeLabelWidth
#
# Computes the width of the col'th label of the tablelist widget win and
# adjusts the column's width accordingly.
#------------------------------------------------------------------------------
proc tablelist::computeLabelWidth {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrLbl)$col
    if {[info exists data($col-labelimage)]} {
	variable usingTile
	if {$usingTile} {
	    set netLabelWidth [expr {[winfo reqwidth $w] - 2*$data(charWidth)}]
	} else {
	    set netLabelWidth \
		[expr {[winfo reqwidth $w-il] + [winfo reqwidth $w-tl]}]
	}
    } else {
	set netLabelWidth [expr {[winfo reqwidth $w] - 2*$data(charWidth)}]
    }

    if {$netLabelWidth < $data($col-elemWidth)} {
	set data($col-reqPixels) $data($col-elemWidth)
    } else {
	set data($col-reqPixels) $netLabelWidth
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustHeaderHeight
#
# Sets the height of the header frame of the tablelist widget win to the max.
# height of its children.
#------------------------------------------------------------------------------
proc tablelist::adjustHeaderHeight win {
    #
    # Compute the max. label height
    #
    upvar ::tablelist::ns${win}::data data
    set maxLabelHeight [winfo reqheight $data(hdrFrLbl)]
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set w $data(hdrTxtFrLbl)$col
	if {[string length [winfo manager $w]] == 0} {
	    continue
	}

	set reqHeight [winfo reqheight $w]
	if {$reqHeight > $maxLabelHeight} {
	    set maxLabelHeight $reqHeight
	}

	foreach l [getSublabels $w] {
	    if {[string length [winfo manager $l]] == 0} {
		continue
	    }

	    set borderWidth [winfo pixels $w [$w cget -borderwidth]]
	    if {$borderWidth < 0} {
		set borderWidth 0
	    }
	    set reqHeight [expr {[winfo reqheight $l] + 2*$borderWidth}]
	    if {$reqHeight > $maxLabelHeight} {
		set maxLabelHeight $reqHeight
	    }
	}
    }

    #
    # Set the height of the header frame and adjust the separators
    #
    $data(hdrTxtFr) configure -height $maxLabelHeight
    if {$data(-showlabels)} {
	$data(hdr) configure -height $maxLabelHeight
	place configure $data(hdrTxt) -y 0
	place configure $data(hdrFr) -y 0

	$data(corner) configure -height $maxLabelHeight
	place configure $data(cornerLbl) -y 0
    } else {
	$data(hdr) configure -height 1
	place configure $data(hdrTxt) -y -1
	place configure $data(hdrFr) -y -1

	$data(corner) configure -height 1
	place configure $data(cornerLbl) -y -1
    }
    adjustSepsWhenIdle $win
}

#------------------------------------------------------------------------------
# tablelist::stretchColumnsWhenIdle
#
# Arranges for the stretchable columns of the tablelist widget win to be
# stretched at idle time.
#------------------------------------------------------------------------------
proc tablelist::stretchColumnsWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stretchId)]} {
	return ""
    }

    set data(stretchId) [after idle [list tablelist::stretchColumns $win -1]]
}

#------------------------------------------------------------------------------
# tablelist::stretchColumns
#
# Stretches the stretchable columns to fill the tablelist window win
# horizontally.  The colOfFixedDelta argument specifies the column for which
# the stretching is to be made using a precomputed amount of pixels.
#------------------------------------------------------------------------------
proc tablelist::stretchColumns {win colOfFixedDelta} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stretchId)]} {
	after cancel $data(stretchId)
	unset data(stretchId)
    }

    set forceAdjust $data(forceAdjust)
    set data(forceAdjust) 0

    if {$data(hdrPixels) == 0 || $data(-width) <= 0} {
	return ""
    }

    #
    # Get the list data(stretchableCols) of the
    # numerical indices of the stretchable columns
    #
    set data(stretchableCols) {}
    if {[string compare $data(-stretch) "all"] == 0} {
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    lappend data(stretchableCols) $col
	}
    } else {
	foreach col $data(-stretch) {
	    lappend data(stretchableCols) [colIndex $win $col 0]
	}
    }

    #
    # Compute the total number data(delta) of pixels by which the
    # columns are to be stretched and the total amount
    # data(stretchablePixels) of stretchable column widths in pixels
    #
    set data(delta) [winfo width $data(hdr)]
    set data(stretchablePixels) 0
    set lastColToStretch -1
    set col 0
    foreach {pixels alignment} $data(colList) {
	if {$data($col-hide)} {
	    incr col
	    continue
	}

	if {$pixels == 0} {			;# convention: dynamic width
	    set pixels $data($col-reqPixels)
	    if {$data($col-maxPixels) > 0} {
		if {$pixels > $data($col-maxPixels)} {
		    set pixels $data($col-maxPixels)
		}
	    }
	}
	incr data(delta) -[expr {$pixels + 2*$data(charWidth)}]
	if {[lsearch -exact $data(stretchableCols) $col] >= 0} {
	    incr data(stretchablePixels) $pixels
	    set lastColToStretch $col
	}

	incr col
    }
    if {$data(delta) < 0} {
	set delta 0
    } else {
	set delta $data(delta)
    }
    if {$data(stretchablePixels) == 0 && !$forceAdjust} {
	return ""
    }

    #
    # Distribute the value of delta to the stretchable
    # columns, proportionally to their widths in pixels
    #
    set rest $delta
    set col 0
    foreach {pixels alignment} $data(colList) {
	if {$data($col-hide) ||
	    [lsearch -exact $data(stretchableCols) $col] < 0} {
	    set data($col-delta) 0
	} else {
	    set oldDelta $data($col-delta)
	    if {$pixels == 0} {			;# convention: dynamic width
		set dynamic 1
		set pixels $data($col-reqPixels)
		if {$data($col-maxPixels) > 0} {
		    if {$pixels > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
			set dynamic 0
		    }
		}
	    } else {
		set dynamic 0
	    }
	    if {$data(stretchablePixels) == 0} {
		set data($col-delta) 0
	    } else {
		if {$col != $colOfFixedDelta} {
		    set data($col-delta) \
			[expr {$delta*$pixels/$data(stretchablePixels)}]
		}
		incr rest -$data($col-delta)
	    }
	    if {$col == $lastColToStretch} {
		incr data($col-delta) $rest
	    }
	    if {!$dynamic && $data($col-delta) != $oldDelta} {
		redisplayColWhenIdle $win $col
	    }
	}

	incr col
    }

    #
    # Adjust the columns and schedule a view update for execution at idle time
    #
    adjustColumns $win {} 0
    updateViewWhenIdle $win 1
}

#------------------------------------------------------------------------------
# tablelist::moveActiveTag
#
# Moves the "active" tag to the line or cell that displays the active item or
# element of the tablelist widget win in its body text child.
#------------------------------------------------------------------------------
proc tablelist::moveActiveTag win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    $w tag remove curRow 1.0 end
    $w tag remove active 1.0 end

    if {$data(itemCount) == 0 || $data(colCount) == 0} {
	return ""
    }

    set activeLine [expr {$data(activeRow) + 1}]
    set activeCol $data(activeCol)
    if {[string compare $data(-selecttype) "row"] == 0} {
	$w tag add active $activeLine.0 $activeLine.end
	updateColors $win $activeLine.0 $activeLine.end
    } elseif {$activeLine > 0 && $activeCol < $data(colCount) &&
	      !$data($activeCol-hide)} {
	$w tag add curRow $activeLine.0 $activeLine.end
	findTabs $win $activeLine $activeCol $activeCol tabIdx1 tabIdx2
	$w tag add active $tabIdx1 $tabIdx2+1c
	updateColors $win $activeLine.0 $activeLine.end
    }
}

#------------------------------------------------------------------------------
# tablelist::updateColorsWhenIdle
#
# Arranges for the background and foreground colors of the label, frame, and
# message widgets containing the currently visible images, embedded windows,
# and multiline elements of the tablelist widget win to be updated at idle
# time.
#------------------------------------------------------------------------------
proc tablelist::updateColorsWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(colorsId)]} {
	return ""
    }

    set data(colorsId) [after idle [list tablelist::updateColors $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateColors
#
# Updates the background and foreground colors of the label, frame, and message
# widgets containing the currently visible images, embedded windows, and
# multiline elements of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::updateColors {win {fromTextIdx ""} {toTextIdx ""}} {
    upvar ::tablelist::ns${win}::data data
    if {$data(itemCount) == 0 || $data(colCount) == 0 ||
	[info exists data(dispId)]} {
	return ""
    }

    set w $data(body)
    if {[string length $fromTextIdx] == 0} {
	set fromTextIdx "[$w index @0,0] linestart"
	set toTextIdx "[$w index @0,$data(btmY)] lineend"
	set updateAll 1

	if {[info exists data(colorsId)]} {
	    after cancel $data(colorsId)
	    unset data(colorsId)
	}
    } else {
	set updateAll 0
    }

    if {$updateAll} {
	if {$data(isDisabled)} {
	    $w tag add disabled $fromTextIdx $toTextIdx
	}

	if {[string length $data(-colorizecommand)] == 0} {
	    set hasColorizeCmd 0
	} else {
	    set hasColorizeCmd 1
	    set colorizeCmd $data(-colorizecommand)
	}

	variable canElide
	variable elide
	set topLine [expr {int([$w index @0,0])}]
	set btmLine [expr {int([$w index @0,$data(btmY)])}]
	if {$btmLine > $data(itemCount)} {		;# text widget bug
	    set btmLine $data(itemCount)
	}
	for {set line $topLine; set row [expr {$line - 1}]} \
	    {$line <= $btmLine} {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {[info exists data($key-elide)] ||
		[info exists data($key-hide)]} {
		continue
	    }

	    #
	    # Handle the -stripebackground and -stripeforeground
	    # column configuration options, as well as the
	    # -(select)background and -(select)foreground column,
	    # row, and cell configuration options in this row
	    #
	    set textIdx1 $line.0
	    set lineTagNames [$w tag names $textIdx1]
	    set inStripe [expr {[lsearch -exact $lineTagNames stripe] >= 0}]
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		if {$data($col-hide) && !$canElide} {
		    continue
		}

		set tabIdx2 [$w search $elide "\t" $textIdx1+1c $line.end]
		if {[string length $tabIdx2] == 0} {
		    break
		}
		set textIdx2 $tabIdx2+1c

		set cellTagNames [$w tag names $tabIdx2]
		foreach tag $cellTagNames {
		    if {[string match "*-*ground-*" $tag]} {
			$w tag remove $tag $textIdx1 $textIdx2
		    }
		}

		if {$inStripe} {
		    foreach opt {-stripebackground -stripeforeground} {
			set name $col$opt
			if {[info exists data($name)]} {
			    $w tag add col$opt-$data($name) $textIdx1 $textIdx2
			}
		    }
		}

		set selected [expr {[lsearch -exact $cellTagNames select] >= 0}]
		foreach optTail {background foreground} {
		    set normalOpt -$optTail
		    set selectOpt -select$optTail
		    foreach level      [list col row cell] \
			    normalName [list $col$normalOpt $key$normalOpt \
					$key,$col$normalOpt] \
			    selectName [list $col$selectOpt $key$selectOpt \
					$key,$col$selectOpt] {
			if {$selected} {
			    if {[info exists data($selectName)]} {
				$w tag add $level$selectOpt-$data($selectName) \
				       $textIdx1 $textIdx2
			    }
			} else {
			    if {[info exists data($normalName)]} {
				$w tag add $level$normalOpt-$data($normalName) \
				       $textIdx1 $textIdx2
			    }
			}
		    }
		}

		if {$hasColorizeCmd} {
		    set tabIdx1 [$w index $textIdx1]
		    uplevel #0 $colorizeCmd [list $win $w $key $row $col \
			$tabIdx1 $tabIdx2 $inStripe $selected]
		}

		set textIdx1 $textIdx2
	    }
	}
    }

    set hasExpCollCtrlSelImgs [expr {$::tk_version >= 8.3 &&
	[info exists tablelist::$data(-treestyle)_collapsedSelImg]}]

    foreach {dummy path textIdx} [$w dump -window $fromTextIdx $toTextIdx] {
	if {[string length $path] == 0} {
	    continue
	}

	set class [winfo class $path]
	set isLabel [expr {[string compare $class "Label"] == 0}]
	set isTblWin [expr {[string compare $class "TablelistWindow"] == 0}]
	set isMessage [expr {[string compare $class "Message"] == 0}]
	if {!$isLabel && !$isTblWin && !$isMessage} {
	    continue
	}

	set name [winfo name $path]
	foreach {key col} [split [string range $name 4 end] ","] {}
	if {[info exists data($key-elide)] || [info exists data($key-hide)]} {
	    continue
	}

	set tagNames [$w tag names $textIdx]
	set selected [expr {[lsearch -exact $tagNames select] >= 0}]

	#
	# If the widget is an indentation label then conditionally remove the
	# "active" and "select" tags from its text position and the preceding
	# one, or change its image to become the "normal" or "selected" one
	#
	if {[string compare $path $w.ind_$key,$col] == 0} {
	    if {$data(protectIndents)} {
		set fromTextIdx [$w index $textIdx-1c]
		set toTextIdx   [$w index $textIdx+1c]

		$w tag remove curRow $fromTextIdx $toTextIdx
		$w tag remove active $fromTextIdx $toTextIdx

		if {$updateAll && $selected} {
		    $w tag remove select $fromTextIdx $toTextIdx
		    foreach tag [$w tag names $fromTextIdx] {
			if {[string match "*-selectbackground-*" $tag] ||
			    [string match "*-selectforeground-*" $tag]} {
			    $w tag remove $tag $fromTextIdx $toTextIdx
			}
		    }
		    set selected 0
		    foreach optTail {background foreground} {
			set opt -$optTail
			foreach level [list col row cell] \
				name  [list $col$opt $key$opt $key,$col$opt] {
			    if {[info exists data($name)]} {
				$w tag add $level$opt-$data($name) \
				       $fromTextIdx $toTextIdx
			    }
			}
		    }
		}
	    } elseif {$hasExpCollCtrlSelImgs} {
		set curImgName [$path cget -image]
		if {$selected} {
		    set newImgName [strMap {
			"SelActImg" "SelActImg" "ActImg" "SelActImg"
			"SelImg" "SelImg" "collapsedImg" "collapsedSelImg"
			"expandedImg" "expandedSelImg"
		    } $curImgName]
		} else {
		    set newImgName [strMap {"Sel" ""} $curImgName]
		}

		if {[string compare $curImgName $newImgName] != 0} {
		    set data($key,$col-indent) $newImgName
		    $path configure -image $data($key,$col-indent)
		}
	    }
	}

	if {!$updateAll} {
	    continue
	}

	#
	# Set the widget's background and foreground
	# colors to those of the containing cell
	#
	if {$data(isDisabled)} {
	    set bg $data(-background)
	    set fg $data(-disabledforeground)
	} elseif {$selected} {
	    if {[info exists data($key,$col-selectbackground)]} {
		set bg $data($key,$col-selectbackground)
	    } elseif {[info exists data($key-selectbackground)]} {
		set bg $data($key-selectbackground)
	    } elseif {[info exists data($col-selectbackground)]} {
		set bg $data($col-selectbackground)
	    } else {
		set bg $data(-selectbackground)
	    }

	    if {$isMessage || $isTblWin} {
		if {[info exists data($key,$col-selectforeground)]} {
		    set fg $data($key,$col-selectforeground)
		} elseif {[info exists data($key-selectforeground)]} {
		    set fg $data($key-selectforeground)
		} elseif {[info exists data($col-selectforeground)]} {
		    set fg $data($col-selectforeground)
		} else {
		    set fg $data(-selectforeground)
		}
	    }
	} else {
	    if {[info exists data($key,$col-background)]} {
		set bg $data($key,$col-background)
	    } elseif {[info exists data($key-background)]} {
		set bg $data($key-background)
	    } elseif {[lsearch -exact $tagNames stripe] >= 0} {
		if {[info exists data($col-stripebackground)]} {
		    set bg $data($col-stripebackground)
		} elseif {[string length $data(-stripebackground)] != 0} {
		    set bg $data(-stripebackground)
		} else {
		    set bg $data(-background)
		}
	    } else {
		if {[info exists data($col-background)]} {
		    set bg $data($col-background)
		} else {
		    set bg $data(-background)
		}
	    }

	    if {$isMessage || $isTblWin} {
		if {[info exists data($key,$col-foreground)]} {
		    set fg $data($key,$col-foreground)
		} elseif {[info exists data($key-foreground)]} {
		    set fg $data($key-foreground)
		} elseif {[lsearch -exact $tagNames stripe] >= 0} {
		    if {[info exists data($col-stripeforeground)]} {
			set fg $data($col-stripeforeground)
		    } elseif {[string length $data(-stripeforeground)] != 0} {
			set fg $data(-stripeforeground)
		    } else {
			set fg $data(-foreground)
		    }
		} else {
		    if {[info exists data($col-foreground)]} {
			set fg $data($col-foreground)
		    } else {
			set fg $data(-foreground)
		    }
		}
	    }
	}
	if {[string compare [$path cget -background] $bg] != 0} {
	    $path configure -background $bg
	}
	if {$isMessage && [string compare [$path cget -foreground] $fg] != 0} {
	    $path configure -foreground $fg
	}
	if {$isTblWin && [info exists data($key,$col-windowupdate)]} {
	    uplevel #0 $data($key,$col-windowupdate) [list \
		$win [keyToRow $win $key] $col $path.w \
		-background $bg -foreground $fg]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateScrlColOffsetWhenIdle
#
# Arranges for the scrolled column offset of the tablelist widget win to be
# updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateScrlColOffsetWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(offsetId)]} {
	return ""
    }

    set data(offsetId) [after idle [list tablelist::updateScrlColOffset $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateScrlColOffset
#
# Updates the scrolled column offset of the tablelist widget win to fit into
# the allowed range.
#------------------------------------------------------------------------------
proc tablelist::updateScrlColOffset win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(offsetId)]} {
	after cancel $data(offsetId)
	unset data(offsetId)
    }

    set maxScrlColOffset [getMaxScrlColOffset $win]
    if {$data(scrlColOffset) > $maxScrlColOffset} {
	set data(scrlColOffset) $maxScrlColOffset
	adjustElidedText $win
	redisplayVisibleItems $win
    }
}

#------------------------------------------------------------------------------
# tablelist::updateHScrlbarWhenIdle
#
# Arranges for the horizontal scrollbar associated with the tablelist widget
# win to be updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateHScrlbarWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(hScrlbarId)]} {
	return ""
    }

    set data(hScrlbarId) [after idle [list tablelist::updateHScrlbar $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateHScrlbar
#
# Updates the horizontal scrollbar associated with the tablelist widget win by
# invoking the command specified as the value of the -xscrollcommand option.
#------------------------------------------------------------------------------
proc tablelist::updateHScrlbar win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(hScrlbarId)]} {
	after cancel $data(hScrlbarId)
	unset data(hScrlbarId)
    }

    if {$data(-titlecolumns) > 0 &&
	[string length $data(-xscrollcommand)] != 0} {
	eval $data(-xscrollcommand) [xviewSubCmd $win {}]
    }
}

#------------------------------------------------------------------------------
# tablelist::updateVScrlbarWhenIdle
#
# Arranges for the vertical scrollbar associated with the tablelist widget win
# to be updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateVScrlbarWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(vScrlbarId)]} {
	return ""
    }

    set data(vScrlbarId) [after idle [list tablelist::updateVScrlbar $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateVScrlbar
#
# Updates the vertical scrollbar associated with the tablelist widget win by
# invoking the command specified as the value of the -yscrollcommand option.
#------------------------------------------------------------------------------
proc tablelist::updateVScrlbar win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(vScrlbarId)]} {
	after cancel $data(vScrlbarId)
	unset data(vScrlbarId)
    }

    if {[string length $data(-yscrollcommand)] != 0} {
	eval $data(-yscrollcommand) [yviewSubCmd $win {}]
    }

    if {[winfo viewable $win] && ![info exists data(colBeingResized)] &&
	![info exists data(redrawId)]} {
	set data(redrawId) [after 50 [list tablelist::forceRedraw $win]]
    }

    if {$data(gotConfigureEvent)} {
	set data(gotConfigureEvent) 0
    } else {
	purgeWidgets $win
    }
}

#------------------------------------------------------------------------------
# tablelist::forceRedraw
#
# Enforces a redraw of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::forceRedraw win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(redrawId)]} {
	after cancel $data(redrawId)
	unset data(redrawId)
    }

    set w $data(body)
    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"
    $w tag add redraw $fromTextIdx $toTextIdx
    $w tag remove redraw $fromTextIdx $toTextIdx

    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	#
	# Work around some Tk bugs on Mac OS X Aqua
	#
	raise $w
	lower $w
	if {[winfo exists $data(bodyFr)]} {
	    lower $data(bodyFr)
	    raise $data(bodyFr)
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::purgeWidgets
#
# Destroys those label widgets containing embedded images and those message
# widgets containing multiline elements that are outside the currently visible
# range of lines of the body of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::purgeWidgets win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"

    foreach {dummy path textIdx} [$w dump -window 1.0 end] {
	if {[string length $path] == 0} {
	    continue
	}

	set class [winfo class $path]
	if {([string compare $class "Label"] == 0 ||
	     [string compare $class "Message"] == 0) &&
	    ([$w compare $textIdx < $fromTextIdx] ||
	     [$w compare $textIdx > $toTextIdx])} {
	    $w tag add elidedWin $textIdx
	    destroy $path
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustElidedText
#
# Updates the elided text ranges of the body text child of the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::adjustElidedText win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(dispId)]} {
	return ""
    }

    #
    # Remove the "hiddenCol" tag
    #
    set w $data(body)
    $w tag remove hiddenCol 1.0 end

    #
    # Add the "hiddenCol" tag to the contents of the hidden
    # columns from the top to the bottom window line
    #
    variable canElide
    variable elide
    if {$canElide && $data(hiddenColCount) > 0 && $data(itemCount) > 0} {
	set topLine [expr {int([$w index @0,0])}]
	set btmLine [expr {int([$w index @0,$data(btmY)])}]
	if {$btmLine > $data(itemCount)} {		;# text widget bug
	    set btmLine $data(itemCount)
	}
	for {set line $topLine; set row [expr {$line - 1}]} \
	    {$line <= $btmLine} {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {[info exists data($key-elide)] ||
		[info exists data($key-hide)]} {
		continue
	    }

	    set textIdx1 $line.0
	    for {set col 0; set count 0} \
		{$col < $data(colCount) && $count < $data(hiddenColCount)} \
		{incr col} {
		set textIdx2 \
		    [$w search $elide "\t" $textIdx1+1c $line.end]+1c
		if {[string compare $textIdx2 "+1c"] == 0} {
		    break
		}
		if {$data($col-hide)} {
		    incr count
		    $w tag add hiddenCol $textIdx1 $textIdx2
		}
		set textIdx1 $textIdx2
	    }

	    #
	    # Update btmLine because it may
	    # change due to the "hiddenCol" tag
	    #
	    set btmLine [expr {int([$w index @0,$data(btmY)])}]
	    if {$btmLine > $data(itemCount)} {		;# text widget bug
		set btmLine $data(itemCount)
	    }
	}

	if {[lindex [$w yview] 1] == 1} {
	    for {set line $btmLine; set row [expr {$line - 1}]} \
		{$line >= $topLine} {set line $row; incr row -1} {
		set key [lindex $data(keyList) $row]
		if {[info exists data($key-elide)] ||
		    [info exists data($key-hide)]} {
		    continue
		}

		set textIdx1 $line.0
		for {set col 0; set count 0} \
		    {$col < $data(colCount) && $count < $data(hiddenColCount)} \
		    {incr col} {
		    set textIdx2 \
			[$w search $elide "\t" $textIdx1+1c $line.end]+1c
		    if {[string compare $textIdx2 "+1c"] == 0} {
			break
		    }
		    if {$data($col-hide)} {
			incr count
			$w tag add hiddenCol $textIdx1 $textIdx2
		    }
		    set textIdx1 $textIdx2
		}

		#
		# Update topLine because it may
		# change due to the "hiddenCol" tag
		#
		set topLine [expr {int([$w index @0,0])}]
	    }
	}
    }

    if {$data(-titlecolumns) == 0} {
	return ""
    }

    #
    # Remove the "elidedCol" tag
    #
    $w tag remove elidedCol 1.0 end
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set data($col-elide) 0
    }

    if {$data(scrlColOffset) == 0} {
	adjustColumns $win {} 0
	return ""
    }

    #
    # Find max. $data(scrlColOffset) non-hidden columns with indices >=
    # $data(-titlecolumns) and retain the first and last of these indices
    #
    set firstCol $data(-titlecolumns)
    while {$firstCol < $data(colCount) && $data($firstCol-hide)} {
	incr firstCol
    }
    if {$firstCol >= $data(colCount)} {
	return ""
    }
    set lastCol $firstCol
    set nonHiddenCount 1
    while {$nonHiddenCount < $data(scrlColOffset) &&
	   $lastCol < $data(colCount)} {
	incr lastCol
	if {!$data($lastCol-hide)} {
	    incr nonHiddenCount
	}
    }

    #
    # Add the "elidedCol" tag to the contents of these
    # columns from the top to the bottom window line
    #
    if {$data(itemCount) > 0} {
	set topLine [expr {int([$w index @0,0])}]
	set btmLine [expr {int([$w index @0,$data(btmY)])}]
	if {$btmLine > $data(itemCount)} {		;# text widget bug
	    set btmLine $data(itemCount)
	}
	for {set line $topLine; set row [expr {$line - 1}]} \
	    {$line <= $btmLine} {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		if {[findTabs $win $line $firstCol $lastCol tabIdx1 tabIdx2]} {
		    $w tag add elidedCol $tabIdx1 $tabIdx2+1c
		}
	    }

	    #
	    # Update btmLine because it may
	    # change due to the "elidedCol" tag
	    #
	    set btmLine [expr {int([$w index @0,$data(btmY)])}]
	    if {$btmLine > $data(itemCount)} {		;# text widget bug
		set btmLine $data(itemCount)
	    }
	}

	if {[lindex [$w yview] 1] == 1} {
	    for {set line $btmLine; set row [expr {$line - 1}]} \
		{$line >= $topLine} {set line $row; incr row -1} {
		set key [lindex $data(keyList) $row]
		if {![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    if {[findTabs $win $line $firstCol $lastCol \
			 tabIdx1 tabIdx2]} {
			$w tag add elidedCol $tabIdx1 $tabIdx2+1c
		    }
		}

		#
		# Update topLine because it may
		# change due to the "elidedCol" tag
		#
		set topLine [expr {int([$w index @0,0])}]
	    }
	}
    }

    #
    # Adjust the columns
    #
    for {set col $firstCol} {$col <= $lastCol} {incr col} {
	set data($col-elide) 1
    }
    adjustColumns $win {} 0
}

#------------------------------------------------------------------------------
# tablelist::redisplayWhenIdle
#
# Arranges for the items of the tablelist widget win to be redisplayed at idle
# time.
#------------------------------------------------------------------------------
proc tablelist::redisplayWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(redispId)] || $data(itemCount) == 0} {
	return ""
    }

    set data(redispId) [after idle [list tablelist::redisplay $win]]

    #
    # Cancel the execution of all delayed redisplayCol commands
    #
    foreach name [array names data *-redispId] {
	after cancel $data($name)
	unset data($name)
    }
}

#------------------------------------------------------------------------------
# tablelist::redisplay
#
# Redisplays the items of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::redisplay {win {getSelCells 1} {selCells {}}} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(redispId)]} {
	after cancel $data(redispId)
	unset data(redispId)
    }

    #
    # Save the indices of the selected cells
    #
    if {$getSelCells} {
	set selCells [curCellSelection $win]
    }

    #
    # Save some data of the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editRow $data(editRow)
	saveEditData $win
    }

    set w $data(body)
    set snipStr $data(-snipstring)
    set rowTagRefCount $data(rowTagRefCount)
    set cellTagRefCount $data(cellTagRefCount)
    set isSimple [expr {$data(imgCount) == 0 && $data(winCount) == 0 &&
			$data(indentCount) == 0}]
    set padY [expr {[$w cget -spacing1] == 0}]
    variable canElide
    variable snipSides
    set newItemList {}
    set row 0
    set line 1
    foreach item $data(itemList) {
	#
	# Empty the line, clip the elements if necessary,
	# and insert them with the corresponding tags
	#
	$w delete $line.0 $line.end
	set keyIdx [expr {[llength $item] - 1}]
	set key [lindex $item end]
	if {$rowTagRefCount == 0} {
	    set hasRowFont 0
	} else {
	    set hasRowFont [info exists data($key-font)]
	}
	set newItem {}
	set col 0
	if {$isSimple} {
	    set insertArgs {}
	    set multilineData {}
	    foreach fmtCmdFlag $data(fmtCmdFlagList) \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$col < $keyIdx} {
		    set text [lindex $item $col]
		} else {
		    set text ""
		}
		lappend newItem $text

		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		if {[string match "*\t*" $text]} {
		    set text [mapTabs $text]
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    if {$multiline} {
			set list [split $text "\n"]
			set snipSide \
			    $snipSides($alignment,$data($col-changesnipside))
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $cellFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		lappend insertArgs "\t\t" $cellTags
		if {$multiline} {
		    lappend multilineData $col $text $cellFont $pixels \
					  $alignment
		}

		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    if {[llength $insertArgs] != 0} {
		eval [list $w insert $line.0] $insertArgs
	    }

	    #
	    # Embed the message widgets displaying multiline elements
	    #
	    foreach {col text font pixels alignment} $multilineData {
		if {[findTabs $win $line $col $col tabIdx1 tabIdx2]} {
		    set msgScript [list ::tablelist::displayText $win $key \
				   $col $text $font $pixels $alignment]
		    $w window create $tabIdx2 \
			      -align top -pady $padY -create $msgScript
		    $w tag add elidedWin $tabIdx2
		}
	    }

	} else {
	    foreach fmtCmdFlag $data(fmtCmdFlagList) \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$col < $keyIdx} {
		    set text [lindex $item $col]
		} else {
		    set text ""
		}
		lappend newItem $text

		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		if {[string match "*\t*" $text]} {
		    set text [mapTabs $text]
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Insert the text and the label or window
		# (if any) into the body text widget
		#
		appendComplexElem $win $key $row $col $text $pixels \
				  $alignment $snipStr $cellFont $cellTags $line

		incr col
	    }
	}

	if {$rowTagRefCount != 0} {
	    if {[info exists data($key-font)]} {
		$w tag add row-font-$data($key-font) $line.0 $line.end
	    }
	}

	if {[info exists data($key-elide)]} {
	    $w tag add elidedRow $line.0 $line.end+1c
	}
	if {[info exists data($key-hide)]} {
	    $w tag add hiddenRow $line.0 $line.end+1c
	}

	lappend newItem $key
	lappend newItemList $newItem

	set row $line
	incr line
    }

    set data(itemList) $newItemList

    #
    # Select the cells that were selected before
    #
    foreach cellIdx $selCells {
	scan $cellIdx "%d,%d" row col
	if {$col < $data(colCount)} {
	    cellSelection $win set $row $col $row $col
	}
    }

    #
    # Conditionally move the "active" tag to the active line or cell
    #
    if {$data(ownsFocus)} {
	moveActiveTag $win
    }

    #
    # Adjust the elided text and restore the stripes in the body text widget
    #
    adjustElidedText $win
    redisplayVisibleItems $win
    makeStripes $win

    #
    # Restore the edit window if it was present before
    #
    if {$editCol >= 0} {
	doEditCell $win $editRow $editCol 1
    }
}

#------------------------------------------------------------------------------
# tablelist::redisplayVisibleItems
#
# Redisplays the visible items of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::redisplayVisibleItems win {
    upvar ::tablelist::ns${win}::data data
    if {$data(itemCount) == 0} {
	return ""
    }

    variable canElide
    variable elide
    variable snipSides

    displayItems $win
    set w $data(body)

    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"
    $w tag remove elidedWin $fromTextIdx $toTextIdx

    set topLine [expr {int([$w index @0,0])}]
    set btmLine [expr {int([$w index @0,$data(btmY)])}]
    if {$btmLine > $data(itemCount)} {			;# text widget bug
	set btmLine $data(itemCount)
    }
    set snipStr $data(-snipstring)

    for {set line $topLine; set row [expr {$line - 1}]} \
	{$line <= $btmLine} {set row $line; incr line} {
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	if {[info exists data($key-elide)] || [info exists data($key-hide)]} {
	    continue
	}

	#
	# Format the item
	#
	set dispItem [lrange $item 0 $data(lastCol)]
	if {$data(hasFmtCmds)} {
	    set dispItem [formatItem $win $key $row $dispItem]
	}
	if {[string match "*\t*" $dispItem]} {
	    set dispItem [mapTabs $dispItem]
	}

	set tabIdx1 $line.0
	set col 0
	foreach text $dispItem \
		colFont $data(colFontList) \
		colTags $data(colTagsList) \
		{pixels alignment} $data(colList) {
	    if {$data($col-hide) && !$canElide} {
		incr col
		continue
	    }

	    set tabIdx2 [$w search $elide "\t" $tabIdx1+1c $line.end]

	    #
	    # Nothing to do if the text is empty or is already displayed,
	    # or interactive editing for this cell is in progress
	    #
	    if {[string length $text] == 0 ||
		[string length [$w get $tabIdx1+1c $tabIdx2]] != 0 ||
		($row == $data(editRow) && $col == $data(editCol))} {
		set tabIdx1 [$w index $tabIdx2+1c]
		incr col
		continue
	    }

	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    if {$pixels != 0} {
		incr pixels $data($col-delta)
	    }

	    #
	    # Nothing to do if the cell has an (indentation)
	    # image or window, or contains multiline text
	    #
	    set aux [getAuxData $win $key $col auxType auxWidth $pixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set multiline [string match "*\n*" $text]
	    if {$auxWidth != 0 || $indentWidth != 0 || $multiline} {
		set tabIdx1 [$w index $tabIdx2+1c]
		incr col
		continue
	    }

	    #
	    # Adjust the cell text
	    #
	    set maxTextWidth $pixels
	    if {[info exists data($key,$col-font)]} {
		set cellFont $data($key,$col-font)
	    } elseif {[info exists data($key-font)]} {
		set cellFont $data($key-font)
	    } else {
		set cellFont $colFont
	    }
	    if {$pixels != 0} {
		set maxTextWidth \
		    [getMaxTextWidth $pixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			#
			# The element is displayed as multiline text
			#
			set tabIdx1 [$w index $tabIdx2+1c]
			incr col
			continue
		    }
		}
	    }
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    adjustElem $win text auxWidth indentWidth $cellFont $pixels \
		       $snipSide $snipStr

	    #
	    # Update the text widget's contents between the two tabs
	    #
	    $w mark set tabMark2 [$w index $tabIdx2]
	    updateCell $w $tabIdx1+1c $tabIdx2 $text $aux $auxType $auxWidth \
		       $indent $indentWidth $alignment ""

	    set tabIdx1 [$w index tabMark2+1c]
	    incr col
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::redisplayColWhenIdle
#
# Arranges for the elements of the col'th column of the tablelist widget win to
# be redisplayed at idle time.
#------------------------------------------------------------------------------
proc tablelist::redisplayColWhenIdle {win col} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data($col-redispId)] || [info exists data(redispId)] ||
	$data(itemCount) == 0} {
	return ""
    }

    set data($col-redispId) \
	[after idle [list tablelist::redisplayCol $win $col 0 last]]
}

#------------------------------------------------------------------------------
# tablelist::redisplayCol
#
# Redisplays the elements of the col'th column of the tablelist widget win, in
# the range specified by first and last.
#------------------------------------------------------------------------------
proc tablelist::redisplayCol {win col first last} {
    upvar ::tablelist::ns${win}::data data
    set allRows [expr {$first == 0 && [string compare $last "last"] == 0}]
    if {$allRows && [info exists data($col-redispId)]} {
	after cancel $data($col-redispId)
	unset data($col-redispId)
    }

    if {$data(itemCount) == 0 || $first < 0 ||
	$col > $data(lastCol) || $data($col-hide)} {
	return ""
    }
    if {[string compare $last "last"] == 0} {
	set last $data(lastRow)
    }

    displayItems $win
    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
    set colFont [lindex $data(colFontList) $col]
    set snipStr $data(-snipstring)

    set w $data(body)
    set pixels [lindex $data(colList) [expr {2*$col}]]
    if {$pixels == 0} {				;# convention: dynamic width
	if {$data($col-maxPixels) > 0} {
	    if {$data($col-reqPixels) > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
	    }
	}
    }
    if {$pixels != 0} {
	incr pixels $data($col-delta)
    }
    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
    variable snipSides
    set snipSide $snipSides($alignment,$data($col-changesnipside))

    for {set row $first; set line [expr {$first + 1}]} {$row <= $last} \
	{set row $line; incr line} {
	if {$row == $data(editRow) && $col == $data(editCol)} {
	    continue
	}

	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	if {!$allRows && ([info exists data($key-elide)] ||
			  [info exists data($key-hide)])} {
	    continue
	}

	#
	# Adjust the cell text and the image or window width
	#
	set text [lindex $item $col]
	if {$fmtCmdFlag} {
	    set text [formatElem $win $key $row $col $text]
	}
	if {[string match "*\t*" $text]} {
	    set text [mapTabs $text]
	}
	set multiline [string match "*\n*" $text]
	set aux [getAuxData $win $key $col auxType auxWidth $pixels]
	set indent [getIndentData $win $key $col indentWidth]
	set maxTextWidth $pixels
	if {[info exists data($key,$col-font)]} {
	    set cellFont $data($key,$col-font)
	} elseif {[info exists data($key-font)]} {
	    set cellFont $data($key-font)
	} else {
	    set cellFont $colFont
	}
	if {$pixels != 0} {
	    set maxTextWidth [getMaxTextWidth $pixels $auxWidth $indentWidth]

	    if {$data($col-wrap) && !$multiline} {
		if {[font measure $cellFont -displayof $win $text] >
		    $maxTextWidth} {
		    set multiline 1
		}
	    }
	}
	if {$multiline} {
	    set list [split $text "\n"]
	    set snipSide2 $snipSide
	    if {$data($col-wrap)} {
		set snipSide2 ""
	    }
	    adjustMlElem $win list auxWidth indentWidth $cellFont \
			 $pixels $snipSide2 $snipStr
	    set msgScript [list ::tablelist::displayText $win $key $col \
			   [join $list "\n"] $cellFont $maxTextWidth $alignment]
	} else {
	    adjustElem $win text auxWidth indentWidth $cellFont \
		       $pixels $snipSide $snipStr
	}

	#
	# Update the text widget's contents between the two tabs
	#
	if {[findTabs $win $line $col $col tabIdx1 tabIdx2]} {
	    if {$auxType > 1 && $auxWidth > 0 && ![winfo exists $aux]} {
		#
		# Create a frame and evaluate the script that
		# creates a child window within the frame
		#
		tk::frame $aux -borderwidth 0 -class TablelistWindow \
			       -container 0 -height $data($key,$col-reqHeight) \
			       -highlightthickness 0 -relief flat \
			       -takefocus 0 -width $auxWidth
		catch {$aux configure -padx 0 -pady 0}
		bindtags $aux [linsert [bindtags $aux] 1 \
			       $data(bodyTag) TablelistBody]
		uplevel #0 $data($key,$col-window) [list $win $row $col $aux.w]
	    }

	    if {$multiline} {
		updateMlCell $w $tabIdx1+1c $tabIdx2 $msgScript $aux $auxType \
			     $auxWidth $indent $indentWidth $alignment \
			     [getVAlignment $win $key $col]
	    } else {
		updateCell $w $tabIdx1+1c $tabIdx2 $text $aux $auxType \
			   $auxWidth $indent $indentWidth $alignment \
			   [getVAlignment $win $key $col]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::makeStripesWhenIdle
#
# Arranges for the stripes in the body of the tablelist widget win to be
# redrawn at idle time.
#------------------------------------------------------------------------------
proc tablelist::makeStripesWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stripesId)] || $data(itemCount) == 0} {
	return ""
    }

    set data(stripesId) [after idle [list tablelist::makeStripes $win]]
}

#------------------------------------------------------------------------------
# tablelist::makeStripes
#
# Redraws the stripes in the body of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeStripes win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stripesId)]} {
	after cancel $data(stripesId)
	unset data(stripesId)
    }

    if {[info exists data(dispId)]} {
	return ""
    }

    set w $data(body)
    $w tag remove stripe 1.0 end
    if {[string length $data(-stripebackground)] != 0 ||
	[string length $data(-stripeforeground)] != 0} {
	set count 0
	set inStripe 0
	for {set row 0; set line 1} {$row < $data(itemCount)} \
	    {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		if {$inStripe} {
		    $w tag add stripe $line.0 $line.end
		}

		if {[incr count] == $data(-stripeheight)} {
		    set count 0
		    set inStripe [expr {!$inStripe}]
		}
	    }
	}
    }

    updateColors $win
}

#------------------------------------------------------------------------------
# tablelist::showLineNumbersWhenIdle
#
# Arranges for the line numbers in the tablelist widget win to be redisplayed
# at idle time.
#------------------------------------------------------------------------------
proc tablelist::showLineNumbersWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(lineNumsId)] || $data(itemCount) == 0} {
	return ""
    }

    set data(lineNumsId) [after idle [list tablelist::showLineNumbers $win]]
}

#------------------------------------------------------------------------------
# tablelist::showLineNumbers
#
# Redisplays the line numbers (if any) in the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::showLineNumbers win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(lineNumsId)]} {
	after cancel $data(lineNumsId)
	unset data(lineNumsId)
    }

    #
    # Update the item list
    #
    set colIdxList {}
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {!$data($col-showlinenumbers)} {
	    continue
	}

	lappend colIdxList $col

	set newItemList {}
	set line 1
	foreach item $data(itemList) {
	    set item [lreplace $item $col $col $line]
	    lappend newItemList $item
	    set key [lindex $item end]
	    if {![info exists data($key-hide)]} {
		incr line
	    }
	}
	set data(itemList) $newItemList

	redisplayColWhenIdle $win $col
    }

    if {[llength $colIdxList] == 0} {
	return ""
    }

    #
    # Update the list variable if present, and adjust the columns
    #
    condUpdateListVar $win
    adjustColumns $win $colIdxList 1
    return ""
}

#------------------------------------------------------------------------------
# tablelist::updateViewWhenIdle
#
# Arranges for the visible part of the tablelist widget win to be updated
# at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateViewWhenIdle {win {reschedule 0}} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(viewId)]} {
	if {$reschedule} {
	    after cancel $data(viewId)
	} else {
	    return ""
	}
    }

    set data(viewId) [after idle [list tablelist::updateView $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateView
#
# Updates the visible part of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::updateView win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(viewId)]} {
	after cancel $data(viewId)
	unset data(viewId)
    }

    adjustElidedText $win
    redisplayVisibleItems $win
    updateColors $win
    adjustSeps $win
    updateVScrlbar $win
}

#------------------------------------------------------------------------------
# tablelist::destroyWidgets
#
# Destroys a list of widgets embedded into the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::destroyWidgets win {
    upvar ::tablelist::ns${win}::data data
    set destroyId [lindex $data(destroyIdList) 0]

    eval destroy $data(widgets-$destroyId)

    set data(destroyIdList) [lrange $data(destroyIdList) 1 end]
    unset data(widgets-$destroyId)
}

#------------------------------------------------------------------------------
# tablelist::synchronize
#
# This procedure is invoked either as an idle callback after the list variable
# associated with the tablelist widget win was written, or directly, upon
# execution of some widget commands.  It makes sure that the content of the
# widget is synchronized with the value of the list variable.
#------------------------------------------------------------------------------
proc tablelist::synchronize win {
    #
    # Nothing to do if the list variable was not written
    #
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(syncId)]} {
	return ""
    }

    #
    # Here we are in the case that the procedure was scheduled for
    # execution at idle time.  However, it might have been invoked
    # directly, before the idle time occured; in this case we should
    # cancel the execution of the previously scheduled idle callback.
    #
    after cancel $data(syncId)	;# no harm if data(syncId) is no longer valid
    unset data(syncId)

    upvar #0 $data(-listvariable) var
    set newCount [llength $var]
    if {$newCount < $data(itemCount)} {
	#
	# Delete the items with indices >= newCount from the widget
	#
	set updateCount $newCount
	deleteRows $win $newCount $data(lastRow) 0
    } elseif {$newCount > $data(itemCount)} {
	#
	# Insert the items of var with indices
	# >= data(itemCount) into the widget
	#
	set updateCount $data(itemCount)
	insertRows $win $data(itemCount) [lrange $var $data(itemCount) end] 0 \
		   root $data(itemCount)
    } else {
	set updateCount $newCount
    }

    #
    # Update the first updateCount items of the internal list
    #
    set itemsChanged 0
    for {set row 0} {$row < $updateCount} {incr row} {
	set oldItem [lindex $data(itemList) $row]
	set newItem [adjustItem [lindex $var $row] $data(colCount)]
	lappend newItem [lindex $oldItem end]

	if {[string compare $oldItem $newItem] != 0} {
	    set data(itemList) [lreplace $data(itemList) $row $row $newItem]
	    set itemsChanged 1
	}
    }

    #
    # If necessary, adjust the columns and make sure
    # that the items will be redisplayed at idle time
    #
    if {$itemsChanged} {
	adjustColumns $win allCols 1
	redisplayWhenIdle $win
	showLineNumbersWhenIdle $win
	updateViewWhenIdle $win
    }
}

#------------------------------------------------------------------------------
# tablelist::getSublabels
#
# Returns the list of the existing sublabels $w-il and $w-tl associated with
# the label widget w.
#------------------------------------------------------------------------------
proc tablelist::getSublabels w {
    set lst {}
    foreach lbl [list $w-il $w-tl] {
	if {[winfo exists $lbl]} {
	    lappend lst $lbl
	}
    }

    return $lst
}

#------------------------------------------------------------------------------
# tablelist::parseLabelPath
#
# Extracts the path name of the tablelist widget as well as the column number
# from the path name w of a header label.
#------------------------------------------------------------------------------
proc tablelist::parseLabelPath {w winName colName} {
    if {![winfo exists $w]} {
	return 0
    }

    upvar $winName win $colName col
    return [regexp {^(\..+)\.hdr\.t\.f\.l([0-9]+)$} $w dummy win col]
}

#------------------------------------------------------------------------------
# tablelist::configLabel
#
# This procedure configures the label widget w according to the options and
# their values given in args.  It is needed for label widgets with sublabels.
#------------------------------------------------------------------------------
proc tablelist::configLabel {w args} {
    foreach {opt val} $args {
	switch -- $opt {
	    -active {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    $w instate !selected {
			set state [expr {$val ? "active" : "!active"}]
			$w state $state
			variable themeDefaults
			if {$val} {
			    set bg $themeDefaults(-labelactiveBg)
			} else {
			    set bg $themeDefaults(-labelbackground)
			}
			foreach l [getSublabels $w] {
			    $l configure -background $bg
			}
		    }
		} else {
		    set state [expr {$val ? "active" : "normal"}]
		    catch {
			$w configure -state $state
			foreach l [getSublabels $w] {
			    $l configure -state $state
			}
		    }
		}

		parseLabelPath $w win col
		upvar ::tablelist::ns${win}::data data
		if {[lsearch -exact $data(arrowColList) $col] >= 0} {
		    configCanvas $win $col
		}
	    }

	    -activebackground -
	    -activeforeground -
	    -disabledforeground -
	    -cursor {
		$w configure $opt $val
		foreach l [getSublabels $w] {
		    $l configure $opt $val
		}
	    }

	    -background -
	    -font {
		if {[string compare [winfo class $w] "TLabel"] == 0 &&
		    [string length $val] == 0} {
		    variable themeDefaults
		    set val $themeDefaults(-label[string range $opt 1 end])
		}
		$w configure $opt $val
		foreach l [getSublabels $w] {
		    $l configure $opt $val
		}
	    }

	    -foreground {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    variable themeDefaults
		    if {[string compare [winfo rgb $w $val] [winfo rgb $w \
			 $themeDefaults(-labelforeground)]] == 0} {
			set val ""    ;# for automatic adaptation to the states
		    }
		    $w instate !disabled {
			$w configure $opt $val
		    }
		} else {
		    $w configure $opt $val
		    foreach l [getSublabels $w] {
			$l configure $opt $val
		    }
		}
	    }

	    -padx {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set padding [$w cget -padding]
		    lset padding 0 $val
		    lset padding 2 $val
		    $w configure -padding $padding
		} else {
		    $w configure $opt $val
		}
	    }

	    -pady {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set val [winfo pixels $w $val]
		    set padding [$w cget -padding]
		    lset padding 1 $val
		    lset padding 3 $val
		    $w configure -padding $padding
		} else {
		    $w configure $opt $val
		}
	    }

	    -pressed {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set state [expr {$val ? "pressed" : "!pressed"}]
		    $w state $state
		    variable themeDefaults
		    if {$val} {
			if {[$w instate selected]} {
			    set bg $themeDefaults(-labelselectedpressedBg)
			} else {
			    set bg $themeDefaults(-labelpressedBg)
			}
		    } else {
			if {[$w instate selected]} {
			    set bg $themeDefaults(-labelselectedBg)
			} elseif {[$w instate active]} {
			    set bg $themeDefaults(-labelactiveBg)
			} else {
			    set bg $themeDefaults(-labelbackground)
			}
		    }
		    foreach l [getSublabels $w] {
			$l configure -background $bg
		    }

		    parseLabelPath $w win col
		    upvar ::tablelist::ns${win}::data data
		    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
			configCanvas $win $col
		    }
		}
	    }

	    -selected {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set state [expr {$val ? "selected" : "!selected"}]
		    $w state $state
		    variable themeDefaults
		    if {$val} {
			if {[$w instate pressed]} {
			    set bg $themeDefaults(-labelselectedpressedBg)
			} else {
			    set bg $themeDefaults(-labelselectedBg)
			}
		    } else {
			if {[$w instate pressed]} {
			    set bg $themeDefaults(-labelpressedBg)
			} else {
			    set bg $themeDefaults(-labelbackground)
			}
		    }
		    foreach l [getSublabels $w] {
			$l configure -background $bg
		    }

		    parseLabelPath $w win col
		    upvar ::tablelist::ns${win}::data data
		    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
			configCanvas $win $col
		    }
		}
	    }

	    -state {
		$w configure $opt $val
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    variable themeDefaults
		    if {[string compare $val "disabled"] == 0} {
			#
			# Set the label's foreground color to the theme-
			# specific one (needed for current tile versions)
			#
			$w configure -foreground ""

			set bg $themeDefaults(-labeldisabledBg)
		    } else {
			#
			# Restore the label's foreground color
			# (needed for current tile versions)
			#
			if {[parseLabelPath $w win col]} {
			    upvar ::tablelist::ns${win}::data data
			    if {[info exists data($col-labelforeground)]} {
				set fg $data($col-labelforeground)
			    } else {
				set fg $data(-labelforeground)
			    }
			    configLabel $w -foreground $fg
			}

			set bg $themeDefaults(-labelbackground)
		    }
		    foreach l [getSublabels $w] {
			$l configure -background $bg
		    }
		} else {
		    foreach l [getSublabels $w] {
			$l configure $opt $val
		    }
		}
	    }

	    default {
		if {[string compare $val [$w cget $opt]] != 0} {
		    $w configure $opt $val
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createArrows
#
# Creates two arrows in the canvas w.
#------------------------------------------------------------------------------
proc tablelist::createArrows {w width height relief} {
    if {$height < 6} {
	set wHeight 6
	variable centerArrows
	set y [expr {$centerArrows ? 0 : 1}]
    } else {
	set wHeight $height
	set y 0
    }

    $w configure -width $width -height $wHeight

    #
    # Delete any existing arrow image items from
    # the canvas and the corresponding images
    #
    set imgNames [image names]
    foreach shape {triangleUp darkLineUp lightLineUp
		   triangleDn darkLineDn lightLineDn} {
	$w delete $shape
	if {[lsearch -exact $imgNames $shape$w] >= 0} {
	    image delete $shape$w
	}
    }

    #
    # Create the arrow images and canvas image items
    # corresponding to the procedure's arguments
    #
    $relief${width}x${height}Arrows $w
    set imgNames [image names]
    foreach shape {triangleUp darkLineUp lightLineUp
		   triangleDn darkLineDn lightLineDn} {
	if {[lsearch -exact $imgNames $shape$w] >= 0} {
	    $w create image 0 $y -anchor nw -image $shape$w -tags $shape
	}
    }

    #
    # Create the sort rank image item
    #
    $w delete sortRank
    set x [expr {$width + 2}]
    set y [expr {$wHeight - 6}]
    $w create image $x $y -anchor nw -tags sortRank
}

#------------------------------------------------------------------------------
# tablelist::configCanvas
#
# Sets the background color of the canvas displaying an up- or down-arrow for
# the given column, and fills the two arrows contained in the canvas.
#------------------------------------------------------------------------------
proc tablelist::configCanvas {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrLbl)$col

    if {[string compare [winfo class $w] "TLabel"] == 0} {
	variable themeDefaults
	set labelBg $themeDefaults(-labelbackground)
	set fg [$w cget -foreground]
	set labelFg $fg
	if {[string length $fg] == 0} {
	    set labelFg $themeDefaults(-labelforeground)
	}

	if {[$w instate disabled]} {
	    set labelBg $themeDefaults(-labeldisabledBg)
	    set labelFg $themeDefaults(-labeldisabledFg)
	} elseif {[$win instate background]} {
	    set labelBg $themeDefaults(-labeldeactivatedBg)
	} else {
	    foreach state {active pressed selected} {
		$w instate $state {
		    set labelBg $themeDefaults(-label${state}Bg)
		    if {[string length $fg] == 0} {
			set labelFg $themeDefaults(-label${state}Fg)
		    }
		}
	    }
	    $w instate {selected pressed} {
		set labelBg $themeDefaults(-labelselectedpressedBg)
		if {[string length $fg] == 0} {
		    set labelFg $themeDefaults(-labelselectedpressedFg)
		}
	    }
	}
    } else {
	set labelBg [$w cget -background]
	set labelFg [$w cget -foreground]

	catch {
	    set state [$w cget -state]
	    if {[string compare $state "disabled"] == 0} {
		set labelFg [$w cget -disabledforeground]
	    } elseif {[string compare $state "active"] == 0} {
		variable winSys
		if {!([string compare $winSys "classic"] == 0 ||
		      [string compare $winSys "aqua"] == 0) ||
		    $::tk_version > 8.4} {
		    set labelBg [$w cget -activebackground]
		    set labelFg [$w cget -activeforeground]
		}
	    }
	}
    }

    set canvas $data(hdrTxtFrCanv)$col
    $canvas configure -background $labelBg
    sortRank$data($col-sortRank)$win configure -foreground $labelFg

    if {$data(isDisabled)} {
	fillArrows $canvas $data(-arrowdisabledcolor) $data(-arrowstyle)
    } else {
	fillArrows $canvas $data(-arrowcolor) $data(-arrowstyle)
    }
}

#------------------------------------------------------------------------------
# tablelist::fillArrows
#
# Fills the two arrows contained in the canvas w with the given color, or with
# the background color of the canvas if color is an empty string.  Also fills
# the arrow's borders (if any) with the corresponding 3-D shadow colors.
#------------------------------------------------------------------------------
proc tablelist::fillArrows {w color arrowStyle} {
    set bgColor [$w cget -background]
    if {[string length $color] == 0} {
	set color $bgColor
    }

    getShadows $w $color darkColor lightColor

    foreach dir {Up Dn} {
	if {[string compare [image type triangle$dir$w] "bitmap"] == 0} {
	    triangle$dir$w configure -foreground $color -background $bgColor
	}

	if {[string match "sunken*" $arrowStyle]} {
	    darkLine$dir$w  configure -foreground $darkColor
	    lightLine$dir$w configure -foreground $lightColor
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::getShadows
#
# Computes the shadow colors for a 3-D border from a given (background) color.
# This is the Tcl-counterpart of the function TkpGetShadows() in the Tk
# distribution file unix/tkUnix3d.c.
#------------------------------------------------------------------------------
proc tablelist::getShadows {w color darkColorName lightColorName} {
    upvar $darkColorName darkColor $lightColorName lightColor

    set rgb [winfo rgb $w $color]
    foreach {r g b} $rgb {}
    set maxIntens [lindex [winfo rgb $w white] 0]

    #
    # Compute the dark shadow color
    #
    if {[string compare $::tk_patchLevel "8.3.1"] >= 0 &&
	$r*0.5*$r + $g*1.0*$g + $b*0.28*$b < $maxIntens*0.05*$maxIntens} {
	#
	# The background is already very dark: make the dark
	# color a little lighter than the background by increasing
	# each color component 1/4th of the way to $maxIntens
	#
	foreach comp $rgb {
	    lappend darkRGB [expr {($maxIntens + 3*$comp)/4}]
	}
    } else {
	#
	# Compute the dark color by cutting 40% from
	# each of the background color components.
	#
	foreach comp $rgb {
	    lappend darkRGB [expr {60*$comp/100}]
	}
    }
    set darkColor [eval format "#%04x%04x%04x" $darkRGB]

    #
    # Compute the light shadow color
    #
    if {[string compare $::tk_patchLevel "8.3.1"] >= 0 &&
	$g > $maxIntens*0.95} {
	#
	# The background is already very bright: make the
	# light color a little darker than the background
	# by reducing each color component by 10%
	#
	foreach comp $rgb {
	    lappend lightRGB [expr {90*$comp/100}]
	}
    } else {
	#
	# Compute the light color by boosting each background
	# color component by 40% or half-way to white, whichever
	# is greater (the first approach works better for
	# unsaturated colors, the second for saturated ones)
	#
	foreach comp $rgb {
	    set comp1 [expr {140*$comp/100}]
	    if {$comp1 > $maxIntens} {
		set comp1 $maxIntens
	    }
	    set comp2 [expr {($maxIntens + $comp)/2}]
	    lappend lightRGB [expr {($comp1 > $comp2) ? $comp1 : $comp2}]
	}
    }
    set lightColor [eval format "#%04x%04x%04x" $lightRGB]
}

#------------------------------------------------------------------------------
# tablelist::raiseArrow
#
# Raises one of the two arrows contained in the canvas associated with the
# given column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::raiseArrow {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrCanv)$col
    variable directions
    set dir $directions($data(-incrarrowtype),$data($col-sortOrder))

    if {[string match "photo*" $data(-arrowstyle)]} {
	$w itemconfigure triangle$dir -state normal
	set dir [expr {([string compare $dir "Up"] == 0) ? "Dn" : "Up"}]
	$w itemconfigure triangle$dir -state hidden
    } else {
	$w raise triangle$dir
	$w raise darkLine$dir
	$w raise lightLine$dir
    }
}

#------------------------------------------------------------------------------
# tablelist::isHdrTxtFrXPosVisible
#
# Checks whether the given x position in the header text child of the tablelist
# widget win is visible.
#------------------------------------------------------------------------------
proc tablelist::isHdrTxtFrXPosVisible {win x} {
    upvar ::tablelist::ns${win}::data data
    foreach {fraction1 fraction2} [$data(hdrTxt) xview] {}
    return [expr {$x >= $fraction1 * $data(hdrPixels) &&
		  $x <  $fraction2 * $data(hdrPixels)}]
}

#------------------------------------------------------------------------------
# tablelist::getScrlContentWidth
#
# Returns the total width of the non-hidden scrollable columns of the tablelist
# widget win, in the specified range.
#------------------------------------------------------------------------------
proc tablelist::getScrlContentWidth {win scrlColOffset lastCol} {
    upvar ::tablelist::ns${win}::data data
    set scrlContentWidth 0
    set nonHiddenCount 0
    for {set col $data(-titlecolumns)} {$col <= $lastCol} {incr col} {
	if {!$data($col-hide) && [incr nonHiddenCount] > $scrlColOffset} {
	    incr scrlContentWidth [colWidth $win $col -total]
	}
    }

    return $scrlContentWidth
}

#------------------------------------------------------------------------------
# tablelist::getScrlWindowWidth
#
# Returns the number of pixels obtained by subtracting the widths of the non-
# hidden title columns from the width of the header frame of the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::getScrlWindowWidth win {
    upvar ::tablelist::ns${win}::data data
    set scrlWindowWidth [winfo width $data(hdr)]
    for {set col 0} {$col < $data(-titlecolumns) && $col < $data(colCount)} \
	{incr col} {
	if {!$data($col-hide)} {
	    incr scrlWindowWidth -[colWidth $win $col -total]
	}
    }

    return $scrlWindowWidth
}

#------------------------------------------------------------------------------
# tablelist::getMaxScrlColOffset
#
# Returns the max. scrolled column offset of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getMaxScrlColOffset win {
    #
    # Get the number of non-hidden scrollable columns
    #
    upvar ::tablelist::ns${win}::data data
    set maxScrlColOffset 0
    for {set col $data(-titlecolumns)} {$col < $data(colCount)} {incr col} {
	if {!$data($col-hide)} {
	    incr maxScrlColOffset
	}
    }

    #
    # Decrement maxScrlColOffset while the total width of the
    # non-hidden scrollable columns starting with this offset
    # is less than the width of the window's scrollable part
    #
    set scrlWindowWidth [getScrlWindowWidth $win]
    if {$scrlWindowWidth > 0} {
	while {$maxScrlColOffset > 0} {
	    incr maxScrlColOffset -1
	    set scrlContentWidth \
		[getScrlContentWidth $win $maxScrlColOffset $data(lastCol)]
	    if {$scrlContentWidth == $scrlWindowWidth} {
		break
	    } elseif {$scrlContentWidth > $scrlWindowWidth} {
		incr maxScrlColOffset
		break
	    }
	}
    }

    return $maxScrlColOffset
}

#------------------------------------------------------------------------------
# tablelist::changeScrlColOffset
#
# Changes the scrolled column offset of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::changeScrlColOffset {win scrlColOffset} {
    #
    # Make sure the offset is non-negative and no
    # greater than the max. scrolled column offset
    #
    if {$scrlColOffset < 0} {
	set scrlColOffset 0
    } else {
	set maxScrlColOffset [getMaxScrlColOffset $win]
	if {$scrlColOffset > $maxScrlColOffset} {
	    set scrlColOffset $maxScrlColOffset
	}
    }

    #
    # Update data(scrlColOffset) and adjust the
    # elided text in the tablelist's body if necessary
    #
    upvar ::tablelist::ns${win}::data data
    if {$scrlColOffset != $data(scrlColOffset)} {
	set data(scrlColOffset) $scrlColOffset
	adjustElidedText $win
	redisplayVisibleItems $win
    }
}

#------------------------------------------------------------------------------
# tablelist::scrlXOffsetToColOffset
#
# Returns the scrolled column offset of the tablelist widget win, corresponding
# to the desired x offset.
#------------------------------------------------------------------------------
proc tablelist::scrlXOffsetToColOffset {win scrlXOffset} {
    upvar ::tablelist::ns${win}::data data
    set scrlColOffset 0
    set scrlContentWidth 0
    for {set col $data(-titlecolumns)} {$col < $data(colCount)} {incr col} {
	if {$data($col-hide)} {
	    continue
	}

	incr scrlContentWidth [colWidth $win $col -total]
	if {$scrlContentWidth > $scrlXOffset} {
	    break
	} else {
	    incr scrlColOffset
	}
    }

    return $scrlColOffset
}

#------------------------------------------------------------------------------
# tablelist::scrlColOffsetToXOffset
#
# Returns the x offset corresponding to the specified scrolled column offset of
# the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::scrlColOffsetToXOffset {win scrlColOffset} {
    upvar ::tablelist::ns${win}::data data
    set scrlXOffset 0
    set nonHiddenCount 0
    for {set col $data(-titlecolumns)} {$col < $data(colCount)} {incr col} {
	if {$data($col-hide)} {
	    continue
	}

	if {[incr nonHiddenCount] > $scrlColOffset} {
	    break
	} else {
	    incr scrlXOffset [colWidth $win $col -total]
	}
    }

    return $scrlXOffset
}

#------------------------------------------------------------------------------
# tablelist::getViewableRowCount
#
# Returns the number of viewable rows of the tablelist widget win in the
# specified range.
#------------------------------------------------------------------------------
proc tablelist::getViewableRowCount {win first last} {
    upvar ::tablelist::ns${win}::data data
    if {$first == 0 && $last == $data(lastRow)} {
	return [expr {$data(itemCount) - $data(nonViewableRowCount)}]
    } elseif {$data(nonViewableRowCount) == 0} {
	return [expr {$last - $first + 1}]
    } else {
	set count 0
	for {set row $first} {$row <= $last} {incr row} {
	    set key [lindex $data(keyList) $row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		incr count
	    }
	}

	return $count
    }
}

#------------------------------------------------------------------------------
# tablelist::viewableRowOffsetToRowIndex
#
# Returns the row index corresponding to the given viewable row offset in the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::viewableRowOffsetToRowIndex {win offset} {
    upvar ::tablelist::ns${win}::data data
    if {$data(nonViewableRowCount) == 0} {
	return $offset
    } else {
	#
	# Rebuild the list data(viewableRowList) of the row
	# indices indicating the viewable rows if needed
	#
	if {[lindex $data(viewableRowList) 0] == -1} {
	    set data(viewableRowList) {}
	    for {set row 0} {$row < $data(itemCount)} {incr row} {
		set key [lindex $data(keyList) $row]
		if {![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    lappend data(viewableRowList) $row
		}
	    }
	}

	set viewableCount [llength $data(viewableRowList)]
	if {$viewableCount == 0} {
	    return 0
	} else {
	    if {$offset >= $viewableCount} {
		set offset [expr {$viewableCount - 1}]
	    }
	    if {$offset < 0} {
		set offset 0
	    }
	    return [lindex $data(viewableRowList) $offset]
	}
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tablelistWidget.tcl.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
#==============================================================================
# Contains the implementation of the tablelist widget.
#
# Structure of the module:
#   - Namespace initialization
#   - Private procedure creating the default bindings
#   - Public procedure creating a new tablelist widget
#   - Private procedures implementing the tablelist widget command
#   - Private callback procedures
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Namespace initialization
# ========================
#

namespace eval tablelist {
    #
    # Get the current windowing system ("x11", "win32", "classic", or "aqua")
    #
    variable winSys
    if {[catch {tk windowingsystem} winSys] != 0} {
	switch $::tcl_platform(platform) {
	    unix	{ set winSys x11 }
	    windows	{ set winSys win32 }
	    macintosh	{ set winSys classic }
	}
    }

    #
    # Create aliases for a few tile commands if not yet present
    #
    proc createTileAliases {} {
	if {[string length [interp alias {} ::tablelist::style]] != 0} {
	    return ""
	}

	if {[string length [info commands ::ttk::style]] == 0} {
	    interp alias {} ::tablelist::style      {} ::style
	    if {[string compare $::tile::version "0.7"] >= 0} {
		interp alias {} ::tablelist::styleConfig {} ::style configure
	    } else {
		interp alias {} ::tablelist::styleConfig {} ::style default
	    }
	    interp alias {} ::tablelist::getThemes  {} ::tile::availableThemes
	    interp alias {} ::tablelist::setTheme   {} ::tile::setTheme

	    interp alias {} ::tablelist::tileqt_kdeStyleChangeNotification \
			 {} ::tile::theme::tileqt::kdeStyleChangeNotification
	    interp alias {} ::tablelist::tileqt_currentThemeName \
			 {} ::tile::theme::tileqt::currentThemeName
	    interp alias {} ::tablelist::tileqt_currentThemeColour \
			 {} ::tile::theme::tileqt::currentThemeColour
	} else {
	    interp alias {} ::tablelist::style	      {} ::ttk::style
	    interp alias {} ::tablelist::styleConfig  {} ::ttk::style configure
	    interp alias {} ::tablelist::getThemes    {} ::ttk::themes
	    interp alias {} ::tablelist::setTheme     {} ::ttk::setTheme

	    interp alias {} ::tablelist::tileqt_kdeStyleChangeNotification \
			 {} ::ttk::theme::tileqt::kdeStyleChangeNotification
	    interp alias {} ::tablelist::tileqt_currentThemeName \
			 {} ::ttk::theme::tileqt::currentThemeName
	    interp alias {} ::tablelist::tileqt_currentThemeColour \
			 {} ::ttk::theme::tileqt::currentThemeColour
	}
    }
    if {$usingTile} {
	createTileAliases 
    }

    variable pngSupported [expr {($::tk_version >= 8.6 &&
	![regexp {^8\.6(a[1-3]|b1)$} $::tk_patchLevel]) ||
	($::tk_version >= 8.5 && [catch {package require img::png}] == 0)}]

    variable specialAquaHandling [expr {$usingTile && ($::tk_version >= 8.6 ||
	[regexp {^8\.5\.(9|[1-9][0-9])$} $::tk_patchLevel]) &&
	[lsearch -exact [winfo server .] "AppKit"] >= 0}]

    #
    # The array configSpecs is used to handle configuration options.  The
    # names of its elements are the configuration options for the Tablelist
    # class.  The value of an array element is either an alias name or a list
    # containing the database name and class as well as an indicator specifying
    # the widget(s) to which the option applies: c stands for all children
    # (text widgets and labels), b for the body text widget, l for the labels,
    # f for the frame, and w for the widget itself.
    #
    #	Command-Line Name	 {Database Name		  Database Class      W}
    #	------------------------------------------------------------------------
    #
    variable configSpecs
    array set configSpecs {
	-acceptchildcommand	 {acceptChildCommand	  AcceptChildCommand  w}
	-acceptdropcommand	 {acceptDropCommand	  AcceptDropCommand   w}
	-activestyle		 {activeStyle		  ActiveStyle	      w}
	-arrowcolor		 {arrowColor		  ArrowColor	      w}
	-arrowdisabledcolor	 {arrowDisabledColor	  ArrowDisabledColor  w}
	-arrowstyle		 {arrowStyle		  ArrowStyle	      w}
	-autofinishediting	 {autoFinishEditing	  AutoFinishEditing   w}
	-autoscan		 {autoScan		  AutoScan	      w}
	-background		 {background		  Background	      b}
	-bg			 -background
	-borderwidth		 {borderWidth		  BorderWidth	      f}
	-bd			 -borderwidth
	-collapsecommand	 {collapseCommand	  CollapseCommand     w}
	-colorizecommand	 {colorizeCommand	  ColorizeCommand     w}
	-columns		 {columns		  Columns	      w}
	-columntitles		 {columnTitles		  ColumnTitles	      w}
	-cursor			 {cursor		  Cursor	      c}
	-customdragsource	 {customDragSource	  CustomDragSource    w}
	-disabledforeground	 {disabledForeground	  DisabledForeground  w}
	-editendcommand		 {editEndCommand	  EditEndCommand      w}
	-editselectedonly	 {editSelectedOnly	  EditSelectedOnly    w}
	-editstartcommand	 {editStartCommand	  EditStartCommand    w}
	-expandcommand		 {expandCommand		  ExpandCommand       w}
	-exportselection	 {exportSelection	  ExportSelection     w}
	-font			 {font			  Font		      b}
	-forceeditendcommand	 {forceEditEndCommand	  ForceEditEndCommand w}
	-foreground		 {foreground		  Foreground	      b}
	-fg			 -foreground
	-fullseparators		 {fullSeparators	  FullSeparators      w}
	-height			 {height		  Height	      w}
	-highlightbackground	 {highlightBackground	  HighlightBackground f}
	-highlightcolor		 {highlightColor	  HighlightColor      f}
	-highlightthickness	 {highlightThickness	  HighlightThickness  f}
	-incrarrowtype		 {incrArrowType		  IncrArrowType	      w}
	-instanttoggle		 {instantToggle		  InstantToggle	      w}
	-labelactivebackground	 {labelActiveBackground	  Foreground	      l}
	-labelactiveforeground	 {labelActiveForeground	  Background	      l}
	-labelbackground	 {labelBackground	  Background	      l}
	-labelbg		 -labelbackground
	-labelborderwidth	 {labelBorderWidth	  BorderWidth	      l}
	-labelbd		 -labelborderwidth
	-labelcommand		 {labelCommand		  LabelCommand	      w}
	-labelcommand2		 {labelCommand2		  LabelCommand2	      w}
	-labeldisabledforeground {labelDisabledForeground DisabledForeground  l}
	-labelfont		 {labelFont		  Font		      l}
	-labelforeground	 {labelForeground	  Foreground	      l}
	-labelfg		 -labelforeground
	-labelheight		 {labelHeight		  Height	      l}
	-labelpady		 {labelPadY		  Pad		      l}
	-labelrelief		 {labelRelief		  Relief	      l}
	-listvariable		 {listVariable		  Variable	      w}
	-movablecolumns	 	 {movableColumns	  MovableColumns      w}
	-movablerows		 {movableRows		  MovableRows	      w}
	-movecolumncursor	 {moveColumnCursor	  MoveColumnCursor    w}
	-movecursor		 {moveCursor		  MoveCursor	      w}
	-populatecommand	 {populateCommand	  PopulateCommand     w}
	-protecttitlecolumns	 {protectTitleColumns	  ProtectTitleColumns w}
	-relief			 {relief		  Relief	      f}
	-resizablecolumns	 {resizableColumns	  ResizableColumns    w}
	-resizecursor		 {resizeCursor		  ResizeCursor	      w}
	-selectbackground	 {selectBackground	  Foreground	      w}
	-selectborderwidth	 {selectBorderWidth	  BorderWidth	      w}
	-selectforeground	 {selectForeground	  Background	      w}
	-selectmode		 {selectMode		  SelectMode	      w}
	-selecttype		 {selectType		  SelectType	      w}
	-setfocus		 {setFocus		  SetFocus	      w}
	-setgrid		 {setGrid		  SetGrid	      w}
	-showarrow		 {showArrow		  ShowArrow	      w}
	-showeditcursor		 {showEditCursor	  ShowEditCursor      w}
	-showhorizseparator	 {showHorizSeparator	  ShowHorizSeparator  w}
	-showlabels		 {showLabels		  ShowLabels	      w}
	-showseparators		 {showSeparators	  ShowSeparators      w}
	-snipstring		 {snipString		  SnipString	      w}
	-sortcommand		 {sortCommand		  SortCommand	      w}
	-spacing		 {spacing		  Spacing	      w}
	-state			 {state			  State		      w}
	-stretch		 {stretch		  Stretch	      w}
	-stripebackground	 {stripeBackground	  Background	      w}
	-stripebg		 -stripebackground
	-stripeforeground	 {stripeForeground	  Foreground	      w}
	-stripefg		 -stripeforeground
	-stripeheight		 {stripeHeight		  StripeHeight	      w}
	-takefocus		 {takeFocus		  TakeFocus	      f}
	-targetcolor		 {targetColor		  TargetColor	      w}
	-tight			 {tight			  Tight		      w}
	-titlecolumns		 {titleColumns	  	  TitleColumns	      w}
	-tooltipaddcommand	 {tooltipAddCommand	  TooltipAddCommand   w}
	-tooltipdelcommand	 {tooltipDelCommand	  TooltipDelCommand   w}
	-treecolumn		 {treeColumn		  TreeColumn	      w}
	-treestyle		 {treeStyle		  TreeStyle	      w}
	-width			 {width			  Width		      w}
	-xscrollcommand		 {xScrollCommand	  ScrollCommand	      w}
	-yscrollcommand		 {yScrollCommand	  ScrollCommand	      w}
    }

    #
    # Extend the elements of the array configSpecs
    #
    extendConfigSpecs 

    variable configOpts [lsort [array names configSpecs]]

    #
    # The array colConfigSpecs is used to handle column configuration options.
    # The names of its elements are the column configuration options for the
    # Tablelist widget class.  The value of an array element is either an alias
    # name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	    }
    #	---------------------------------------------------------------------
    #
    variable colConfigSpecs
    array set colConfigSpecs {
	-align			{align			Align		    }
	-background		{background		Background	    }
	-bg			-background
	-changesnipside		{changeSnipSide		ChangeSnipSide	    }
	-changetitlesnipside	{changeTitleSnipSide	ChangeTitleSnipSide }
	-editable		{editable		Editable	    }
	-editwindow		{editWindow		EditWindow	    }
	-font			{font			Font		    }
	-foreground		{foreground		Foreground	    }
	-fg			-foreground
	-formatcommand		{formatCommand		FormatCommand	    }
	-hide			{hide			Hide		    }
	-labelalign		{labelAlign		Align		    }
	-labelbackground	{labelBackground	Background	    }
	-labelbg		-labelbackground
	-labelborderwidth	{labelBorderWidth	BorderWidth	    }
	-labelbd		-labelborderwidth
	-labelcommand		{labelCommand		LabelCommand	    }
	-labelcommand2		{labelCommand2		LabelCommand2	    }
	-labelfont		{labelFont		Font		    }
	-labelforeground	{labelForeground	Foreground	    }
	-labelfg		-labelforeground
	-labelheight		{labelHeight		Height		    }
	-labelimage		{labelImage		Image		    }
	-labelpady		{labelPadY		Pad		    }
	-labelrelief		{labelRelief		Relief		    }
	-maxwidth		{maxWidth		MaxWidth	    }
	-name			{name			Name		    }
	-resizable		{resizable		Resizable	    }
	-selectbackground	{selectBackground	Foreground	    }
	-selectforeground	{selectForeground	Background	    }
	-showarrow		{showArrow		ShowArrow	    }
	-showlinenumbers	{showLineNumbers	ShowLineNumbers	    }
	-sortcommand		{sortCommand		SortCommand	    }
	-sortmode		{sortMode		SortMode	    }
	-stretchable		{stretchable		Stretchable	    }
	-stripebackground	{stripeBackground	Background	    }
	-stripeforeground	{stripeForeground	Foreground	    }
	-text			{text			Text		    }
	-title			{title			Title		    }
	-valign			{valign			Valign		    }
	-width			{width			Width		    }
	-wrap			{wrap			Wrap		    }
    }

    #
    # Extend some elements of the array colConfigSpecs
    #
    lappend colConfigSpecs(-align)			- left
    lappend colConfigSpecs(-changesnipside)		- 0
    lappend colConfigSpecs(-changetitlesnipside)	- 0
    lappend colConfigSpecs(-editable)			- 0
    lappend colConfigSpecs(-editwindow)			- entry
    lappend colConfigSpecs(-hide)			- 0
    lappend colConfigSpecs(-maxwidth)			- 0
    lappend colConfigSpecs(-resizable)			- 1
    lappend colConfigSpecs(-showarrow)			- 1
    lappend colConfigSpecs(-showlinenumbers)		- 0
    lappend colConfigSpecs(-sortmode)			- ascii
    lappend colConfigSpecs(-stretchable)		- 0
    lappend colConfigSpecs(-valign)			- center
    lappend colConfigSpecs(-width)			- 0
    lappend colConfigSpecs(-wrap)			- 0

    if {$usingTile} {
	unset colConfigSpecs(-labelbackground)
	unset colConfigSpecs(-labelbg)
	unset colConfigSpecs(-labelheight)
    }

    #
    # The array rowConfigSpecs is used to handle row configuration options.
    # The names of its elements are the row configuration options for the
    # Tablelist widget class.  The value of an array element is either an alias
    # name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	}
    #	-----------------------------------------------------------------
    #
    variable rowConfigSpecs
    array set rowConfigSpecs {
	-background		{background		Background	}
	-bg			-background
	-font			{font			Font		}
	-foreground		{foreground		Foreground	}
	-fg			-foreground
	-hide			{hide			Hide		}
	-name			{name			Name		}
	-selectable		{selectable		Selectable	}
	-selectbackground	{selectBackground	Foreground	}
	-selectforeground	{selectForeground	Background	}
	-text			{text			Text		}
    }

    #
    # Check whether the -elide text widget tag option is available
    #
    variable canElide
    variable elide
    if {$::tk_version >= 8.3} {
	set canElide 1
	set elide -elide
    } else {
	set canElide 0
	set elide --
    }

    #
    # Extend some elements of the array rowConfigSpecs
    #
    if {$canElide} {
	lappend rowConfigSpecs(-hide)	- 0
    } else {
	unset rowConfigSpecs(-hide)
    }
    lappend rowConfigSpecs(-selectable)	- 1

    #
    # The array cellConfigSpecs is used to handle cell configuration options.
    # The names of its elements are the cell configuration options for the
    # Tablelist widget class.  The value of an array element is either an alias
    # name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	}
    #	-----------------------------------------------------------------
    #
    variable cellConfigSpecs
    array set cellConfigSpecs {
	-background		{background		Background	}
	-bg			-background
	-editable		{editable		Editable	}
	-editwindow		{editWindow		EditWindow	}
	-font			{font			Font		}
	-foreground		{foreground		Foreground	}
	-fg			-foreground
	-image			{image			Image		}
	-selectbackground	{selectBackground	Foreground	}
	-selectforeground	{selectForeground	Background	}
	-stretchwindow		{stretchWindow		StretchWindow	}
	-text			{text			Text		}
	-valign			{valign			Valign		}
	-window			{window			Window		}
	-windowdestroy		{windowDestroy		WindowDestroy	}
	-windowupdate		{windowUpdate		WindowUpdate	}
    }

    #
    # Extend some elements of the array cellConfigSpecs
    #
    lappend cellConfigSpecs(-editable)		- 0
    lappend cellConfigSpecs(-editwindow)	- entry
    lappend cellConfigSpecs(-stretchwindow)	- 0
    lappend cellConfigSpecs(-valign)		- center

    #
    # Use a list to facilitate the handling of the command options 
    #
    variable cmdOpts [list \
	activate activatecell applysorting attrib bbox bodypath bodytag \
	canceledediting cancelediting cellattrib cellbbox cellcget \
	cellconfigure cellindex cellselection cget childcount childindex \
	childkeys collapse collapseall columnattrib columncget \
	columnconfigure columncount columnindex columnwidth config \
	configcelllist configcells configcolumnlist configcolumns \
	configrowlist configrows configure containing containingcell \
	containingcolumn cornerlabelpath cornerpath curcellselection \
	curselection depth delete deletecolumns descendantcount editcell \
	editinfo editwinpath editwintag entrypath expand expandall \
	expandedkeys fillcolumn findcolumnname findrowname finishediting \
	formatinfo get getcells getcolumns getformatted getformattedcells \
	getformattedcolumns getfullkeys getkeys hasattrib hascellattrib \
	hascolumnattrib hasrowattrib hidetargetmark imagelabelpath index \
	insert insertchild insertchildlist insertchildren insertcolumnlist \
	insertcolumns insertlist iselemsnipped isexpanded istitlesnipped \
	isviewable itemlistvar labelpath labels labeltag move movecolumn \
	nearest nearestcell nearestcolumn noderow parentkey refreshsorting \
	rejectinput resetsortinfo rowattrib rowcget rowconfigure scan \
	searchcolumn see seecell seecolumn selection separatorpath separators \
	showtargetmark size sort sortbycolumn sortbycolumnlist sortcolumn \
	sortcolumnlist sortorder sortorderlist targetmarkpath targetmarkpos \
	togglecolumnhide togglerowhide toplevelkey unsetattrib \
	unsetcellattrib unsetcolumnattrib unsetrowattrib viewablerowcount \
	windowpath xview yview]

    proc restrictCmdOpts {} {
	variable canElide
	if {!$canElide} {
	    variable cmdOpts
	    foreach opt [list collapse collapseall expand expandall \
			 insertchild insertchildlist insertchildren \
			 togglerowhide] {
		set idx [lsearch -exact $cmdOpts $opt]
		set cmdOpts [lreplace $cmdOpts $idx $idx]
	    }
	}
    }
    restrictCmdOpts 

    #
    # Use lists to facilitate the handling of miscellaneous options
    #
    variable activeStyles  [list frame none underline]
    variable alignments    [list left right center]
    variable arrowStyles   [list flat5x3 flat5x4 flat6x4 flat7x4 flat7x5 \
				 flat7x7 flat8x4 flat8x5 flat9x5 flat9x6 \
				 flat11x6 flat15x8 flatAngle7x4 flatAngle7x5 \
				 flatAngle9x5 flatAngle9x6 flatAngle9x7 \
				 flatAngle10x6 flatAngle10x7 flatAngle11x6 \
				 flatAngle15x8 photo7x4 photo7x7 photo9x5 \
				 photo11x6 photo15x8 sunken8x7 sunken10x9 \
				 sunken12x11]
    variable arrowTypes    [list up down]
    variable colWidthOpts  [list -requested -stretched -total]
    variable curSelOpts    [list -all -nonhidden -viewable]
    variable expCollOpts   [list -fully -partly]
    variable findOpts      [list -descend -parent]
    variable gapTypeOpts   [list -any -horizontal -vertical]
    variable scanOpts      [list mark dragto]
    variable searchOpts    [list -all -backwards -check -descend -exact \
				 -formatted -glob -nocase -not -numeric \
				 -parent -regexp -start]
    variable selectionOpts [list anchor clear includes set]
    variable selectTypes   [list row cell]
    variable targetOpts    [list before inside]
    variable sortModes     [list ascii asciinocase command dictionary \
				 integer real]
    variable sortOpts      [list -increasing -decreasing]
    variable sortOrders    [list increasing decreasing]
    variable states	   [list disabled normal]
    variable treeStyles    [list adwaita ambiance aqua baghira bicolor1 \
				 bicolor2 bicolor3 bicolor4 classic1 classic2 \
				 classic3 classic4 dust dustSand gtk \
				 klearlooks mate mint mint2 newWave oxygen1 \
				 oxygen2 phase plain1 plain2 plain3 plain4 \
				 plastik plastique radiance ubuntu ubuntu2 \
				 vistaAero vistaClassic win7Aero win7Classic \
				 win10 winnative winxpBlue winxpOlive \
				 winxpSilver yuyo]
    variable valignments   [list center top bottom]

    proc restrictArrowStyles {} {
	variable pngSupported
	if {!$pngSupported} {
	    variable arrowStyles
	    set idx [lsearch -exact $arrowStyles "photo7x7"]
	    set arrowStyles [lreplace $arrowStyles $idx $idx]
	}
    }
    restrictArrowStyles 

    #
    # The array maxIndentDepths holds the current max.
    # indentation depth for every tree style in use
    #
    variable maxIndentDepths

    #
    # Define the command mapTabs, which returns the string obtained by
    # replacing all \t characters in its argument with \\t, as well as
    # the commands strMap and isInteger, needed because the "string map"
    # and "string is" commands were not available in Tcl 8.0 and 8.1.0
    #
    if {[catch {string map {} ""}] == 0} {
	interp alias {} ::tablelist::mapTabs {} string map {"\t" "\\t"}
	interp alias {} ::tablelist::strMap  {} string map
    } else {
	proc mapTabs str {
	    regsub -all "\t" $str "\\t" str
	    return $str
	}

	proc strMap {charMap str} {
	    foreach {key val} $charMap {
		#
		# We will only need this for noncritical key and str values
		#
		regsub -all $key $str $val str
	    }

	    return $str
	}
    }
    if {[catch {string is integer "0"}] == 0} {
	interp alias {} ::tablelist::isInteger {} string is integer -strict
    } else {
	proc isInteger str {
	    return [expr {[catch {format "%d" $str}] == 0}]
	}
    }

    #
    # Define the command genVirtualEvent, needed because the -data option of the
    # "event generate" command was not available in Tk versions earlier than 8.5
    #
    if {[catch {event generate . <<__>> -data ""}] == 0} {
	proc genVirtualEvent {win event userData} {
	    event generate $win $event -data $userData
	}
    } else {
	proc genVirtualEvent {win event userData} {
	    event generate $win $event
	}
    }

    interp alias {} ::tablelist::configSubCmd \
		 {} ::tablelist::configureSubCmd
    interp alias {} ::tablelist::insertchildSubCmd \
		 {} ::tablelist::insertchildrenSubCmd
}

#
# Private procedure creating the default bindings
# ===============================================
#

#------------------------------------------------------------------------------
# tablelist::createBindings
#
# Creates the default bindings for the binding tags Tablelist, TablelistWindow,
# TablelistKeyNav, TablelistBody, TablelistLabel, TablelistSubLabel,
# TablelistArrow, and TablelistEdit.
#------------------------------------------------------------------------------
proc tablelist::createBindings {} {
    #
    # Define some Tablelist class bindings
    #
    bind Tablelist <KeyPress> continue
    bind Tablelist <FocusIn> {
	tablelist::addActiveTag %W
	if {[string compare [focus -lastfor %W] %W] == 0} {
	    if {[winfo exists [%W editwinpath]]} {
		focus [set tablelist::ns%W::data(editFocus)]
	    } else {
		focus [%W bodypath]
	    }
	}
    }
    bind Tablelist <FocusOut>		{ tablelist::removeActiveTag %W }
    bind Tablelist <<TablelistSelect>>	{ event generate %W <<ListboxSelect>> }
    bind Tablelist <Destroy>		{ tablelist::cleanup %W }
    variable usingTile
    if {$usingTile} {
	bind Tablelist <Activate>	{ tablelist::updateCanvases %W }
	bind Tablelist <Deactivate>	{ tablelist::updateCanvases %W }
	bind Tablelist <<ThemeChanged>>	{
	    after idle [list tablelist::updateConfigSpecs %W]
	}
    }

    #
    # Define some TablelistWindow class bindings
    #
    bind TablelistWindow <Destroy>	{ tablelist::cleanupWindow %W }

    #
    # Define the binding tags TablelistKeyNav and TablelistBody
    #
    mwutil::defineKeyNav Tablelist
    defineTablelistBody 

    #
    # Define the virtual events <<Button3>> and <<ShiftButton3>>
    #
    event add <<Button3>> <Button-3>
    event add <<ShiftButton3>> <Shift-Button-3>
    variable winSys
    if {[string compare $winSys "classic"] == 0 ||
	[string compare $winSys "aqua"] == 0} {
	event add <<Button3>> <Control-Button-1>
	event add <<ShiftButton3>> <Shift-Control-Button-1>
    }

    #
    # Define some mouse bindings for the binding tag TablelistLabel
    #
    bind TablelistLabel <Enter>		  { tablelist::labelEnter  %W %X %Y %x }
    bind TablelistLabel <Motion>	  { tablelist::labelEnter  %W %X %Y %x }
    bind TablelistLabel <Leave>		  { tablelist::labelLeave  %W %X %x %y }
    bind TablelistLabel <Button-1>	  { tablelist::labelB1Down %W %x 0 }
    bind TablelistLabel <Shift-Button-1>  { tablelist::labelB1Down %W %x 1 }
    bind TablelistLabel <B1-Motion>	{ tablelist::labelB1Motion %W %X %x %y }
    bind TablelistLabel <B1-Enter>	{ tablelist::labelB1Enter  %W }
    bind TablelistLabel <B1-Leave>	{ tablelist::labelB1Leave  %W %x %y }
    bind TablelistLabel <ButtonRelease-1> { tablelist::labelB1Up   %W %X}
    bind TablelistLabel <<Button3>>	  { tablelist::labelB3Down %W 0 }
    bind TablelistLabel <<ShiftButton3>>  { tablelist::labelB3Down %W 1 }
    bind TablelistLabel <Double-Button-1>	{ tablelist::labelDblB1 %W %x 0}
    bind TablelistLabel <Shift-Double-Button-1> { tablelist::labelDblB1 %W %x 1}

    #
    # Define the binding tags TablelistSubLabel and TablelistArrow
    #
    defineTablelistSubLabel 
    defineTablelistArrow 

    #
    # Define the binding tag TablelistEdit if the file tablelistEdit.tcl exists
    #
    catch {defineTablelistEdit}
}

#
# Public procedure creating a new tablelist widget
# ================================================
#

#------------------------------------------------------------------------------
# tablelist::tablelist
#
# Creates a new tablelist widget whose name is specified as the first command-
# line argument, and configures it according to the options and their values
# given on the command line.  Returns the name of the newly created widget.
#------------------------------------------------------------------------------
proc tablelist::tablelist args {
    variable usingTile
    variable configSpecs
    variable configOpts
    variable canElide

    if {[llength $args] == 0} {
	mwutil::wrongNumArgs "tablelist pathName ?options?"
    }

    #
    # Create a frame of the class Tablelist
    #
    set win [lindex $args 0]
    if {[catch {
	if {$usingTile} {
	    ttk::frame $win -style Frame$win.TFrame -class Tablelist \
			    -height 0 -width 0 -padding 0
	} else {
	    tk::frame $win -class Tablelist -container 0 -height 0 -width 0
	    catch {$win configure -padx 0 -pady 0}
	}
    } result] != 0} {
	return -code error $result
    }

    #
    # Create a namespace within the current one to hold the data of the widget
    #
    namespace eval ns$win {
	#
	# The folowing array holds various data for this widget
	#
	variable data
	array set data {
	    arrowWidth		 10
	    arrowHeight		 9
	    hasListVar		 0
	    isDisabled		 0
	    ownsFocus		 0
	    charWidth		 1
	    hdrPixels		 0
	    activeRow		 0
	    activeCol		 0
	    anchorRow		 0
	    anchorCol		 0
	    seqNum		-1
	    freeKeyList		 {}
	    keyList		 {}
	    itemList		 {}
	    itemCount		 0
	    lastRow		-1
	    colList		 {}
	    colCount		 0
	    lastCol		-1
	    treeCol		 0
	    gotConfigureEvent	 0
	    rightX		 0
	    btmY		 0
	    rowTagRefCount	 0
	    cellTagRefCount	 0
	    imgCount		 0
	    winCount		 0
	    indentCount		 0
	    afterId		 ""
	    labelClicked	 0
	    arrowColList	 {}
	    sortColList		 {}
	    sortOrder		 ""
	    editKey		 ""
	    editRow		-1
	    editCol		-1
	    canceled		 0
	    fmtKey		 ""
	    fmtRow		-1
	    fmtCol		-1
	    prevCell		 ""
	    prevCol		-1
	    forceAdjust		 0
	    fmtCmdFlagList	 {}
	    hasFmtCmds		 0
	    scrlColOffset	 0
	    cellsToReconfig	 {}
	    nonViewableRowCount	 0
	    viewableRowList	 {-1}
	    hiddenColCount	 0
	    root-row		-1
	    root-parent		 ""
	    root-children	 {}
	    keyToRowMapValid	 1
	    searchStartIdx	 0
	    keyBeingExpanded	 ""
	    destroyIdList	 {}
	    justEntered		 0
	    inEditWin		 0
	}

	#
	# The following array is used to hold arbitrary
	# attributes and their values for this widget
	#
	variable attribs
    }

    #
    # Initialize some further components of data
    #
    upvar ::tablelist::ns${win}::data data
    foreach opt $configOpts {
	set data($opt) [lindex $configSpecs($opt) 3]
    }
    if {$usingTile} {
	setThemeDefaults
	variable themeDefaults
	set data(currentTheme) [getCurrentTheme]
	set data(themeDefaults) [array get themeDefaults]
	if {[string compare $data(currentTheme) "tileqt"] == 0} {
	    set data(widgetStyle) [tileqt_currentThemeName]
	    if {[info exists ::env(KDE_SESSION_VERSION)] &&
		[string length $::env(KDE_SESSION_VERSION)] != 0} {
		set data(colorScheme) [getKdeConfigVal "General" "ColorScheme"]
	    } else {
		set data(colorScheme) [getKdeConfigVal "KDE" "colorScheme"]
	    }
	} else {
	    set data(widgetStyle) ""
	    set data(colorScheme) ""
	}
    }
    set data(-titlecolumns)	0		;# for Tk versions < 8.3
    set data(-treecolumn)	0		;# for Tk versions < 8.3
    set data(-treestyle)	""		;# for Tk versions < 8.3
    set data(colFontList)	[list $data(-font)]
    set data(listVarTraceCmd)	[list tablelist::listVarTrace $win]
    set data(bodyTag)		body$win
    set data(labelTag)		label$win
    set data(editwinTag)	editwin$win
    set data(body)		$win.body
    set data(bodyFr)		$data(body).f
    set data(bodyFrEd)		$data(bodyFr).e
    set data(rowGap)		$data(body).g
    set data(hdr)		$win.hdr
    set data(hdrTxt)		$data(hdr).t
    set data(hdrTxtFr)		$data(hdrTxt).f
    set data(hdrTxtFrCanv)	$data(hdrTxtFr).c
    set data(hdrTxtFrLbl)	$data(hdrTxtFr).l
    set data(hdrFr)		$data(hdr).f
    set data(hdrFrLbl)		$data(hdrFr).l
    set data(colGap)		$data(hdr).g
    set data(lb)		$win.lb
    set data(sep)		$win.sep
    set data(hsep)		$win.hsep

    #
    # Get a unique name for the corner frame (a sibling of the tablelist widget)
    #
    set data(corner) $win-corner
    for {set n 2} {[winfo exists $data(corner)]} {incr n} {
	set data(corner) $data(corner)$n
    }
    set data(cornerLbl) $data(corner).l

    #
    # Create a child hierarchy used to hold the column labels.  The
    # labels will be created as children of the frame data(hdrTxtFr),
    # which is embedded into the text widget data(hdrTxt) (in order
    # to make it scrollable), which in turn fills the frame data(hdr)
    # (whose width and height can be set arbitrarily in pixels).
    #

    set w $data(hdr)			;# header frame
    tk::frame $w -borderwidth 0 -container 0 -height 0 -highlightthickness 0 \
		 -relief flat -takefocus 0 -width 0
    catch {$w configure -padx 0 -pady 0}
    bind $w <Configure> {
	set tablelist::W [winfo parent %W]
	tablelist::stretchColumnsWhenIdle $tablelist::W
	tablelist::updateScrlColOffsetWhenIdle $tablelist::W
	tablelist::updateHScrlbarWhenIdle $tablelist::W
    }
    pack $w -fill x

    set w $data(hdrTxt)			;# text widget within the header frame
    text $w -borderwidth 0 -highlightthickness 0 -insertwidth 0 \
	    -padx 0 -pady 0 -state normal -takefocus 0 -wrap none
    place $w -relheight 1.0 -relwidth 1.0
    bindtags $w [lreplace [bindtags $w] 1 1]
    tk::frame $data(hdrTxtFr) -borderwidth 0 -container 0 -height 0 \
			      -highlightthickness 0 -relief flat \
			      -takefocus 0 -width 0
    catch {$data(hdrTxtFr) configure -padx 0 -pady 0}
    $w window create 1.0 -window $data(hdrTxtFr)

    set w $data(hdrFr)			;# filler frame within the header frame
    tk::frame $w -borderwidth 0 -container 0 -height 0 -highlightthickness 0 \
		 -relief flat -takefocus 0 -width 0
    catch {$w configure -padx 0 -pady 0}
    place $w -relheight 1.0 -relwidth 1.0

    set w $data(hdrFrLbl)		;# label within the filler frame
    set x 0
    if {$usingTile} {
	ttk::label $w -style TablelistHeader.TLabel -image "" \
		      -padding {1 1 1 1} -takefocus 0 -text "" \
		      -textvariable "" -underline -1 -wraplength 0
	if {[string compare [getCurrentTheme] "aqua"] == 0} {
	    set x -1
	}
    } else {
	tk::label $w -bitmap "" -highlightthickness 0 -image "" \
		     -takefocus 0 -text "" -textvariable "" -underline -1 \
		     -wraplength 0
    }
    place $w -x $x -relheight 1.0 -relwidth 1.0

    set w $data(corner)			;# corner frame (outside the tablelist)
    tk::frame $w -borderwidth 0 -container 0 -height 0 -highlightthickness 0 \
		 -relief flat -takefocus 0 -width 0
    catch {$w configure -padx 0 -pady 0}

    set w $data(cornerLbl)		;# label within the corner frame
    if {$usingTile} {
	ttk::label $w -style TablelistHeader.TLabel -image "" \
		      -padding {1 1 1 1} -takefocus 0 -text "" \
		      -textvariable "" -underline -1 -wraplength 0
    } else {
	tk::label $w -bitmap "" -highlightthickness 0 -image "" \
		     -takefocus 0 -text "" -textvariable "" -underline -1 \
		     -wraplength 0
    }
    place $w -relheight 1.0 -relwidth 1.0

    #
    # Create the body text widget within the main frame
    #
    set w $data(body)
    text $w -borderwidth 0 -exportselection 0 -highlightthickness 0 \
	    -insertwidth 0 -padx 0 -pady 0 -state normal -takefocus 0 -wrap none
    catch {$w configure -undo 0};  # because of a text widget issue in Tk 8.6.6
    bind $w <Configure> {
	set tablelist::W [winfo parent %W]
	set tablelist::ns${tablelist::W}::data(gotConfigureEvent) 1
	set tablelist::ns${tablelist::W}::data(rightX) [expr {%w - 1}]
	set tablelist::ns${tablelist::W}::data(btmY) [expr {%h - 1}]
	tablelist::makeColFontAndTagLists $tablelist::W
	tablelist::updateViewWhenIdle $tablelist::W
    }
    pack $w -expand 1 -fill both

    #
    # Modify the list of binding tags of the body text widget
    #
    bindtags $w [list $w $data(bodyTag) TablelistBody [winfo toplevel $w] \
		 TablelistKeyNav all]

    #
    # Create the "stripe", "select", "active", "disabled", "redraw",
    # "hiddenRow", "elidedRow", "hiddenCol", and "elidedCol" tags in the body
    # text widget.  Don't use the built-in "sel" tag because on Windows the
    # selection in a text widget only becomes visible when the window gets
    # the input focus.  DO NOT CHANGE the order of creation of these tags!
    #
    $w tag configure stripe -background "" -foreground ""    ;# will be changed
    $w tag configure select -relief raised
    $w tag configure curRow -borderwidth 1 -relief raised
    $w tag configure active -borderwidth ""		     ;# will be changed
    $w tag configure disabled -foreground ""		     ;# will be changed
    $w tag configure redraw -relief sunken
    if {$canElide} {
	$w tag configure hiddenRow -elide 1	;# used for hiding a row
	$w tag configure elidedRow -elide 1	;# used when collapsing a row
	$w tag configure hiddenCol -elide 1	;# used for hiding a column
	$w tag configure elidedCol -elide 1	;# used for horizontal scrolling
    }
    if {$::tk_version >= 8.5} {
	$w tag configure elidedWin -elide 1	;# used for eliding a window
    }

    #
    # Create two frames used to display a gap between two consecutive
    # rows/columns when moving a row/column interactively
    #
    tk::frame $data(rowGap) -borderwidth 1 -container 0 -highlightthickness 0 \
			    -relief sunken -takefocus 0 -height 4
    tk::frame $data(colGap) -borderwidth 1 -container 0 -highlightthickness 0 \
			    -relief sunken -takefocus 0 -width 4

    #
    # Create an unmanaged listbox child, used to handle the -setgrid option
    #
    listbox $data(lb)

    #
    # Create the bitmaps needed to display the sort ranks
    #
    createSortRankImgs $win

    #
    # Take into account that some scripts start by
    # destroying all children of the root window
    #
    variable helpLabel
    if {![winfo exists $helpLabel]} {
	if {$usingTile} {
	    ttk::label $helpLabel -takefocus 0
	} else {
	    tk::label $helpLabel -takefocus 0
	}
    }

    #
    # Configure the widget according to the command-line
    # arguments and to the available database options
    #
    if {[catch {
	mwutil::configureWidget $win configSpecs tablelist::doConfig \
				tablelist::doCget [lrange $args 1 end] 1
    } result] != 0} {
	destroy $win
	return -code error $result
    }

    #
    # Move the original widget command into the current namespace and
    # create an alias of the original name for a new widget procedure
    #
    rename ::$win $win
    interp alias {} ::$win {} tablelist::tablelistWidgetCmd $win

    #
    # Register a callback to be invoked whenever the PRIMARY
    # selection is owned by the window win and someone
    # attempts to retrieve it as a UTF8_STRING or STRING
    #
    selection handle -type UTF8_STRING $win \
	[list ::tablelist::fetchSelection $win]
    selection handle -type STRING $win \
	[list ::tablelist::fetchSelection $win]

    #
    # Set a trace on the array elements data(activeRow),
    # data(avtiveCol), and data(-selecttype)
    #
    foreach name {activeRow activeCol -selecttype} {
	trace variable data($name) w [list tablelist::activeTrace $win]
    }

    return $win
}

#
# Private procedures implementing the tablelist widget command
# ============================================================
#

#------------------------------------------------------------------------------
# tablelist::tablelistWidgetCmd
#
# Processes the Tcl command corresponding to a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::tablelistWidgetCmd {win args} {
    if {[llength $args] == 0} {
	mwutil::wrongNumArgs "$win option ?arg arg ...?"
    }

    variable cmdOpts
    set cmd [mwutil::fullOpt "option" [lindex $args 0] $cmdOpts]
    return [${cmd}SubCmd $win [lrange $args 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::activateSubCmd
#------------------------------------------------------------------------------
proc tablelist::activateSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win activate index"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0]

    #
    # Adjust the index to fit within the existing viewable items
    #
    adjustRowIndex $win index 1

    set data(activeRow) $index
    return ""
}

#------------------------------------------------------------------------------
# tablelist::activatecellSubCmd
#------------------------------------------------------------------------------
proc tablelist::activatecellSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win activatecell cellIndex"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 0] {}

    #
    # Adjust the row and column indices to fit
    # within the existing viewable elements
    #
    adjustRowIndex $win row 1
    adjustColIndex $win col 1

    set data(activeRow) $row
    set data(activeCol) $col
    return ""
}

#------------------------------------------------------------------------------
# tablelist::applysortingSubCmd
#------------------------------------------------------------------------------
proc tablelist::applysortingSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win applysorting itemList"
    }

    return [sortList $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::attribSubCmd
#------------------------------------------------------------------------------
proc tablelist::attribSubCmd {win argList} {
    return [mwutil::attribSubCmd $win "widget" $argList]
}

#------------------------------------------------------------------------------
# tablelist::bboxSubCmd
#------------------------------------------------------------------------------
proc tablelist::bboxSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win bbox index"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0]

    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set dlineinfo [$w dlineinfo [expr {double($index + 1)}]]
    if {$data(itemCount) == 0 || [llength $dlineinfo] == 0} {
	return {}
    }

    set spacing1 [$w cget -spacing1]
    set spacing3 [$w cget -spacing3]
    foreach {x y width height baselinePos} $dlineinfo {}
    incr height -[expr {$spacing1 + $spacing3}]
    if {$height < 0} {
	set height 0
    }
    return [list [expr {$x + [winfo x $w]}] \
		 [expr {$y + [winfo y $w] + $spacing1}] $width $height]
}

#------------------------------------------------------------------------------
# tablelist::bodypathSubCmd
#------------------------------------------------------------------------------
proc tablelist::bodypathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win bodypath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(body)
}

#------------------------------------------------------------------------------
# tablelist::bodytagSubCmd
#------------------------------------------------------------------------------
proc tablelist::bodytagSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win bodytag"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(bodyTag)
}

#------------------------------------------------------------------------------
# tablelist::cancelededitingSubCmd
#------------------------------------------------------------------------------
proc tablelist::cancelededitingSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win canceledediting"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(canceled)
}

#------------------------------------------------------------------------------
# tablelist::canceleditingSubCmd
#------------------------------------------------------------------------------
proc tablelist::canceleditingSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win cancelediting"
    }

    synchronize $win
    return [doCancelEditing $win]
}

#------------------------------------------------------------------------------
# tablelist::cellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win cellattrib cellIndex ?name? ?value\
			      name value ...?"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::attribSubCmd $win $key,$col [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::cellbboxSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellbboxSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win cellbbox cellIndex"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 0] {}
    upvar ::tablelist::ns${win}::data data
    if {$row < 0 || $row > $data(lastRow) ||
	$col < 0 || $col > $data(lastCol)} {
	return {}
    }

    foreach {x y width height} [bboxSubCmd $win $row] {}
    set w $data(hdrTxtFrLbl)$col
    return [list [expr {[winfo rootx $w] - [winfo rootx $win]}] $y \
		 [winfo width $w] $height]
}

#------------------------------------------------------------------------------
# tablelist::cellcgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellcgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win cellcget cellIndex option"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    variable cellConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] cellConfigSpecs]
    return [doCellCget $row $col $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::cellconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win cellconfigure cellIndex ?option? ?value\
			      option value ...?"
    }

    synchronize $win
    displayItems $win
    variable cellConfigSpecs
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    return [mwutil::configureSubCmd $win cellConfigSpecs \
	    "tablelist::doCellConfig $row $col" \
	    "tablelist::doCellCget $row $col" [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::cellindexSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellindexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win cellindex cellIndex"
    }

    synchronize $win
    return [join [cellIndex $win [lindex $argList 0] 0] ","]
}

#------------------------------------------------------------------------------
# tablelist::cellselectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellselectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2 || $argCount > 3} {
	mwutil::wrongNumArgs \
		"$win cellselection option firstCellIndex lastCellIndex" \
		"$win cellselection option cellIndexList"
    }

    synchronize $win
    displayItems $win
    variable selectionOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $selectionOpts]
    set first [lindex $argList 1]

    switch $opt {
	anchor -
	includes {
	    if {$argCount != 2} {
		mwutil::wrongNumArgs "$win cellselection $opt cellIndex"
	    }
	    foreach {row col} [cellIndex $win $first 0] {}
	    return [cellSelection $win $opt $row $col $row $col]
	}

	clear -
	set {
	    if {$argCount == 2} {
		foreach elem $first {
		    foreach {row col} [cellIndex $win $elem 0] {}
		    cellSelection $win $opt $row $col $row $col
		}
	    } else {
		foreach {firstRow firstCol} [cellIndex $win $first 0] {}
		foreach {lastRow lastCol} \
			[cellIndex $win [lindex $argList 2] 0] {}
		cellSelection $win $opt $firstRow $firstCol $lastRow $lastCol
	    }

	    updateColors $win
	    invokeMotionHandler $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::cgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::cgetSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win cget option"
    }

    #
    # Return the value of the specified configuration option
    #
    variable configSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 0] configSpecs]
    return [doCget $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::childcountSubCmd
#------------------------------------------------------------------------------
proc tablelist::childcountSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win childcount nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    upvar ::tablelist::ns${win}::data data
    return [llength $data($key-children)]
}

#------------------------------------------------------------------------------
# tablelist::childindexSubCmd
#------------------------------------------------------------------------------
proc tablelist::childindexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win childindex index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set parentKey $data($key-parent)
    return [lsearch -exact $data($parentKey-children) $key]
}

#------------------------------------------------------------------------------
# tablelist::childkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::childkeysSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win childkeys nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    upvar ::tablelist::ns${win}::data data
    return $data($key-children)
}

#------------------------------------------------------------------------------
# tablelist::collapseSubCmd
#------------------------------------------------------------------------------
proc tablelist::collapseSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win collapse index ?-fully|-partly?"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0 1]

    if {$argCount == 1} {
	set fullCollapsion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $expCollOpts]
	set fullCollapsion [expr {[string compare $opt "-fully"] == 0}]
    }

    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    set col $data(treeCol)
    if {![info exists data($key,$col-indent)]} {
	return ""
    }

    if {[string length $data(-collapsecommand)] != 0} {
	uplevel #0 $data(-collapsecommand) [list $win $index]
    }

    #
    # Set the indentation image to the collapsed one
    #
    set data($key,$col-indent) [strMap \
	{"indented" "collapsed" "expanded" "collapsed"} $data($key,$col-indent)]
    if {[winfo exists $data(body).ind_$key,$col]} {
	$data(body).ind_$key,$col configure -image $data($key,$col-indent)
    }

    if {[llength $data($key-children)] == 0} {
	return ""
    }

    #
    # Elide the descendants of this item
    #
    set fromRow [expr {$index + 1}]
    set toRow [nodeRow $win $key end]
    for {set row $fromRow} {$row < $toRow} {incr row} {
	doRowConfig $row $win -elide 1

	if {$fullCollapsion} {
	    set descKey [lindex $data(keyList) $row]
	    if {[llength $data($descKey-children)] != 0} {
		if {[string length $data(-collapsecommand)] != 0} {
		    uplevel #0 $data(-collapsecommand) \
			[list $win [keyToRow $win $descKey]]
		}

		#
		# Change the descendant's indentation image
		# from the expanded to the collapsed one
		#
		set data($descKey,$col-indent) [strMap \
		    {"expanded" "collapsed"} $data($descKey,$col-indent)]
		if {[winfo exists $data(body).ind_$descKey,$col]} {
		    $data(body).ind_$descKey,$col configure -image \
			$data($descKey,$col-indent)
		}
	    }
	}
    }

    set callerProc [lindex [info level -1] 0]
    if {![string match "collapse*SubCmd" $callerProc]} {
	#
	# Destroy the label and messsage widgets
	# embedded into the descendants just elided
	#
	set widgets {}
	set fromTextIdx [expr {double($fromRow + 1)}]
	set toTextIdx [expr {double($toRow + 1)}]
	foreach {dummy path textIdx} \
		[$data(body) dump -window $fromTextIdx $toTextIdx] {
	    if {[string length $path] != 0} {
		set class [winfo class $path]
		if {[string compare $class "Label"] == 0 ||
		    [string compare $class "Message"] == 0} {
		    lappend widgets $path
		}
	    }
	}
	set destroyId [after 300 [list tablelist::destroyWidgets $win]]
	lappend data(destroyIdList) $destroyId
	set data(widgets-$destroyId) $widgets

	adjustRowIndex $win data(anchorRow) 1

	set activeRow $data(activeRow)
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow

	makeStripes $win
	adjustElidedText $win
	redisplayVisibleItems $win
	updateColors $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::collapseallSubCmd
#------------------------------------------------------------------------------
proc tablelist::collapseallSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win collapseall ?-fully|-partly?"
    }

    if {$argCount == 0} {
	set fullCollapsion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $expCollOpts]
	set fullCollapsion [expr {[string compare $opt "-fully"] == 0}]
    }

    synchronize $win
    displayItems $win

    upvar ::tablelist::ns${win}::data data
    set col $data(treeCol)

    if {[winfo viewable $win]} {
	purgeWidgets $win
	update idletasks
	if {![array exists ::tablelist::ns${win}::data]} {
	    return ""
	}
    }

    set childIdx 0
    set childCount [llength $data(root-children)]
    foreach key $data(root-children) {
	if {[llength $data($key-children)] == 0} {
	    incr childIdx
	    continue
	}

	if {[string length $data(-collapsecommand)] != 0} {
	    uplevel #0 $data(-collapsecommand) [list $win [keyToRow $win $key]]
	}

	#
	# Change the indentation image from the expanded to the collapsed one
	#
	set data($key,$col-indent) \
	    [strMap {"expanded" "collapsed"} $data($key,$col-indent)]
	if {[winfo exists $data(body).ind_$key,$col]} {
	    $data(body).ind_$key,$col configure -image $data($key,$col-indent)
	}

	#
	# Elide the descendants of this item
	#
	incr childIdx
	if {[llength $data($key-children)] != 0} {
	    set fromRow [expr {[keyToRow $win $key] + 1}]
	    if {$childIdx < $childCount} {
		set nextChildKey [lindex $data(root-children) $childIdx]
		set toRow [keyToRow $win $nextChildKey]
	    } else {
		set toRow $data(itemCount)
	    }
	    for {set row $fromRow} {$row < $toRow} {incr row} {
		doRowConfig $row $win -elide 1

		if {$fullCollapsion} {
		    set descKey [lindex $data(keyList) $row]
		    if {[llength $data($descKey-children)] != 0} {
			if {[string length $data(-collapsecommand)] != 0} {
			    uplevel #0 $data(-collapsecommand) \
				[list $win [keyToRow $win $descKey]]
			}

			#
			# Change the descendant's indentation image
			# from the expanded to the collapsed one
			#
			set data($descKey,$col-indent) \
			    [strMap {"expanded" "collapsed"} \
				    $data($descKey,$col-indent)]
			if {[winfo exists $data(body).ind_$descKey,$col]} {
			    $data(body).ind_$descKey,$col configure -image \
				$data($descKey,$col-indent)
			}
		    }
		}
	    }

	    #
	    # Destroy the label and messsage widgets
	    # embedded into the descendants just elided
	    #
	    set widgets {}
	    set fromTextIdx [expr {double($fromRow + 1)}]
	    set toTextIdx [expr {double($toRow + 1)}]
	    foreach {dummy path textIdx} \
		    [$data(body) dump -window $fromTextIdx $toTextIdx] {
		if {[string length $path] != 0} {
		    set class [winfo class $path]
		    if {[string compare $class "Label"] == 0 ||
			[string compare $class "Message"] == 0} {
			lappend widgets $path
		    }
		}
	    }
	    set destroyId [after 300 [list tablelist::destroyWidgets $win]]
	    lappend data(destroyIdList) $destroyId
	    set data(widgets-$destroyId) $widgets
	}
    }

    adjustRowIndex $win data(anchorRow) 1

    set activeRow $data(activeRow)
    adjustRowIndex $win activeRow 1
    set data(activeRow) $activeRow

    makeStripes $win
    adjustElidedText $win
    redisplayVisibleItems $win
    updateColors $win
    adjustSepsWhenIdle $win
    updateVScrlbarWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::columnattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win columnattrib columnIndex ?name? ?value\
			      name value ...?"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::attribSubCmd $win $col [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::columncgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::columncgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win columncget columnIndex option"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    variable colConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] colConfigSpecs]
    return [doColCget $col $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::columnconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win columnconfigure columnIndex ?option? ?value\
			      option value ...?"
    }

    synchronize $win
    displayItems $win
    variable colConfigSpecs
    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::configureSubCmd $win colConfigSpecs \
	    "tablelist::doColConfig $col" "tablelist::doColCget $col" \
	    [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::columncountSubCmd
#------------------------------------------------------------------------------
proc tablelist::columncountSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win columncount"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(colCount)
}

#------------------------------------------------------------------------------
# tablelist::columnindexSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnindexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win columnindex columnIndex"
    }

    return [colIndex $win [lindex $argList 0] 0]
}

#------------------------------------------------------------------------------
# tablelist::columnwidthSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnwidthSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win columnwidth columnIndex\
			      ?-requested|-stretched|-total?"
    }

    synchronize $win
    set col [colIndex $win [lindex $argList 0] 1]
    if {$argCount == 1} {
	set opt -requested
    } else {
	variable colWidthOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $colWidthOpts]
    }

    return [colWidth $win $col $opt]
}

#------------------------------------------------------------------------------
# tablelist::configcelllistSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcelllistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win configcelllist cellConfigSpecList"
    }

    return [configcellsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::configcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcellsSubCmd {win argList} {
    synchronize $win
    displayItems $win
    variable cellConfigSpecs

    set argCount [llength $argList]
    foreach {cell opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$cell\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	foreach {row col} [cellIndex $win $cell 1] {}
	mwutil::configureWidget $win cellConfigSpecs \
		"tablelist::doCellConfig $row $col" \
		"tablelist::doCellCget $row $col" [list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::configcolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcolumnlistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win configcolumnlist columnConfigSpecList"
    }

    return [configcolumnsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::configcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcolumnsSubCmd {win argList} {
    synchronize $win
    displayItems $win
    variable colConfigSpecs

    set argCount [llength $argList]
    foreach {col opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$col\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	set col [colIndex $win $col 1]
	mwutil::configureWidget $win colConfigSpecs \
		"tablelist::doColConfig $col" "tablelist::doColCget $col" \
		[list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::configrowlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::configrowlistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win configrowlist rowConfigSpecList"
    }

    return [configrowsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::configrowsSubCmd
#------------------------------------------------------------------------------
proc tablelist::configrowsSubCmd {win argList} {
    synchronize $win
    displayItems $win
    variable rowConfigSpecs

    set argCount [llength $argList]
    foreach {rowSpec opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$rowSpec\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	set row [rowIndex $win $rowSpec 0 1]
	mwutil::configureWidget $win rowConfigSpecs \
		"tablelist::doRowConfig $row" "tablelist::doRowCget $row" \
		[list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::configureSubCmd
#------------------------------------------------------------------------------
proc tablelist::configureSubCmd {win argList} {
    variable configSpecs
    return [mwutil::configureSubCmd $win configSpecs tablelist::doConfig \
	    tablelist::doCget $argList]
}

#------------------------------------------------------------------------------
# tablelist::containingSubCmd
#------------------------------------------------------------------------------
proc tablelist::containingSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win containing y"
    }

    set y [format "%d" [lindex $argList 0]]
    synchronize $win
    displayItems $win
    return [containingRow $win $y]
}

#------------------------------------------------------------------------------
# tablelist::containingcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::containingcellSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win containingcell x y"
    }

    set x [format "%d" [lindex $argList 0]]
    set y [format "%d" [lindex $argList 1]]
    synchronize $win
    displayItems $win
    return [containingRow $win $y],[containingCol $win $x]
}

#------------------------------------------------------------------------------
# tablelist::containingcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::containingcolumnSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win containingcolumn x"
    }

    set x [format "%d" [lindex $argList 0]]
    synchronize $win
    displayItems $win
    return [containingCol $win $x]
}

#------------------------------------------------------------------------------
# tablelist::cornerlabelpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::cornerlabelpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win cornerlabelpath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(cornerLbl)
}

#------------------------------------------------------------------------------
# tablelist::cornerpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::cornerpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win cornerpath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(corner)
}

#------------------------------------------------------------------------------
# tablelist::curcellselectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::curcellselectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win curcellselection\
			      ?-all|-nonhidden||-viewable?"
    }

    if {$argCount == 0} {
	set constraint 0
    } else {
	variable curSelOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $curSelOpts]
	set constraint [lsearch -exact $curSelOpts $opt]
    }
    

    synchronize $win
    displayItems $win
    return [curCellSelection $win 0 $constraint]
}

#------------------------------------------------------------------------------
# tablelist::curselectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::curselectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win curselection\
			      ?-all|-nonhidden||-viewable?"
    }

    if {$argCount == 0} {
	set constraint 0
    } else {
	variable curSelOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $curSelOpts]
	set constraint [lsearch -exact $curSelOpts $opt]
    }

    synchronize $win
    displayItems $win
    return [curSelection $win $constraint]
}

#------------------------------------------------------------------------------
# tablelist::deleteSubCmd
#------------------------------------------------------------------------------
proc tablelist::deleteSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win delete firstIndex lastIndex" \
			     "$win delete indexList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    if {$argCount == 1} {
	if {[llength $first] == 1} {			;# just to save time
	    set index [rowIndex $win [lindex $first 0] 0]
	    return [deleteRows $win $index $index $data(hasListVar)]
	} elseif {$data(itemCount) == 0} {		;# no items present
	    return ""
	} else {					;# a bit more work
	    #
	    # Sort the numerical equivalents of the
	    # specified indices in decreasing order
	    #
	    set indexList {}
	    foreach elem $first {
		set index [rowIndex $win $elem 0]
		if {$index < 0} {
		    set index 0
		} elseif {$index > $data(lastRow)} {
		    set index $data(lastRow)
		}
		lappend indexList $index
	    }
	    set indexList [lsort -integer -decreasing $indexList]

	    #
	    # Traverse the sorted index list and ignore any duplicates
	    #
	    set prevIndex -1
	    foreach index $indexList {
		if {$index != $prevIndex} {
		    deleteRows $win $index $index $data(hasListVar)
		    set prevIndex $index
		}
	    }
	    return ""
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	return [deleteRows $win $first $last $data(hasListVar)]
    }
}

#------------------------------------------------------------------------------
# tablelist::deletecolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::deletecolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win deletecolumns firstColumnIndex lastColumnIndex" \
		"$win deletecolumns columnIndexList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    if {$argCount == 1} {
	if {[llength $first] == 1} {			;# just to save time
	    set col [colIndex $win [lindex $first 0] 1]
	    set selCells [curCellSelection $win]
	    deleteCols $win $col $col selCells
	    redisplay $win 0 $selCells
	} elseif {$data(colCount) == 0} {		;# no columns present
	    return ""
	} else {					;# a bit more work
	    #
	    # Sort the numerical equivalents of the
	    # specified column indices in decreasing order
	    #
	    set colList {}
	    foreach elem $first {
		lappend colList [colIndex $win $elem 1]
	    }
	    set colList [lsort -integer -decreasing $colList]

	    #
	    # Traverse the sorted column index list and ignore any duplicates
	    #
	    set selCells [curCellSelection $win]
	    set deleted 0
	    set prevCol -1
	    foreach col $colList {
		if {$col != $prevCol} {
		    deleteCols $win $col $col selCells
		    set deleted 1
		    set prevCol $col
		}
	    }
	    if {$deleted} {
		redisplay $win 0 $selCells
	    }
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]
	if {$first <= $last} {
	    set selCells [curCellSelection $win]
	    deleteCols $win $first $last selCells
	    redisplay $win 0 $selCells
	}
    }

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::depthSubCmd
#------------------------------------------------------------------------------
proc tablelist::depthSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win depth nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    return [depth $win $key]
}

#------------------------------------------------------------------------------
# tablelist::descendantcountSubCmd
#------------------------------------------------------------------------------
proc tablelist::descendantcountSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win descendantcount nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    return [descCount $win $key]
}

#------------------------------------------------------------------------------
# tablelist::editcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::editcellSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win editcell cellIndex"
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    return [doEditCell $win $row $col 0]
}

#------------------------------------------------------------------------------
# tablelist::editinfoSubCmd
#------------------------------------------------------------------------------
proc tablelist::editinfoSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win editinfo"
    }

    upvar ::tablelist::ns${win}::data data
    return [list $data(editKey) $data(editRow) $data(editCol)]
}

#------------------------------------------------------------------------------
# tablelist::editwinpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::editwinpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win editwinpath"
    }

    upvar ::tablelist::ns${win}::data data
    if {[winfo exists $data(bodyFrEd)]} {
	return $data(bodyFrEd)
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::editwintagSubCmd
#------------------------------------------------------------------------------
proc tablelist::editwintagSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win editwintag"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(editwinTag)
}

#------------------------------------------------------------------------------
# tablelist::entrypathSubCmd
#------------------------------------------------------------------------------
proc tablelist::entrypathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win entrypath"
    }

    upvar ::tablelist::ns${win}::data data
    if {[winfo exists $data(bodyFrEd)]} {
	set class [winfo class $data(bodyFrEd)]
	if {[regexp {^(Mentry|T?Checkbutton|T?Menubutton)$} $class]} {
	    return ""
	} else {
	    return $data(editFocus)
	}
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::expandSubCmd
#------------------------------------------------------------------------------
proc tablelist::expandSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win expand index ?-fully|-partly?"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0 1]

    if {$argCount == 1} {
	set fullExpansion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $expCollOpts]
	set fullExpansion [expr {[string compare $opt "-fully"] == 0}]
    }

    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    set col $data(treeCol)
    if {![info exists data($key,$col-indent)] ||
	[string match "*indented*" $data($key,$col-indent)]} {
	return ""
    }

    set callerProc [lindex [info level -1] 0]
    if {[string compare $callerProc "doRowConfig"] != 0 &&
	[string length $data(-expandcommand)] != 0} {
	set data(keyBeingExpanded) $key
	uplevel #0 $data(-expandcommand) [list $win $index]
	set data(keyBeingExpanded) ""
    }

    #
    # Set the indentation image to the indented or expanded one
    #
    set childCount [llength $data($key-children)]
    set state [expr {($childCount == 0) ? "indented" : "expanded"}]
    set data($key,$col-indent) [strMap \
	[list "collapsed" $state "expanded" $state] $data($key,$col-indent)]
    if {[string compare $state "indented"] == 0} {
	set data($key,$col-indent) [strMap \
	    {"Act" "" "Sel" ""} $data($key,$col-indent)]
    }
    if {[winfo exists $data(body).ind_$key,$col]} {
	$data(body).ind_$key,$col configure -image $data($key,$col-indent)
    }

    #
    # Unelide the children if appropriate and
    # invoke this procedure recursively on them
    #
    set isViewable [expr {![info exists data($key-elide)] &&
			  ![info exists data($key-hide)]}]
    foreach childKey $data($key-children) {
	set childRow [keyToRow $win $childKey]
	if {$isViewable} {
	    doRowConfig $childRow $win -elide 0
	}
	if {$fullExpansion} {
	    expandSubCmd $win [list $childRow -fully]
	} elseif {[string match "*expanded*" $data($childKey,$col-indent)]} {
	    expandSubCmd $win [list $childRow -partly]
	}
    }

    if {![string match "expand*SubCmd" $callerProc]} {
	makeStripes $win
	adjustElidedText $win
	redisplayVisibleItems $win
	updateColors $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::expandallSubCmd
#------------------------------------------------------------------------------
proc tablelist::expandallSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win expandall ?-fully|-partly?"
    }

    if {$argCount == 0} {
	set fullExpansion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $expCollOpts]
	set fullExpansion [expr {[string compare $opt "-fully"] == 0}]
    }

    synchronize $win
    displayItems $win

    upvar ::tablelist::ns${win}::data data
    set col $data(treeCol)

    foreach key $data(root-children) {
	if {![info exists data($key,$col-indent)] ||
	    [string match "*indented*" $data($key,$col-indent)]} {
	    continue
	}

	if {[string length $data(-expandcommand)] != 0} {
	    set data(keyBeingExpanded) $key
	    uplevel #0 $data(-expandcommand) [list $win [keyToRow $win $key]]
	    set data(keyBeingExpanded) ""
	}

	#
	# Set the indentation image to the indented or expanded one
	#
	set childCount [llength $data($key-children)]
	set state [expr {($childCount == 0) ? "indented" : "expanded"}]
	set data($key,$col-indent) [strMap \
	    [list "collapsed" $state "expanded" $state] $data($key,$col-indent)]
	if {[string compare $state "indented"] == 0} {
	    set data($key,$col-indent) [strMap \
		{"Act" "" "Sel" ""} $data($key,$col-indent)]
	}
	if {[winfo exists $data(body).ind_$key,$col]} {
	    $data(body).ind_$key,$col configure -image $data($key,$col-indent)
	}

	#
	# Unelide the children and invoke expandSubCmd on them
	#
	foreach childKey $data($key-children) {
	    set childRow [keyToRow $win $childKey]
	    doRowConfig $childRow $win -elide 0
	    if {$fullExpansion} {
		expandSubCmd $win [list $childRow -fully]
	    } elseif {[string match "*expanded*" \
		       $data($childKey,$col-indent)]} {
		expandSubCmd $win [list $childRow -partly]
	    }
	}
    }

    makeStripes $win
    adjustElidedText $win
    redisplayVisibleItems $win
    updateColors $win
    adjustSepsWhenIdle $win
    updateVScrlbarWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::expandedkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::expandedkeysSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win expandedkeys"
    }

    upvar ::tablelist::ns${win}::data data
    set result {}
    foreach name [array names data "*,$data(treeCol)-indent"] {
	if {[string match "tablelist_*_expanded*Img*" $data($name)]} {
	    set commaPos [string first "," $name]
	    lappend result [string range $name 0 [expr {$commaPos - 1}]]
	}
    }
    return $result
}

#------------------------------------------------------------------------------
# tablelist::fillcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::fillcolumnSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win fillcolumn columnIndex text"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set colIdx [colIndex $win [lindex $argList 0] 1]
    set text [lindex $argList 1]

    #
    # Update the item list
    #
    set newItemList {}
    foreach item $data(itemList) {
	set item [lreplace $item $colIdx $colIdx $text]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Adjust the columns and make sure the specified
    # column will be redisplayed at idle time
    #
    adjustColumns $win $colIdx 1
    redisplayColWhenIdle $win $colIdx
    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::findcolumnnameSubCmd
#------------------------------------------------------------------------------
proc tablelist::findcolumnnameSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win findcolumnname name"
    }

    set name [lindex $argList 0]
    set nameIsEmpty [expr {[string length $name] == 0}]

    upvar ::tablelist::ns${win}::data data
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set hasName [info exists data($col-name)]
	if {($hasName && [string compare $name $data($col-name)] == 0) ||
	    (!$hasName && $nameIsEmpty)} {
	    return $col
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::findrownameSubCmd
#------------------------------------------------------------------------------
proc tablelist::findrownameSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1} {
	mwutil::wrongNumArgs "$win findrowname name ?-descend?\
			      ?-parent nodeIndex?"
    }

    synchronize $win
    set name [lindex $argList 0]
    set nameIsEmpty [expr {[string length $name] == 0}]

    #
    # Initialize some processing parameters
    #
    set parentKey root
    set descend 0						;# boolean

    #
    # Parse the argument list
    #
    variable findOpts
    for {set n 1} {$n < $argCount} {incr n} {
	set arg [lindex $argList $n]
	set opt [mwutil::fullOpt "option" $arg $findOpts]
	switch -- $opt {
	    -descend { set descend 1 }
	    -parent {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set parentKey [nodeIndexToKey $win [lindex $argList $n]]
	    }
	}
    }

    upvar ::tablelist::ns${win}::data data
    set childCount [llength $data($parentKey-children)]
    if {$childCount == 0} {
	return -1
    }

    if {$descend} {
	set fromChildKey [lindex $data($parentKey-children) 0]
	set fromRow [keyToRow $win $fromChildKey]
	set toRow [nodeRow $win $parentKey end]
	for {set row $fromRow} {$row < $toRow} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set hasName [info exists data($key-name)]
	    if {($hasName && [string compare $name $data($key-name)] == 0) ||
		(!$hasName && $nameIsEmpty)} {
		return $row
	    }
	}
    } else {
	for {set childIdx 0} {$childIdx < $childCount} {incr childIdx} {
	    set key [lindex $data($parentKey-children) $childIdx]
	    set hasName [info exists data($key-name)]
	    if {($hasName && [string compare $name $data($key-name)] == 0) ||
		(!$hasName && $nameIsEmpty)} {
		return [keyToRow $win $key]
	    }
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::finisheditingSubCmd
#------------------------------------------------------------------------------
proc tablelist::finisheditingSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win finishediting"
    }

    synchronize $win
    return [doFinishEditing $win]
}

#------------------------------------------------------------------------------
# tablelist::formatinfoSubCmd
#------------------------------------------------------------------------------
proc tablelist::formatinfoSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win formatinfo"
    }

    upvar ::tablelist::ns${win}::data data
    return [list $data(fmtKey) $data(fmtRow) $data(fmtCol)]
}

#------------------------------------------------------------------------------
# tablelist::getSubCmd
#------------------------------------------------------------------------------
proc tablelist::getSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win get firstIndex lastIndex" \
			     "$win get indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified items from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		set item [lindex $data(itemList) $row]
		lappend result [lrange $item 0 $data(lastCol)]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	foreach item [lrange $data(itemList) $first $last] {
	    lappend result [lrange $item 0 $data(lastCol)]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getcellsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win getcells firstCellIndex lastCellIndex" \
			     "$win getcells cellIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified elements from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    foreach {row col} [cellIndex $win $elem 1] {}
	    lappend result [lindex [lindex $data(itemList) $row] $col]
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	foreach {firstRow firstCol} [cellIndex $win $first 1] {}
	foreach {lastRow lastCol} [cellIndex $win [lindex $argList 1] 1] {}

	foreach item [lrange $data(itemList) $firstRow $lastRow] {
	    foreach elem [lrange $item $firstCol $lastCol] {
		lappend result $elem
	    }
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getcolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getcolumns firstColumnIndex lastColumnIndex" \
		"$win getcolumns columnIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified columns from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set colResult {}
	    foreach item $data(itemList) {
		lappend colResult [lindex $item $col]
	    }
	    lappend result $colResult
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set colResult {}
	    foreach item $data(itemList) {
		lappend colResult [lindex $item $col]
	    }
	    lappend result $colResult
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getformattedSubCmd
#------------------------------------------------------------------------------
proc tablelist::getformattedSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win getformatted firstIndex lastIndex" \
			     "$win getformatted indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified items from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		set item [lindex $data(itemList) $row]
		set key [lindex $item end]
		set item [lrange $item 0 $data(lastCol)]
		lappend result [formatItem $win $key $row $item]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	set row $first
	foreach item [lrange $data(itemList) $first $last] {
	    set key [lindex $item end]
	    set item [lrange $item 0 $data(lastCol)]
	    lappend result [formatItem $win $key $row $item]
	    incr row
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getformattedcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getformattedcellsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getformattedcells firstCellIndex lastCellIndex" \
		"$win getformattedcells cellIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified elements from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    foreach {row col} [cellIndex $win $elem 1] {}
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    lappend result $text
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	foreach {firstRow firstCol} [cellIndex $win $first 1] {}
	foreach {lastRow lastCol} [cellIndex $win [lindex $argList 1] 1] {}

	set row $firstRow
	foreach item [lrange $data(itemList) $firstRow $lastRow] {
	    set key [lindex $item end]
	    set col $firstCol
	    foreach text [lrange $item $firstCol $lastCol] {
		if {[lindex $data(fmtCmdFlagList) $col]} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend result $text
		incr col
	    }
	    incr row
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getformattedcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getformattedcolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getformattedcolumns firstColumnIndex lastColumnIndex" \
		"$win getformattedcolumns columnIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified columns from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    set colResult {}
	    set row 0
	    foreach item $data(itemList) {
		set key [lindex $item end]
		set text [lindex $item $col]
		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend colResult $text
		incr row
	    }
	    lappend result $colResult
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    set colResult {}
	    set row 0
	    foreach item $data(itemList) {
		set key [lindex $item end]
		set text [lindex $item $col]
		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend colResult $text
		incr row
	    }
	    lappend result $colResult
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getfullkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::getfullkeysSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win getfullkeys firstIndex lastIndex" \
			     "$win getfullkeys indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified keys from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		lappend result [lindex [lindex $data(itemList) $row] end]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	foreach item [lrange $data(itemList) $first $last] {
	    lappend result [lindex $item end]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::getkeysSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win getkeys firstIndex lastIndex" \
			     "$win getkeys indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified keys from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		set item [lindex $data(itemList) $row]
		lappend result [string range [lindex $item end] 1 end]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	foreach item [lrange $data(itemList) $first $last] {
	    lappend result [string range [lindex $item end] 1 end]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::hasattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hasattribSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win hasattrib name"
    }

    return [mwutil::hasattribSubCmd $win "widget" [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::hascellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hascellattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win hascellattrib cellIndex name"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::hasattribSubCmd $win $key,$col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::hascolumnattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hascolumnattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win hascolumnattrib columnIndex name"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::hasattribSubCmd $win $col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::hasrowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hasrowattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win hasrowattrib index name"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::hasattribSubCmd $win $key [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::hidetargetmarkSubCmd
#------------------------------------------------------------------------------
proc tablelist::hidetargetmarkSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win hidetargetmark"
    }

    upvar ::tablelist::ns${win}::data data
    place forget $data(rowGap)
    return ""
}

#------------------------------------------------------------------------------
# tablelist::imagelabelpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::imagelabelpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win imagelabelpath cellIndex"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set w $data(body).img_$key,$col
    if {[winfo exists $w]} {
	return $w
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::indexSubCmd
#------------------------------------------------------------------------------
proc tablelist::indexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win index index"
    }

    synchronize $win
    return [rowIndex $win [lindex $argList 0] 1]
}

#------------------------------------------------------------------------------
# tablelist::insertSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win insert index ?item item ...?"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    set index [rowIndex $win [lindex $argList 0] 1]
    return [insertRows $win $index [lrange $argList 1 end] \
	    $data(hasListVar) root $index]
}

#------------------------------------------------------------------------------
# tablelist::insertchildlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertchildlistSubCmd {win argList} {
    if {[llength $argList] != 3} {
	mwutil::wrongNumArgs "$win insertchildlist parentNodeIndex childIndex\
			      itemList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    set parentKey [nodeIndexToKey $win [lindex $argList 0]]
    set childIdx [lindex $argList 1]
    set listIdx [nodeRow $win $parentKey $childIdx]
    set itemList [lindex $argList 2]
    set result [insertRows $win $listIdx $itemList $data(hasListVar) \
		$parentKey $childIdx]

    if {$data(colCount) == 0} {
	return $result
    }

    displayItems $win
    set treeCol $data(treeCol)
    set treeStyle $data(-treestyle)

    #
    # Mark the parent item as expanded if it was just indented
    #
    set depth [depth $win $parentKey]
    if {[info exists data($parentKey,$treeCol-indent)] &&
	[string compare $data($parentKey,$treeCol-indent) \
	 tablelist_${treeStyle}_indentedImg$depth] == 0} {
	set data($parentKey,$treeCol-indent) \
	    tablelist_${treeStyle}_expandedImg$depth
	if {[winfo exists $data(body).ind_$parentKey,$treeCol]} {
	    $data(body).ind_$parentKey,$treeCol configure -image \
		$data($parentKey,$treeCol-indent)
	}
    }

    #
    # Elide the new items if the parent is collapsed or non-viewable
    #
    set itemCount [llength $itemList]
    if {[string compare $parentKey $data(keyBeingExpanded)] != 0 &&
	(([info exists data($parentKey,$treeCol-indent)] && \
	  [string compare $data($parentKey,$treeCol-indent) \
	   tablelist_${treeStyle}_collapsedImg$depth] == 0) || \
	 [info exists data($parentKey-elide)] || \
	 [info exists data($parentKey-hide)])} {
	for {set n 0; set row $listIdx} {$n < $itemCount} {incr n; incr row} {
	    doRowConfig $row $win -elide 1
	}
    }

    #
    # Mark the new items as indented
    #
    incr depth
    variable maxIndentDepths
    if {$depth > $maxIndentDepths($treeStyle)} {
	createTreeImgs $treeStyle $depth
	set maxIndentDepths($treeStyle) $depth
    }
    for {set n 0; set row $listIdx} {$n < $itemCount} {incr n; incr row} {
	doCellConfig $row $treeCol $win -indent \
		     tablelist_${treeStyle}_indentedImg$depth
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::insertchildrenSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertchildrenSubCmd {win argList} {
    if {[llength $argList] < 2} {
	mwutil::wrongNumArgs "$win insertchildren parentNodeIndex childIndex\
			      ?item item ...?"
    }

    return [insertchildlistSubCmd $win [list [lindex $argList 0] \
	    [lindex $argList 1] [lrange $argList 2 end]]]
}

#------------------------------------------------------------------------------
# tablelist::insertcolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertcolumnlistSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win insertcolumnlist columnIndex columnList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set arg0 [lindex $argList 0]
    if {[string first $arg0 "end"] == 0 || $arg0 == $data(colCount)} {
	set col $data(colCount)
    } else {
	set col [colIndex $win $arg0 1]
    }

    return [insertCols $win $col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::insertcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertcolumnsSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win insertcolumns columnIndex\
		?width title ?alignment? width title ?alignment? ...?"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set arg0 [lindex $argList 0]
    if {[string first $arg0 "end"] == 0 || $arg0 == $data(colCount)} {
	set col $data(colCount)
    } else {
	set col [colIndex $win $arg0 1]
    }

    return [insertCols $win $col [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::insertlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertlistSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win insertlist index itemList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    set index [rowIndex $win [lindex $argList 0] 1]
    return [insertRows $win $index [lindex $argList 1] \
	    $data(hasListVar) root $index]
}

#------------------------------------------------------------------------------
# tablelist::iselemsnippedSubCmd
#------------------------------------------------------------------------------
proc tablelist::iselemsnippedSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win iselemsnipped cellIndex fullTextName"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    set fullTextName [lindex $argList 1]
    upvar 2 $fullTextName fullText

    upvar ::tablelist::ns${win}::data data
    set item [lindex $data(itemList) $row]
    set key [lindex $item end]
    set fullText [lindex $item $col]
    if {[lindex $data(fmtCmdFlagList) $col]} {
	set fullText [formatElem $win $key $row $col $fullText]
    }
    if {[string match "*\t*" $fullText]} {
	set fullText [mapTabs $fullText]
    }

    set pixels [lindex $data(colList) [expr {2*$col}]]
    if {$pixels == 0} {				;# convention: dynamic width
	if {$data($col-maxPixels) > 0 &&
	    $data($col-reqPixels) > $data($col-maxPixels)} {
	    set pixels $data($col-maxPixels)
	}
    }
    if {$pixels == 0 || $data($col-wrap)} {
	return 0
    }

    set text $fullText
    getAuxData $win $key $col auxType auxWidth $pixels
    getIndentData $win $key $col indentWidth
    set cellFont [getCellFont $win $key $col]
    incr pixels $data($col-delta)

    if {[string match "*\n*" $text]} {
	set list [split $text "\n"]
	adjustMlElem $win list auxWidth indentWidth $cellFont $pixels "r" ""
	set text [join $list "\n"]
    } else {
	adjustElem $win text auxWidth indentWidth $cellFont $pixels "r" ""
    }

    return [expr {[string compare $text $fullText] != 0}]
}

#------------------------------------------------------------------------------
# tablelist::isexpandedSubCmd
#------------------------------------------------------------------------------
proc tablelist::isexpandedSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win isexpanded index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set treeCol $data(treeCol)
    if {[info exists data($key,$treeCol-indent)]} {
	return [string match "*expanded*" $data($key,$treeCol-indent)]
    } else {
	return 0
    }
}

#------------------------------------------------------------------------------
# tablelist::istitlesnippedSubCmd
#------------------------------------------------------------------------------
proc tablelist::istitlesnippedSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win istitlesnipped columnIndex fullTextName"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    set fullTextName [lindex $argList 1]
    upvar 2 $fullTextName fullText

    upvar ::tablelist::ns${win}::data data
    set fullText [lindex $data(-columns) [expr {3*$col + 1}]]
    return $data($col-isSnipped)
}

#------------------------------------------------------------------------------
# tablelist::isviewableSubCmd
#------------------------------------------------------------------------------
proc tablelist::isviewableSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win isviewable index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    return [isRowViewable $win $row]
}

#------------------------------------------------------------------------------
# tablelist::itemlistvarSubCmd
#------------------------------------------------------------------------------
proc tablelist::itemlistvarSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win itemlistvar"
    }

    return ::tablelist::ns${win}::data(itemList)
}

#------------------------------------------------------------------------------
# tablelist::labelpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::labelpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win labelpath columnIndex"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    upvar ::tablelist::ns${win}::data data
    return $data(hdrTxtFrLbl)$col
}

#------------------------------------------------------------------------------
# tablelist::labelsSubCmd
#------------------------------------------------------------------------------
proc tablelist::labelsSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win labels"
    }

    upvar ::tablelist::ns${win}::data data
    set labelList {}
    for {set col 0} {$col < $data(colCount)} {incr col} {
	lappend labelList $data(hdrTxtFrLbl)$col
    }

    return $labelList
}

#------------------------------------------------------------------------------
# tablelist::labeltagSubCmd
#------------------------------------------------------------------------------
proc tablelist::labeltagSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win labeltag"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(labelTag)
}

#------------------------------------------------------------------------------
# tablelist::moveSubCmd
#------------------------------------------------------------------------------
proc tablelist::moveSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2 || $argCount > 3} {
	mwutil::wrongNumArgs \
		"$win move sourceIndex targetIndex" \
		"$win move sourceIndex targetParentNodeIndex targetChildIndex"
    }

    synchronize $win
    displayItems $win
    set source [rowIndex $win [lindex $argList 0] 0]
    if {$argCount == 2} {
	set target [rowIndex $win [lindex $argList 1] 1]
	return [moveRow $win $source $target]
    } else {
	set targetParentKey [nodeIndexToKey $win [lindex $argList 1]]
	set targetChildIdx [lindex $argList 2]
	return [moveNode $win $source $targetParentKey $targetChildIdx]
    }
}

#------------------------------------------------------------------------------
# tablelist::movecolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::movecolumnSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win movecolumn sourceColumnIndex\
			      targetColumnIndex"
    }

    synchronize $win
    displayItems $win
    set arg0 [lindex $argList 0]
    set source [colIndex $win $arg0 1]
    set arg1 [lindex $argList 1]
    upvar ::tablelist::ns${win}::data data
    if {[string first $arg1 "end"] == 0 || $arg1 == $data(colCount)} {
	set target $data(colCount)
    } else {
	set target [colIndex $win $arg1 1]
    }

    return [moveCol $win $source $target]
}

#------------------------------------------------------------------------------
# tablelist::nearestSubCmd
#------------------------------------------------------------------------------
proc tablelist::nearestSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win nearest y"
    }

    set y [format "%d" [lindex $argList 0]]
    synchronize $win
    displayItems $win
    return [rowIndex $win @0,$y 0]
}

#------------------------------------------------------------------------------
# tablelist::nearestcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::nearestcellSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win nearestcell x y"
    }

    set x [format "%d" [lindex $argList 0]]
    set y [format "%d" [lindex $argList 1]]
    synchronize $win
    displayItems $win
    return [join [cellIndex $win @$x,$y 0] ","]
}

#------------------------------------------------------------------------------
# tablelist::nearestcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::nearestcolumnSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win nearestcolumn x"
    }

    set x [format "%d" [lindex $argList 0]]
    return [colIndex $win @$x,0 0]
}

#------------------------------------------------------------------------------
# tablelist::noderowSubCmd
#------------------------------------------------------------------------------
proc tablelist::noderowSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win noderow parentNodeIndex childIndex"
    }

    synchronize $win
    set parentKey [nodeIndexToKey $win [lindex $argList 0]]
    set childIdx [lindex $argList 1]
    return [nodeRow $win $parentKey $childIdx]
}

#------------------------------------------------------------------------------
# tablelist::parentkeySubCmd
#------------------------------------------------------------------------------
proc tablelist::parentkeySubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win parentkey nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    upvar ::tablelist::ns${win}::data data
    return $data($key-parent)
}

#------------------------------------------------------------------------------
# tablelist::refreshsortingSubCmd
#------------------------------------------------------------------------------
proc tablelist::refreshsortingSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win refreshsorting ?parentNodeIndex?"
    }

    synchronize $win
    displayItems $win
    if {$argCount == 0} {
	set parentKey root
    } else {
	set parentKey [nodeIndexToKey $win [lindex $argList 0]]
    }

    upvar ::tablelist::ns${win}::data data
    set sortOrderList {}
    foreach col $data(sortColList) {
	lappend sortOrderList $data($col-sortOrder)
    }

    return [sortItems $win $parentKey $data(sortColList) $sortOrderList]
}

#------------------------------------------------------------------------------
# tablelist::rejectinputSubCmd
#------------------------------------------------------------------------------
proc tablelist::rejectinputSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win rejectinput"
    }

    upvar ::tablelist::ns${win}::data data
    set data(rejected) 1
    return ""
}

#------------------------------------------------------------------------------
# tablelist::resetsortinfoSubCmd
#------------------------------------------------------------------------------
proc tablelist::resetsortinfoSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win resetsortinfo"
    }

    upvar ::tablelist::ns${win}::data data

    foreach col $data(sortColList) {
	set data($col-sortRank) 0
	set data($col-sortOrder) ""
    }

    set whichWidths {}
    foreach col $data(arrowColList) {
	lappend whichWidths l$col
    }

    set data(sortColList) {}
    set data(arrowColList) {}
    set data(sortOrder) {}

    if {[llength $whichWidths] > 0} {
	synchronize $win
	displayItems $win
	adjustColumns $win $whichWidths 1
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::rowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::rowattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win rowattrib index ?name? ?value\
			      name value ...?"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::attribSubCmd $win $key [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::rowcgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::rowcgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win rowcget index option"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    variable rowConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] rowConfigSpecs]
    return [doRowCget $row $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::rowconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::rowconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win rowconfigure index ?option? ?value\
			      option value ...?"
    }

    synchronize $win
    displayItems $win
    variable rowConfigSpecs
    set row [rowIndex $win [lindex $argList 0] 0 1]
    return [mwutil::configureSubCmd $win rowConfigSpecs \
	    "tablelist::doRowConfig $row" "tablelist::doRowCget $row" \
	    [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::scanSubCmd
#------------------------------------------------------------------------------
proc tablelist::scanSubCmd {win argList} {
    if {[llength $argList] != 3} {
	mwutil::wrongNumArgs "$win scan mark|dragto x y"
    }

    set x [format "%d" [lindex $argList 1]]
    set y [format "%d" [lindex $argList 2]]
    variable scanOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $scanOpts]
    synchronize $win
    displayItems $win
    return [doScan $win $opt $x $y]
}

#------------------------------------------------------------------------------
# tablelist::searchcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::searchcolumnSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2} {
	mwutil::wrongNumArgs "$win searchcolumn columnIndex pattern ?options?"
    }

    synchronize $win
    set col [colIndex $win [lindex $argList 0] 1]
    set pattern [lindex $argList 1]

    #
    # Initialize some processing parameters
    #
    set mode -glob		;# possible values: -exact, -glob, -regexp
    set checkCmd ""
    set parentKey root
    set allMatches 0						;# boolean
    set backwards 0						;# boolean
    set descend 0						;# boolean
    set formatted 0						;# boolean
    set noCase 0						;# boolean
    set negated 0						;# boolean
    set numeric 0						;# boolean
    set gotStartRow 0						;# boolean

    #
    # Parse the argument list
    #
    variable searchOpts
    for {set n 2} {$n < $argCount} {incr n} {
	set arg [lindex $argList $n]
	set opt [mwutil::fullOpt "option" $arg $searchOpts]
	switch -- $opt {
	    -all	{ set allMatches 1}
	    -backwards	{ set backwards 1 }
	    -check {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set checkCmd [lindex $argList $n]
	    }
	    -descend	{ set descend 1 }
	    -exact	{ set mode -exact }
	    -formatted	{ set formatted 1 }
	    -glob	{ set mode -glob }
	    -nocase	{ set noCase 1 }
	    -not	{ set negated 1 }
	    -numeric	{ set numeric 1 }
	    -parent {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set parentKey [nodeIndexToKey $win [lindex $argList $n]]
	    }
	    -regexp	{ set mode -regexp }
	    -start {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set startRow [rowIndex $win [lindex $argList $n] 0]
		set gotStartRow 1
	    }
	}
    }

    if {([string compare $mode "-exact"] == 0 && !$numeric && $noCase) ||
	([string compare $mode "-glob"] == 0 && $noCase)} {
	set pattern [string tolower $pattern]
    }

    upvar ::tablelist::ns${win}::data data
    if {[string length $data(-populatecommand)] != 0} {
	#
	# Populate the relevant subtree(s) if necessary
	#
	if {[string compare $parentKey "root"] == 0} {
	    if {$descend} {
		for {set row 0} {$row < $data(itemCount)} {incr row} {
		    populate $win $row 1
		}
	    }
	} else {
	    populate $win [keyToRow $win $parentKey] $descend
	}
    }

    #
    # Build the list of row indices of the matching elements
    #
    set rowList {}
    set useFormatCmd [expr {$formatted && [lindex $data(fmtCmdFlagList) $col]}]
    set childCount [llength $data($parentKey-children)]
    if {$childCount != 0} {
	if {$backwards} {
	    set childIdx [expr {$childCount - 1}]
	    if {$descend} {
		set childKey [lindex $data($parentKey-children) $childIdx]
		set maxRow [expr {[nodeRow $win $childKey end] - 1}]
		if {$gotStartRow && $maxRow > $startRow} {
		    set maxRow $startRow
		}
		set minRow [nodeRow $win $parentKey 0]
		for {set row $maxRow} {$row >= $minRow} {incr row -1} {
		    set item [lindex $data(itemList) $row]
		    set elem [lindex $item $col]
		    if {$useFormatCmd} {
			set key [lindex $item end]
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    } else {
		for {} {$childIdx >= 0} {incr childIdx -1} {
		    set key [lindex $data($parentKey-children) $childIdx]
		    set row [keyToRow $win $key]
		    if {$gotStartRow && $row > $startRow} {
			continue
		    }
		    set elem [lindex [lindex $data(itemList) $row] $col]
		    if {$useFormatCmd} {
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    }
	} else {
	    set childIdx 0
	    if {$descend} {
		set childKey [lindex $data($parentKey-children) $childIdx]
		set fromRow [keyToRow $win $childKey]
		if {$gotStartRow && $fromRow < $startRow} {
		    set fromRow $startRow
		}
		set toRow [nodeRow $win $parentKey end]
		for {set row $fromRow} {$row < $toRow} {incr row} {
		    set item [lindex $data(itemList) $row]
		    set elem [lindex $item $col]
		    if {$useFormatCmd} {
			set key [lindex $item end]
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    } else {
		for {} {$childIdx < $childCount} {incr childIdx} {
		    set key [lindex $data($parentKey-children) $childIdx]
		    set row [keyToRow $win $key]
		    if {$gotStartRow && $row < $startRow} {
			continue
		    }
		    set elem [lindex [lindex $data(itemList) $row] $col]
		    if {$useFormatCmd} {
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    }
	}
    }

    if {$allMatches} {
	return $rowList
    } elseif {[llength $rowList] == 0} {
	return -1
    } else {
	return [lindex $rowList 0]
    }
}

#------------------------------------------------------------------------------
# tablelist::seeSubCmd
#------------------------------------------------------------------------------
proc tablelist::seeSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win see index"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0]
    if {[winfo viewable $win] ||
	[llength [$win.body tag nextrange elidedWin 1.0 end]] == 0} {
	return [seeRow $win $index]
    } else {
	after 0 [list tablelist::seeRow $win $index]
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::seecellSubCmd
#------------------------------------------------------------------------------
proc tablelist::seecellSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win seecell cellIndex"
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 0] {}
    if {[winfo viewable $win] &&
	[llength [$win.body tag nextrange elidedWin 1.0 end]] == 0} {
	return [seeCell $win $row $col]
    } else {
	after 0 [list tablelist::seeCell $win $row $col]
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::seecolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::seecolumnSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win seecolumn columnIndex"
    }

    synchronize $win
    displayItems $win
    set col [colIndex $win [lindex $argList 0] 0]
    if {[winfo viewable $win] &&
	[llength [$win.body tag nextrange elidedWin 1.0 end]] == 0} {
	return [seeCell $win [rowIndex $win @0,0 0] $col]
    } else {
	after 0 [list tablelist::seeCell $win [rowIndex $win @0,0 0] $col]
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::selectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::selectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2 || $argCount > 3} {
	mwutil::wrongNumArgs "$win selection option firstIndex lastIndex" \
			     "$win selection option indexList"
    }

    synchronize $win
    displayItems $win
    variable selectionOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $selectionOpts]
    set first [lindex $argList 1]

    switch $opt {
	anchor -
	includes {
	    if {$argCount != 2} {
		mwutil::wrongNumArgs "$win selection $opt index"
	    }
	    set index [rowIndex $win $first 0]
	    return [rowSelection $win $opt $index $index]
	}

	clear -
	set {
	    if {$argCount == 2} {
		foreach elem $first {
		    set index [rowIndex $win $elem 0]
		    rowSelection $win $opt $index $index
		}
	    } else {
		set first [rowIndex $win $first 0]
		set last [rowIndex $win [lindex $argList 2] 0]
		rowSelection $win $opt $first $last
	    }

	    updateColors $win
	    invokeMotionHandler $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::separatorpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::separatorpathSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win separatorpath ?columnIndex?"
    }

    upvar ::tablelist::ns${win}::data data
    if {$argCount == 0} {
	if {[winfo exists $data(sep)]} {
	    return $data(sep)
	} else {
	    return ""
	}
    } else {
	set col [colIndex $win [lindex $argList 0] 1]
	if {$data(-showseparators)} {
	    return $data(sep)$col
	} else {
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::separatorsSubCmd
#------------------------------------------------------------------------------
proc tablelist::separatorsSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win separators"
    }

    set sepList {}
    foreach w [winfo children $win] {
	if {[regexp {^sep([0-9]+)?$} [winfo name $w]]} {
	    lappend sepList $w
	}
    }

    return [lsort -dictionary $sepList]
}

#------------------------------------------------------------------------------
# tablelist::showtargetmarkSubCmd
#------------------------------------------------------------------------------
proc tablelist::showtargetmarkSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win showtargetmark before|inside index"
    }

    variable targetOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $targetOpts]
    set index [lindex $argList 1]

    upvar ::tablelist::ns${win}::data data
    set w $data(body)

    switch $opt {
	before {
	    set row [rowIndex $win $index 1]
	    if {$data(itemCount) == 0} {
		set y 0
	    } elseif {$row >= $data(itemCount)} {
		set dlineinfo [$w dlineinfo [expr {double($data(itemCount))}]]
		if {[llength $dlineinfo] == 0} {
		    return ""
		}

		set lineY [lindex $dlineinfo 1]
		set lineHeight [lindex $dlineinfo 3]
		set y [expr {$lineY + $lineHeight}]
	    } else {
		if {$row < 0} {
		    set row 0
		}
		set dlineinfo [$w dlineinfo [expr {double($row + 1)}]]
		if {[llength $dlineinfo] == 0} {
		    return ""
		}

		set y [lindex $dlineinfo 1]
	    }

	    place $data(rowGap) -anchor w -y $y -height 4 \
				-width [winfo width $data(hdrTxtFr)]
	}

	inside {
	    set row [rowIndex $win $index 0 1]
	    set dlineinfo [$w dlineinfo [expr {double($row + 1)}]]
	    if {[llength $dlineinfo] == 0} {
		return ""
	    }

	    set lineY [lindex $dlineinfo 1]
	    set lineHeight [lindex $dlineinfo 3]
	    set y [expr {$lineY + $lineHeight/2}]

	    place $data(rowGap) -anchor w -y $y -height $lineHeight -width 6
	}
    }

    raise $data(rowGap)
    return ""
}

#------------------------------------------------------------------------------
# tablelist::sizeSubCmd
#------------------------------------------------------------------------------
proc tablelist::sizeSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win size"
    }

    synchronize $win
    upvar ::tablelist::ns${win}::data data
    return $data(itemCount)
}

#------------------------------------------------------------------------------
# tablelist::sortSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win sort ?-increasing|-decreasing?"
    }

    if {$argCount == 0} {
	set order -increasing
    } else {
	variable sortOpts
	set order [mwutil::fullOpt "option" [lindex $argList 0] $sortOpts]
    }

    synchronize $win
    displayItems $win
    return [sortItems $win root -1 [string range $order 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::sortbycolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortbycolumnSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win sortbycolumn columnIndex\
			      ?-increasing|-decreasing?"
    }

    synchronize $win
    displayItems $win
    set col [colIndex $win [lindex $argList 0] 1]
    if {$argCount == 1} {
	set order -increasing
    } else {
	variable sortOpts
	set order [mwutil::fullOpt "option" [lindex $argList 1] $sortOpts]
    }

    return [sortItems $win root $col [string range $order 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::sortbycolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortbycolumnlistSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win sortbycolumnlist columnIndexList\
			      ?sortOrderList?"
    }

    synchronize $win
    displayItems $win
    set sortColList {}
    foreach elem [lindex $argList 0] {
	set col [colIndex $win $elem 1]
	if {[lsearch -exact $sortColList $col] >= 0} {
	    return -code error "duplicate column index \"$elem\""
	}
	lappend sortColList $col
    }

    set sortOrderList {}
    if {$argCount == 2} {
	variable sortOrders
	foreach elem [lindex $argList 1] {
	    lappend sortOrderList [mwutil::fullOpt "option" $elem $sortOrders]
	}
    }

    return [sortItems $win root $sortColList $sortOrderList]
}

#------------------------------------------------------------------------------
# tablelist::sortcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortcolumnSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortcolumn"
    }

    upvar ::tablelist::ns${win}::data data
    if {[llength $data(sortColList)] == 0} {
	return -1
    } else {
	return [lindex $data(sortColList) 0]
    }
}

#------------------------------------------------------------------------------
# tablelist::sortcolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortcolumnlistSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortcolumnlist"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(sortColList)
}

#------------------------------------------------------------------------------
# tablelist::sortorderSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortorderSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortorder"
    }

    upvar ::tablelist::ns${win}::data data
    if {[llength $data(sortColList)] == 0} {
	return $data(sortOrder)
    } else {
	set col [lindex $data(sortColList) 0]
	return $data($col-sortOrder)
    }
}

#------------------------------------------------------------------------------
# tablelist::sortorderlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortorderlistSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortorderlist"
    }

    upvar ::tablelist::ns${win}::data data
    set sortOrderList {}
    foreach col $data(sortColList) {
	lappend sortOrderList $data($col-sortOrder)
    }

    return $sortOrderList
}

#------------------------------------------------------------------------------
# tablelist::targetmarkpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::targetmarkpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win targetmarkpath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(rowGap)
}

#------------------------------------------------------------------------------
# tablelist::targetmarkposSubCmd
#------------------------------------------------------------------------------
proc tablelist::targetmarkposSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win targetmarkpos y ?-any|-horizontal|-vertical?"
    }

    set y [format "%d" [lindex $argList 0]]
    if {$argCount == 1} {
	set opt -any
    } else {
	variable gapTypeOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $gapTypeOpts]
    }

    synchronize $win
    displayItems $win

    switch -- $opt {
	-any {
	    set row [containingRow $win $y relOffset]
	    if {$row < 0} {
		set place before
		upvar ::tablelist::ns${win}::data data
		set row [expr {
		    ($y < [winfo y $data(body)]) ? 0 : $data(itemCount)
		}]
	    } elseif {$relOffset < 0.25} {
		set place before
	    } elseif {$relOffset < 0.75} {
		set place inside
	    } else {
		set place before
		if {[isexpandedSubCmd $win $row]} {
		    incr row
		} else {
		    #
		    # Get the containing row's next sibling
		    #
		    set childIdx [childindexSubCmd $win $row]
		    set row [noderowSubCmd $win [list \
			     [parentkeySubCmd $win $row] [incr childIdx]]]
		}
	    }

	    return [list $place $row]
	}

	-horizontal {
	    set row [containingRow $win $y relOffset]
	    if {$row < 0} {
		upvar ::tablelist::ns${win}::data data
		set row [expr {
		    ($y < [winfo y $data(body)]) ? 0 : $data(itemCount)
		}]
	    } elseif {$relOffset >= 0.5} {
		if {[isexpandedSubCmd $win $row]} {
		    incr row
		} else {
		    #
		    # Get the containing row's next sibling
		    #
		    set childIdx [childindexSubCmd $win $row]
		    set row [noderowSubCmd $win [list \
			     [parentkeySubCmd $win $row] [incr childIdx]]]
		}
	    }

	    return [list before $row]
	}

	-vertical {
	    set row [containingRow $win $y]
	    return [list inside $row]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::togglecolumnhideSubCmd
#------------------------------------------------------------------------------
proc tablelist::togglecolumnhideSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win togglecolumnhide firstColumnIndex lastColumnIndex" \
		"$win togglecolumnhide columnIndexList"
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    #
    # Toggle the value of the -hide option of the specified columns
    #
    variable canElide
    if {!$canElide} {
	set selCells [curCellSelection $win]
    }
    upvar ::tablelist::ns${win}::data data
    set colIdxList {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set data($col-hide) [expr {!$data($col-hide)}]
	    if {$data($col-hide)} {
		incr data(hiddenColCount)
		if {$col == $data(editCol)} {
		    doCancelEditing $win
		}
	    } else {
		incr data(hiddenColCount) -1
	    }
	    lappend colIdxList $col
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set data($col-hide) [expr {!$data($col-hide)}]
	    if {$data($col-hide)} {
		incr data(hiddenColCount)
		if {$col == $data(editCol)} {
		    doCancelEditing $win
		}
	    } else {
		incr data(hiddenColCount) -1
	    }
	    lappend colIdxList $col
	}
    }

    if {[llength $colIdxList] == 0} {
	return ""
    }

    #
    # Adjust the columns and redisplay the items
    #
    makeColFontAndTagLists $win
    adjustColumns $win $colIdxList 1
    adjustColIndex $win data(anchorCol) 1
    adjustColIndex $win data(activeCol) 1
    if {!$canElide} {
	redisplay $win 0 $selCells
    }
    if {[string compare $data(-selecttype) "row"] == 0} {
	foreach row [curSelection $win] {
	    rowSelection $win set $row $row
	}
    }

    updateViewWhenIdle $win
    genVirtualEvent $win <<TablelistColHiddenStateChanged>> $colIdxList
    return ""
}

#------------------------------------------------------------------------------
# tablelist::togglerowhideSubCmd
#------------------------------------------------------------------------------
proc tablelist::togglerowhideSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win togglerowhide firstIndex lastIndex" \
			     "$win togglerowhide indexList"
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    #
    # Toggle the value of the -hide option of the specified rows
    #
    set rowIdxList {}
    set count 0
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0 1]
	    doRowConfig $row $win -hide [expr {![doRowCget $row $win -hide]}]
	    incr count
	    lappend rowIdxList $row
	}
    } else {
	set firstRow [rowIndex $win $first 0 1]
	set lastRow [rowIndex $win [lindex $argList 1] 0 1]
	for {set row $firstRow} {$row <= $lastRow} {incr row} {
	    doRowConfig $row $win -hide [expr {![doRowCget $row $win -hide]}]
	    incr count
	    lappend rowIdxList $row
	}
    }

    if {$count != 0} {
	makeStripesWhenIdle $win
	showLineNumbersWhenIdle $win
	updateViewWhenIdle $win
	genVirtualEvent $win <<TablelistRowHiddenStateChanged>> $rowIdxList
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::toplevelkeySubCmd
#------------------------------------------------------------------------------
proc tablelist::toplevelkeySubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win toplevelkey index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [topLevelKey $win $key]
}

#------------------------------------------------------------------------------
# tablelist::unsetattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetattribSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win unsetattrib name"
    }

    return [mwutil::unsetattribSubCmd $win "widget" [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::unsetcellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetcellattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win unsetcellattrib cellIndex name"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::unsetattribSubCmd $win $key,$col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::unsetcolumnattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetcolumnattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win unsetcolumnattrib columnIndex name"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::unsetattribSubCmd $win $col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::unsetrowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetrowattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win unsetrowattrib index name"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::unsetattribSubCmd $win $key [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::viewablerowcountSubCmd
#------------------------------------------------------------------------------
proc tablelist::viewablerowcountSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount != 0 && $argCount != 2} {
	mwutil::wrongNumArgs "$win viewablerowcount ?firstIndex lastIndex?"
    }

    synchronize $win
    upvar ::tablelist::ns${win}::data data
    if {$argCount == 0} {
	set first 0
	set last $data(lastRow)
    } else {
	set first [rowIndex $win [lindex $argList 0] 0]
	set last [rowIndex $win [lindex $argList 1] 0]
    }
    if {$last < $first} {
	return 0
    }

    #
    # Adjust the range to fit within the existing items
    #
    if {$first < 0} {
	set first 0
    }
    if {$last > $data(lastRow)} {
	set last $data(lastRow)
    }

    return [getViewableRowCount $win $first $last]
}

#------------------------------------------------------------------------------
# tablelist::windowpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::windowpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win windowpath cellIndex"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set w $data(body).frm_$key,$col.w
    if {[winfo exists $w]} {
	return $w
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::xviewSubCmd
#------------------------------------------------------------------------------
proc tablelist::xviewSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount != 1 || [lindex $argList 0] != 0} {
	synchronize $win
	displayItems $win
    }
    upvar ::tablelist::ns${win}::data data

    switch $argCount {
	0 {
	    #
	    # Command: $win xview
	    #
	    if {$data(-titlecolumns) == 0} {
		return [$data(hdrTxt) xview]
	    } else {
		set scrlWindowWidth [getScrlWindowWidth $win]
		if {$scrlWindowWidth <= 0} {
		    return [list 0 0]
		}

		set scrlContentWidth [getScrlContentWidth $win 0 $data(lastCol)]
		if {$scrlContentWidth == 0} {
		    return [list 0 1]
		}

		set scrlXOffset \
		    [scrlColOffsetToXOffset $win $data(scrlColOffset)]
		set fraction1 [expr {$scrlXOffset/double($scrlContentWidth)}]
		set fraction2 [expr {($scrlXOffset + $scrlWindowWidth)/
				     double($scrlContentWidth)}]
		if {$fraction2 > 1.0} {
		    set fraction2 1.0
		}
		return [list [format "%g" $fraction1] [format "%g" $fraction2]]
	    }
	}

	1 {
	    #
	    # Command: $win xview <units>
	    #
	    set units [format "%d" [lindex $argList 0]]
	    if {$data(-titlecolumns) == 0} {
		foreach w [list $data(hdrTxt) $data(body)] {
		    $w xview moveto 0
		    $w xview scroll $units units
		}
	    } else {
		changeScrlColOffset $win $units
		updateColors $win
	    }
	    return ""
	}

	default {
	    #
	    # Command: $win xview moveto <fraction>
	    #	       $win xview scroll <number> units|pages
	    #
	    set argList [mwutil::getScrollInfo $argList]
	    if {$data(-titlecolumns) == 0} {
		foreach w [list $data(hdrTxt) $data(body)] {
		    eval [list $w xview] $argList
		}
	    } else {
		if {[string compare [lindex $argList 0] "moveto"] == 0} {
		    #
		    # Compute the new scrolled column offset
		    #
		    set fraction [lindex $argList 1]
		    set scrlContentWidth \
			[getScrlContentWidth $win 0 $data(lastCol)]
		    set pixels [expr {int($fraction*$scrlContentWidth + 0.5)}]
		    set scrlColOffset [scrlXOffsetToColOffset $win $pixels]

		    #
		    # Increase the new scrolled column offset if necessary
		    #
		    if {$pixels + [getScrlWindowWidth $win] >=
			$scrlContentWidth} {
			incr scrlColOffset
		    }

		    changeScrlColOffset $win $scrlColOffset
		} else {
		    set number [lindex $argList 1]
		    if {[string compare [lindex $argList 2] "units"] == 0} {
			changeScrlColOffset $win \
			    [expr {$data(scrlColOffset) + $number}]
		    } else {
			#
			# Compute the new scrolled column offset
			#
			set scrlXOffset \
			    [scrlColOffsetToXOffset $win $data(scrlColOffset)]
			set scrlWindowWidth [getScrlWindowWidth $win]
			set deltaPixels [expr {$number*$scrlWindowWidth}]
			set pixels [expr {$scrlXOffset + $deltaPixels}]
			set scrlColOffset [scrlXOffsetToColOffset $win $pixels]

			#
			# Adjust the new scrolled column offset if necessary
			#
			if {$number < 0 &&
			    [getScrlContentWidth $win $scrlColOffset \
			     $data(lastCol)] -
			    [getScrlContentWidth $win $data(scrlColOffset) \
			     $data(lastCol)] > -$deltaPixels} {
			    incr scrlColOffset
			}
			if {$scrlColOffset == $data(scrlColOffset)} {
			    if {$number < 0} {
				incr scrlColOffset -1
			    } elseif {$number > 0} {
				incr scrlColOffset
			    }
			}

			changeScrlColOffset $win $scrlColOffset
		    }
		}
		updateColors $win
	    }
	    variable winSys
	    if {[string compare $winSys "aqua"] == 0 && [winfo viewable $win]} {
		#
		# Work around a Tk bug on Mac OS X Aqua
		#
		if {[winfo exists $data(bodyFr)]} {
		    lower $data(bodyFr)
		    raise $data(bodyFr)
		}
	    }
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::yviewSubCmd
#------------------------------------------------------------------------------
proc tablelist::yviewSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount != 1 || [lindex $argList 0] != 0} {
	synchronize $win
	displayItems $win
    }
    upvar ::tablelist::ns${win}::data data
    set w $data(body)

    switch $argCount {
	0 {
	    #
	    # Command: $win yview
	    #
	    set totalViewableCount \
		[expr {$data(itemCount) - $data(nonViewableRowCount)}]
	    if {$totalViewableCount == 0} {
		return [list 0 1]
	    }
	    set topTextIdx [$w index @0,0]
	    set btmTextIdx [$w index @0,$data(btmY)]
	    set topRow [expr {int($topTextIdx) - 1}]
	    set btmRow [expr {int($btmTextIdx) - 1}]
	    if {$btmRow > $data(lastRow)} {		;# text widget bug
		set btmRow $data(lastRow)
	    }
	    foreach {x y width height baselinePos} [$w dlineinfo $topTextIdx] {}
	    if {$y < 0} {
		incr topRow	;# top row incomplete in vertical direction
	    }
	    foreach {x y width height baselinePos} [$w dlineinfo $btmTextIdx] {}
	    set y2 [expr {$y + $height}]
	    if {[string compare [$w index @0,$y] [$w index @0,$y2]] == 0} {
		incr btmRow -1	;# btm row incomplete in vertical direction
	    }
	    set upperViewableCount \
		[getViewableRowCount $win 0 [expr {$topRow - 1}]]
	    set winViewableCount [getViewableRowCount $win $topRow $btmRow]
	    set fraction1 [expr {$upperViewableCount/
				 double($totalViewableCount)}]
	    set fraction2 [expr {($upperViewableCount + $winViewableCount)/
				 double($totalViewableCount)}]
	    return [list [format "%g" $fraction1] [format "%g" $fraction2]]
	}

	1 {
	    #
	    # Command: $win yview <units>
	    #
	    set units [format "%d" [lindex $argList 0]]
	    set row [viewableRowOffsetToRowIndex $win $units]
	    if {![yviewTextRow $win $row]} {
		return ""
	    }
	    adjustElidedText $win
	    redisplayVisibleItems $win
	    updateColors $win
	    adjustSepsWhenIdle $win
	    updateVScrlbarWhenIdle $win
	    return ""
	}

	default {
	    #
	    # Command: $win yview moveto <fraction>
	    #	       $win yview scroll <number> units|pages
	    #
	    set argList [mwutil::getScrollInfo $argList]
	    if {[string compare [lindex $argList 0] "moveto"] == 0} {
		set data(fraction) [lindex $argList 1]
		if {![info exists data(moveToId)]} {
		    set data(moveToId) [after 1 [list tablelist::moveTo $win]]
		}
		return ""
	    } else {
		set number [lindex $argList 1]
		if {[string compare [lindex $argList 2] "units"] == 0} {
		    set topRow [expr {int([$w index @0,0]) - 1}]
		    set upperViewableCount \
			[getViewableRowCount $win 0 [expr {$topRow - 1}]]
		    set offset [expr {$upperViewableCount + $number}]
		    set row [viewableRowOffsetToRowIndex $win $offset]
		    if {![yviewTextRow $win $row]} {
			return ""
		    }
		} else {
		    set absNumber [expr {abs($number)}]
		    for {set n 0} {$n < $absNumber} {incr n} {
			set topRow [expr {int([$w index @0,0]) - 1}]
			set btmRow [expr {int([$w index @0,$data(btmY)]) - 1}]
			if {$btmRow > $data(lastRow)} {	;# text widget bug
			    set btmRow $data(lastRow)
			}
			set upperViewableCount \
			    [getViewableRowCount $win 0 [expr {$topRow - 1}]]
			set winViewableCount \
			    [getViewableRowCount $win $topRow $btmRow]
			set delta [expr {$winViewableCount - 2}]
			if {$number < 0} {
			    set delta [expr {(-1)*$delta}]
			}
			set offset [expr {$upperViewableCount + $delta}]
			set row [viewableRowOffsetToRowIndex $win $offset]
			if {![yviewTextRow $win $row]} {
			    return ""
			}
		    }
		}

		adjustElidedText $win
		redisplayVisibleItems $win
		updateColors $win
		adjustSepsWhenIdle $win
		updateVScrlbarWhenIdle $win
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::cellSelection
#
# Processes the tablelist cellselection subcommand.
#------------------------------------------------------------------------------
proc tablelist::cellSelection {win opt firstRow firstCol lastRow lastCol} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) && [string compare $opt "includes"] != 0} {
	return ""
    }

    switch $opt {
	anchor {
	    #
	    # Adjust the row and column indices to fit
	    # within the existing viewable elements
	    #
	    adjustRowIndex $win firstRow 1
	    adjustColIndex $win firstCol 1

	    set data(anchorRow) $firstRow
	    set data(anchorCol) $firstCol
	    return ""
	}

	clear {
	    #
	    # Adjust the row and column indices
	    # to fit within the existing elements
	    #
	    if {$data(itemCount) == 0 || $data(colCount) == 0} {
		return ""
	    }
	    adjustRowIndex $win firstRow
	    adjustColIndex $win firstCol
	    adjustRowIndex $win lastRow
	    adjustColIndex $win lastCol

	    #
	    # Swap the indices if necessary
	    #
	    if {$lastRow < $firstRow} {
		set tmp $firstRow
		set firstRow $lastRow
		set lastRow $tmp
	    }
	    if {$lastCol < $firstCol} {
		set tmp $firstCol
		set firstCol $lastCol
		set lastCol $tmp
	    }

	    set fromTextIdx [expr {$firstRow + 1}].0
	    set toTextIdx [expr {$lastRow + 1}].end

	    #
	    # Find the (partly) selected lines of the body text widget
	    # in the text range specified by the two cell indices
	    #
	    set w $data(body)
	    variable canElide
	    variable elide
	    set selRange [$w tag nextrange select $fromTextIdx $toTextIdx]
	    while {[llength $selRange] != 0} {
		set selStart [lindex $selRange 0]
		set line [expr {int($selStart)}]
		set row [expr {$line - 1}]
		set key [lindex $data(keyList) $row]

		#
		# Deselect the relevant elements of the row
		#
		findTabs $win $line $firstCol $lastCol firstTabIdx lastTabIdx
		set textIdx1 $firstTabIdx
		for {set col $firstCol} {$col <= $lastCol} {incr col} {
		    if {$data($col-hide) && !$canElide} {
			continue
		    }

		    set textIdx2 \
			[$w search $elide "\t" $textIdx1+1c $lastTabIdx+1c]+1c
		    $w tag remove select $textIdx1 $textIdx2
		    set textIdx1 $textIdx2
		}

		set selRange \
		    [$w tag nextrange select "$selStart lineend" $toTextIdx]
	    }

	    updateColorsWhenIdle $win
	    return ""
	}

	includes {
	    variable canElide
	    if {$firstRow < 0 || $firstRow > $data(lastRow) || \
		$firstCol < 0 || $firstCol > $data(lastCol) ||
		($data($firstCol-hide) && !$canElide)} {
		return 0
	    }

	    findTabs $win [expr {$firstRow + 1}] $firstCol $firstCol \
		     tabIdx1 tabIdx2
	    if {[lsearch -exact [$data(body) tag names $tabIdx2] select] < 0} {
		return 0
	    } else {
		return 1
	    }
	}

	set {
	    #
	    # Adjust the row and column indices
	    # to fit within the existing elements
	    #
	    if {$data(itemCount) == 0 || $data(colCount) == 0} {
		return ""
	    }
	    adjustRowIndex $win firstRow
	    adjustColIndex $win firstCol
	    adjustRowIndex $win lastRow
	    adjustColIndex $win lastCol

	    #
	    # Swap the indices if necessary
	    #
	    if {$lastRow < $firstRow} {
		set tmp $firstRow
		set firstRow $lastRow
		set lastRow $tmp
	    }
	    if {$lastCol < $firstCol} {
		set tmp $firstCol
		set firstCol $lastCol
		set lastCol $tmp
	    }

	    set w $data(body)
	    variable canElide
	    variable elide
	    for {set row $firstRow; set line [expr {$firstRow + 1}]} \
		{$row <= $lastRow} {set row $line; incr line} {
		#
		# Check whether the row is selectable
		#
		set key [lindex $data(keyList) $row]
		if {[info exists data($key-selectable)]} {
		    continue
		}

		#
		# Select the relevant elements of the row
		#
		findTabs $win $line $firstCol $lastCol firstTabIdx lastTabIdx
		set textIdx1 $firstTabIdx
		for {set col $firstCol} {$col <= $lastCol} {incr col} {
		    if {$data($col-hide) && !$canElide} {
			continue
		    }

		    set textIdx2 \
			[$w search $elide "\t" $textIdx1+1c $lastTabIdx+1c]+1c
		    $w tag add select $textIdx1 $textIdx2
		    set textIdx1 $textIdx2
		}
	    }

	    #
	    # If the selection is exported and there are any selected
	    # cells in the widget then make win the new owner of the
	    # PRIMARY selection and register a callback to be invoked
	    # when it loses ownership of the PRIMARY selection
	    #
	    if {$data(-exportselection) &&
		[llength [$w tag nextrange select 1.0]] != 0} {
		selection own -command \
			[list ::tablelist::lostSelection $win] $win
	    }

	    updateColorsWhenIdle $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::colWidth
#
# Processes the tablelist columnwidth subcommand.
#------------------------------------------------------------------------------
proc tablelist::colWidth {win col opt} {
    upvar ::tablelist::ns${win}::data data
    set pixels [lindex $data(colList) [expr {2*$col}]]
    if {$pixels == 0} {				;# convention: dynamic width
	set pixels $data($col-reqPixels)
	if {$data($col-maxPixels) > 0} {
	    if {$pixels > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
	    }
	}
    }

    switch -- $opt {
	-requested { return $pixels }
	-stretched { return [expr {$pixels + $data($col-delta)}] }
	-total {
	    return [expr {$pixels + $data($col-delta) + 2*$data(charWidth)}]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::containingRow
#
# Processes the tablelist containing subcommand.
#------------------------------------------------------------------------------
proc tablelist::containingRow {win y {relOffsetName ""}} {
    upvar ::tablelist::ns${win}::data data
    if {$data(itemCount) == 0} {
	return -1
    }

    set row [rowIndex $win @0,$y 0]
    set w $data(body)
    incr y -[winfo y $w]
    if {$y < 0} {
	return -1
    }

    set dlineinfo [$w dlineinfo [expr {double($row + 1)}]]
    set lineY [lindex $dlineinfo 1]
    set lineHeight [lindex $dlineinfo 3]
    if {[llength $dlineinfo] != 0 && $y < $lineY + $lineHeight} {
	if {[string length $relOffsetName] != 0} {
	    upvar $relOffsetName relOffset
	    if {$y == $lineY + $lineHeight -1} {
		set relOffset 1.0
	    } else {
		set relOffset [expr {double($y - $lineY) / $lineHeight}]
	    }
	}
	return $row
    } else {
	return -1
    }
}

#------------------------------------------------------------------------------
# tablelist::containingCol
#
# Processes the tablelist containingcolumn subcommand.
#------------------------------------------------------------------------------
proc tablelist::containingCol {win x} {
    upvar ::tablelist::ns${win}::data data
    if {$x < [winfo x $data(body)]} {
	return -1
    }

    set col [colIndex $win @$x,0 0]
    if {$col < 0} {
	return -1
    }

    set lbl $data(hdrTxtFrLbl)$col
    if {$x + [winfo rootx $win] < [winfo width $lbl] + [winfo rootx $lbl]} {
	return $col
    } else {
	return -1
    }
}

#------------------------------------------------------------------------------
# tablelist::curCellSelection
#
# Processes the tablelist curcellselection subcommand.  Meaning of the last
# optional argument: 0: all; 1: nonhidden only; 2: viewable only.
#------------------------------------------------------------------------------
proc tablelist::curCellSelection {win {getKeys 0} {constraint 0}} {
    variable canElide
    variable elide
    upvar ::tablelist::ns${win}::data data

    #
    # Find the (partly) selected lines of the body text widget
    #
    set result {}
    set w $data(body)
    for {set selRange [$w tag nextrange select 1.0]} \
	{[llength $selRange] != 0} \
	{set selRange [$w tag nextrange select $selEnd]} {
	foreach {selStart selEnd} $selRange {}
	set line [expr {int($selStart)}]
	set row [expr {$line - 1}]
	if {$getKeys || $constraint != 0} {
	    set key [lindex $data(keyList) $row]
	}
	if {($constraint == 1 && [info exists data($key-hide)]) ||
	    ($constraint == 2 && ([info exists data($key-hide)] ||
	     [info exists data($key-elide)]))} {
	    continue
	}

	#
	# Get the index of the column starting at the text position selStart
	#
	set textIdx $line.0
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    if {$data($col-hide) && !$canElide} {
		continue
	    }

	    if {[$w compare $selStart == $textIdx] ||
		[$w compare $selStart == $textIdx+1c] ||
		[$w compare $selStart == $textIdx+2c] &&
		[string compare [$w get $textIdx+2c] "\t"] != 0} {
		set firstCol $col
		break
	    } else {
		set textIdx [$w search $elide "\t" $textIdx+1c $selEnd]+1c
	    }
	}

	#
	# Process the columns, starting at the found one
	# and ending just before the text position selEnd
	#
	set textIdx [$w search $elide "\t" $textIdx+1c $selEnd]+1c
	for {set col $firstCol} {$col < $data(colCount)} {incr col} {
	    if {$data($col-hide) && !$canElide} {
		continue
	    }

	    if {$constraint == 0 || !$data($col-hide)} {
		if {$getKeys} {
		    lappend result $key $col
		} else {
		    lappend result $row,$col
		}
	    }
	    if {[$w compare $textIdx == $selEnd]} {
		break
	    } else {
		set textIdx [$w search $elide "\t" $textIdx+1c $selEnd]+1c
	    }
	}
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::curSelection
#
# Processes the tablelist curselection subcommand.  Meaning of the optional
# argument: 0: all; 1: nonhidden only; 2: viewable only.
#------------------------------------------------------------------------------
proc tablelist::curSelection {win {constraint 0}} {
    #
    # Find the (partly) selected lines of the body text widget
    #
    set result {}
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set selRange [$w tag nextrange select 1.0]
    while {[llength $selRange] != 0} {
	set selStart [lindex $selRange 0]
	set row [expr {int($selStart) - 1}]
	if {$constraint == 0} {
	    lappend result $row
	} else {
	    set key [lindex $data(keyList) $row]
	    if {($constraint == 1 && ![info exists data($key-hide)]) ||
		($constraint == 2 && ![info exists data($key-hide)] &&
		 ![info exists data($key-elide)])} {
		lappend result $row
	    }
	}

	set selRange [$w tag nextrange select "$selStart lineend"]
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::deleteRows
#
# Processes the tablelist delete subcommand.
#------------------------------------------------------------------------------
proc tablelist::deleteRows {win first last updateListVar} {
    #
    # Adjust the range to fit within the existing items
    #
    if {$first < 0} {
	set first 0
    }
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs
    if {$last > $data(lastRow)} {
	set last $data(lastRow)
    }
    if {$last < $first} {
	return ""
    }

    #
    # Increase the last index if necessary, to make sure that all
    # descendants of the corresponding item will get deleted, too
    #
    set lastKey [lindex $data(keyList) $last]
    set last [expr {[nodeRow $win $lastKey end] - 1}]
    set count [expr {$last - $first + 1}]

    #
    # Check whether the width of any dynamic-width
    # column might be affected by the deletion
    #
    set w $data(body)
    if {$count == $data(itemCount)} {
	set colWidthsChanged 1				;# just to save time
	set data(seqNum) -1
	set data(freeKeyList) {}
    } else {
	variable canElide
	set colWidthsChanged 0
	set snipStr $data(-snipstring)
	set row 0
	set itemListRange [lrange $data(itemList) $first $last]
	foreach item $itemListRange {
	    #
	    # Format the item
	    #
	    set key [lindex $item end]
	    set dispItem [lrange $item 0 $data(lastCol)]
	    if {$data(hasFmtCmds)} {
		set dispItem [formatItem $win $key $row $dispItem]
	    }
	    if {[string match "*\t*" $dispItem]} {
		set dispItem [mapTabs $dispItem]
	    }

	    set col 0
	    foreach text $dispItem {pixels alignment} $data(colList) {
		if {($data($col-hide) && !$canElide) || $pixels != 0} {
		    incr col
		    continue
		}

		getAuxData $win $key $col auxType auxWidth
		getIndentData $win $key $col indentWidth
		set cellFont [getCellFont $win $key $col]
		set elemWidth \
		    [getElemWidth $win $text $auxWidth $indentWidth $cellFont]
		if {$elemWidth == $data($col-elemWidth) &&
		    [incr data($col-widestCount) -1] == 0} {
		    set colWidthsChanged 1
		    break
		}

		incr col
	    }

	    if {$colWidthsChanged} {
		break
	    }

	    incr row
	}
    }

    #
    # Delete the given items from the body text widget.  Interestingly,
    # for a large number of items it is much more efficient to delete
    # the lines in chunks than to invoke a global delete command.
    #
    for {set toLine [expr {$last + 2}]; set fromLine [expr {$toLine - 50}]} \
	{$fromLine > $first} {set toLine $fromLine; incr fromLine -50} {
	$w delete [expr {double($fromLine)}] [expr {double($toLine)}]
    }
    set rest [expr {$count % 50}]
    $w delete [expr {double($first + 1)}] [expr {double($first + $rest + 1)}]

    if {$last == $data(lastRow)} {
	#
	# Delete the newline character that ends
	# the line preceding the first deleted one
	#
	$w delete $first.end

	#
	# Work around a peculiarity of the text widget:  Hide
	# the newline character that ends the line preceding
	# the first deleted one if it was hidden before
	#
	set textIdx [expr {double($first)}]
	foreach tag {elidedRow hiddenRow} {
	    if {[lsearch -exact [$w tag names $textIdx] $tag] >= 0} {
		$w tag add $tag $first.end
	    }
	}
    }

    #
    # Unset the elements of data corresponding to the deleted items
    #
    for {set row $first} {$row <= $last} {incr row} {
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	if {$count != $data(itemCount)} {
	    lappend data(freeKeyList) $key
	}

	foreach opt {-background -foreground -name -selectable
		     -selectbackground -selectforeground} {
	    if {[info exists data($key$opt)]} {
		unset data($key$opt)
	    }
	}

	if {[info exists data($key-font)]} {
	    unset data($key-font)
	    incr data(rowTagRefCount) -1
	}

	set isElided [info exists data($key-elide)]
	set isHidden [info exists data($key-hide)]
	if {$isElided} {
	    unset data($key-elide)
	}
	if {$isHidden} {
	    unset data($key-hide)
	}
	if {$isElided || $isHidden} {
	    incr data(nonViewableRowCount) -1
	}

	if {$count != $data(itemCount)} {
	    #
	    # Remove the key from the list of children of its parent
	    #
	    set parentKey $data($key-parent)
	    if {[info exists data($parentKey-children)]} {
		set childIdx [lsearch -exact $data($parentKey-children) $key]
		set data($parentKey-children) \
		    [lreplace $data($parentKey-children) $childIdx $childIdx]

		#
		# If the parent's list of children has become empty
		# then set its indentation image to the indented one
		#
		set col $data(treeCol)
		if {[llength $data($parentKey-children)] == 0 &&
		    [info exists data($parentKey,$col-indent)]} {
		    collapseSubCmd $win [list $parentKey -partly]
		    set data($parentKey,$col-indent) [strMap \
			{"collapsed" "indented" "expanded" "indented"
			 "Act" "" "Sel" ""} $data($parentKey,$col-indent)]
		    if {[winfo exists $data(body).ind_$parentKey,$col]} {
			$data(body).ind_$parentKey,$col configure -image \
			    $data($parentKey,$col-indent)
		    }
		}
	    }
	}

	foreach prop {-row -parent -children} {
	    unset data($key$prop)
	}

	foreach name [array names attribs $key-*] {
	    unset attribs($name)
	}

	for {set col 0} {$col < $data(colCount)} {incr col} {
	    foreach opt {-background -foreground -editable -editwindow
			 -selectbackground -selectforeground -valign
			 -windowdestroy -windowupdate} {
		if {[info exists data($key,$col$opt)]} {
		    unset data($key,$col$opt)
		}
	    }

	    if {[info exists data($key,$col-font)]} {
		unset data($key,$col-font)
		incr data(cellTagRefCount) -1
	    }

	    if {[info exists data($key,$col-image)]} {
		unset data($key,$col-image)
		incr data(imgCount) -1
	    }

	    if {[info exists data($key,$col-window)]} {
		unset data($key,$col-window)
		unset data($key,$col-reqWidth)
		unset data($key,$col-reqHeight)
		incr data(winCount) -1
	    }

	    if {[info exists data($key,$col-indent)]} {
		unset data($key,$col-indent)
		incr data(indentCount) -1
	    }
	}

	foreach name [array names attribs $key,*-*] {
	    unset attribs($name)
	}
    }

    if {$count == $data(itemCount)} {
	set data(root-children) {}
    }

    #
    # Delete the given items from the internal list
    #
    set data(itemList) [lreplace $data(itemList) $first $last]
    set data(keyList) [lreplace $data(keyList) $first $last]
    incr data(itemCount) -$count

    #
    # Delete the given items from the list variable if needed
    #
    if {$updateListVar} {
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
	set var [lreplace $var $first $last]
	trace variable var wu $data(listVarTraceCmd)
    }

    #
    # Update the key -> row mapping at idle time if needed
    #
    if {$last != $data(lastRow)} {
	set data(keyToRowMapValid) 0
	if {![info exists data(mapId)]} {
	    set data(mapId) \
		[after idle [list tablelist::updateKeyToRowMap $win]]
	}
    }

    incr data(lastRow) -$count

    #
    # Update the indices anchorRow and activeRow
    #
    if {$first <= $data(anchorRow)} {
	incr data(anchorRow) -$count
	if {$data(anchorRow) < $first} {
	    set data(anchorRow) $first
	}
	adjustRowIndex $win data(anchorRow) 1
    }
    if {$last < $data(activeRow)} {
	set activeRow $data(activeRow)
	incr activeRow -$count
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    } elseif {$first <= $data(activeRow)} {
	set activeRow $first
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    }

    #
    # Update data(editRow) if the edit window is present
    #
    if {$data(editRow) >= 0} {
	set data(editRow) [keyToRow $win $data(editKey)]
    }

    #
    # Adjust the heights of the body text widget
    # and of the listbox child, if necessary
    #
    if {$data(-height) <= 0} {
	set viewableRowCount \
	    [expr {$data(itemCount) - $data(nonViewableRowCount)}]
	$w configure -height $viewableRowCount
	$data(lb) configure -height $viewableRowCount
    }

    #
    # Invalidate the list of row indices indicating the
    # viewable rows, adjust the columns if necessary, and
    # schedule some operations for execution at idle time
    #
    set data(viewableRowList) {-1}
    if {$colWidthsChanged} {
	adjustColumns $win allCols 1
    }
    makeStripesWhenIdle $win
    showLineNumbersWhenIdle $win
    updateViewWhenIdle $win

    return ""
}

#------------------------------------------------------------------------------
# tablelist::deleteCols
#
# Processes the tablelist deletecolumns subcommand.
#------------------------------------------------------------------------------
proc tablelist::deleteCols {win first last selCellsName} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs $selCellsName selCells

    #
    # Delete the data and attributes corresponding to the given range
    #
    for {set col $first} {$col <= $last} {incr col} {
	if {$data($col-hide)} {
	    incr data(hiddenColCount) -1
	}
	deleteColData $win $col
	deleteColAttribs $win $col
	set selCells [deleteColFromCellList $selCells $col]
    }

    #
    # Shift the elements of data and attribs corresponding to the
    # column indices > last to the left by last - first + 1 positions
    #
    for {set oldCol [expr {$last + 1}]; set newCol $first} \
	{$oldCol < $data(colCount)} {incr oldCol; incr newCol} {
	moveColData data data imgs $oldCol $newCol
	moveColAttribs attribs attribs $oldCol $newCol
	set selCells [replaceColInCellList $selCells $oldCol $newCol]
    }

    #
    # Update the item list
    #
    set newItemList {}
    foreach item $data(itemList) {
	set item [lreplace $item $first $last]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Set up and adjust the columns, and rebuild some columns-related lists
    #
    setupColumns $win \
	[lreplace $data(-columns) [expr {3*$first}] [expr {3*$last + 2}]] 1
    makeColFontAndTagLists $win
    makeSortAndArrowColLists $win
    adjustColumns $win {} 1
    updateViewWhenIdle $win

    #
    # Reconfigure the relevant column labels
    #
    for {set col $first} {$col < $data(colCount)} {incr col} {
	reconfigColLabels $win imgs $col
    }

    #
    # Update the indices anchorCol and activeCol
    #
    set count [expr {$last - $first + 1}]
    if {$first <= $data(anchorCol)} {
	incr data(anchorCol) -$count
	if {$data(anchorCol) < $first} {
	    set data(anchorCol) $first
	}
	adjustColIndex $win data(anchorCol) 1
    }
    if {$last < $data(activeCol)} {
	incr data(activeCol) -$count
	adjustColIndex $win data(activeCol) 1
    } elseif {$first <= $data(activeCol)} {
	set data(activeCol) $first
	adjustColIndex $win data(activeCol) 1
    }
}

#------------------------------------------------------------------------------
# tablelist::insertRows
#
# Processes the tablelist insert and insertlist subcommands.
#------------------------------------------------------------------------------
proc tablelist::insertRows {win index argList updateListVar parentKey \
			    childIdx} {
    set argCount [llength $argList]
    if {$argCount == 0} {
	return {}
    }

    upvar ::tablelist::ns${win}::data data
    if {$index < $data(itemCount)} {
	displayItems $win
    }

    if {$index < 0} {
	set index 0
    } elseif {$index > $data(itemCount)} {
	set index $data(itemCount)
    }

    set childCount [llength $data($parentKey-children)]
    if {$childIdx < 0} {
	set childIdx 0
    } elseif {$childIdx > $childCount} {	;# e.g., if $childIdx is "end"
	set childIdx $childCount
    }

    #
    # Insert the items into the internal list
    #
    set result {}
    set appendingItems [expr {$index == $data(itemCount)}]
    set appendingChildren [expr {$childIdx == $childCount}]
    set row $index
    foreach item $argList {
	#
	# Adjust the item
	#
	set item [adjustItem $item $data(colCount)]

	#
	# Insert the item into the list variable if needed
	#
	if {$updateListVar} {
	    upvar #0 $data(-listvariable) var
	    trace vdelete var wu $data(listVarTraceCmd)
	    if {$appendingItems} {
		lappend var $item    		;# this works much faster
	    } else {
		set var [linsert $var $row $item]
	    }
	    trace variable var wu $data(listVarTraceCmd)
	}

	#
	# Get a free key for the new item
	#
	if {[llength $data(freeKeyList)] == 0} {
	    set key k[incr data(seqNum)]
	} else {
	    set key [lindex $data(freeKeyList) 0]
	    set data(freeKeyList) [lrange $data(freeKeyList) 1 end]
	}

	#
	# Insert the extended item into the internal list
	#
	lappend item $key
	if {$appendingItems} {
	    lappend data(itemList) $item	;# this works much faster
	    lappend data(keyList) $key		;# this works much faster
	} else {
	    set data(itemList) [linsert $data(itemList) $row $item]
	    set data(keyList) [linsert $data(keyList) $row $key]
	}

	array set data \
	      [list $key-row $row  $key-parent $parentKey  $key-children {}]

	#
	# Insert the key into the parent's list of children
	#
	if {$appendingChildren} {
	    lappend data($parentKey-children) $key    ;# this works much faster
	} else {
	    set data($parentKey-children) \
		[linsert $data($parentKey-children) $childIdx $key]
	}

	lappend data(rowsToDisplay) $row
	lappend result $key

	incr row
	incr childIdx
    }
    incr data(itemCount) $argCount
    set data(lastRow) [expr {$data(itemCount) - 1}]

    #
    # Update the key -> row mapping at idle time if needed
    #
    if {!$appendingItems} {
	set data(keyToRowMapValid) 0
	if {![info exists data(mapId)]} {
	    set data(mapId) \
		[after idle [list tablelist::updateKeyToRowMap $win]]
	}
    }

    if {![info exists data(dispId)]} {
	#
	# Arrange for the inserted items to be displayed at idle time
	#
	set data(dispId) [after idle [list tablelist::displayItems $win]]
    }

    #
    # Update the indices anchorRow and activeRow
    #
    if {$index <= $data(anchorRow)} {
	incr data(anchorRow) $argCount
	adjustRowIndex $win data(anchorRow) 1
    }
    if {$index <= $data(activeRow)} {
	set activeRow $data(activeRow)
	incr activeRow $argCount
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    }

    #
    # Update data(editRow) if the edit window is present
    #
    if {$data(editRow) >= 0} {
	set data(editRow) [keyToRow $win $data(editKey)]
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::displayItems
#
# This procedure is invoked either as an idle callback after inserting some
# items into the internal list of the tablelist widget win, or directly, upon
# execution of some widget commands.  It displays the inserted items.
#------------------------------------------------------------------------------
proc tablelist::displayItems win {
    #
    # Nothing to do if there are no items to display
    #
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(dispId)]} {
	return ""
    }

    #
    # Here we are in the case that the procedure was scheduled for
    # execution at idle time.  However, it might have been invoked
    # directly, before the idle time occured; in this case we should
    # cancel the execution of the previously scheduled idle callback.
    #
    after cancel $data(dispId)	;# no harm if data(dispId) is no longer valid
    unset data(dispId)

    #
    # Insert the items into the body text widget
    #
    variable canElide
    variable snipSides
    set w $data(body)
    set widgetFont $data(-font)
    set snipStr $data(-snipstring)
    set padY [expr {[$w cget -spacing1] == 0}]
    set wasEmpty [expr {[llength $data(rowsToDisplay)] == $data(itemCount)}]
    set isEmpty $wasEmpty
    foreach row $data(rowsToDisplay) {
	set line [expr {$row + 1}]
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]

	#
	# Format the item
	#
	set dispItem [lrange $item 0 $data(lastCol)]
	if {$data(hasFmtCmds)} {
	    set dispItem [formatItem $win $key $row $dispItem]
	}
	if {[string match "*\t*" $dispItem]} {
	    set dispItem [mapTabs $dispItem]
	}

	if {$isEmpty} {
	    set isEmpty 0
	} else {
	    $w insert $line.0 "\n"
	}
	if {$data(nonViewableRowCount) != 0} {
	    $w tag remove elidedRow $line.0
	    $w tag remove hiddenRow $line.0
	}
	set multilineData {}
	set col 0
	if {$data(hasColTags)} {
	    set insertArgs {}
	    foreach text $dispItem \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Update the column width or clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$multiline} {
			set list [split $text "\n"]
			set textWidth [getListWidth $win $list $colFont]
		    } else {
			set textWidth \
			    [font measure $colFont -displayof $win $text]
		    }
		    if {$data($col-maxPixels) > 0} {
			if {$textWidth > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		    if {$textWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$textWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $textWidth
			set data($col-widestCount) 1
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $colFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    if {$multiline} {
			set list [split $text "\n"]
			set snipSide \
			    $snipSides($alignment,$data($col-changesnipside))
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $colFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		lappend insertArgs "\t\t" $colTags
		if {$multiline} {
		    lappend multilineData $col $text $colFont $pixels $alignment
		}
		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    if {[llength $insertArgs] != 0} {
		eval [list $w insert $line.0] $insertArgs
	    }

	} else {
	    set insertStr ""
	    foreach text $dispItem {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Update the column width or clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$multiline} {
			set list [split $text "\n"]
			set textWidth [getListWidth $win $list $widgetFont]
		    } else {
			set textWidth \
			    [font measure $widgetFont -displayof $win $text]
		    }
		    if {$data($col-maxPixels) > 0} {
			if {$textWidth > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		    if {$textWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$textWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $textWidth
			set data($col-widestCount) 1
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $widgetFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    if {$multiline} {
			set list [split $text "\n"]
			set snipSide \
			    $snipSides($alignment,$data($col-changesnipside))
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $widgetFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		append insertStr "\t\t"
		if {$multiline} {
		    lappend multilineData $col $text $widgetFont \
					  $pixels $alignment
		}
		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    $w insert $line.0 $insertStr
	}

	#
	# Embed the message widgets displaying multiline elements
	#
	foreach {col text font pixels alignment} $multilineData {
	    findTabs $win $line $col $col tabIdx1 tabIdx2
	    set msgScript [list ::tablelist::displayText $win $key \
			   $col $text $font $pixels $alignment]
	    $w window create $tabIdx2 -align top -pady $padY -create $msgScript
	    $w tag add elidedWin $tabIdx2
	}
    }
    unset data(rowsToDisplay)

    #
    # Adjust the heights of the body text widget
    # and of the listbox child, if necessary
    #
    if {$data(-height) <= 0} {
	set viewableRowCount \
	    [expr {$data(itemCount) - $data(nonViewableRowCount)}]
	$w configure -height $viewableRowCount
	$data(lb) configure -height $viewableRowCount
    }

    #
    # Check whether the width of any column has changed
    #
    set colWidthsChanged 0
    set col 0
    foreach {pixels alignment} $data(colList) {
	if {$pixels == 0} {			;# convention: dynamic width
	    if {$data($col-elemWidth) > $data($col-reqPixels)} {
		set data($col-reqPixels) $data($col-elemWidth)
		set colWidthsChanged 1
	    }
	}
	incr col
    }

    #
    # Invalidate the list of row indices indicating the
    # viewable rows, adjust the columns if necessary, and
    # schedule some operations for execution at idle time
    #
    set data(viewableRowList) {-1}
    if {$colWidthsChanged} {
	adjustColumns $win {} 1
    }
    makeStripesWhenIdle $win
    showLineNumbersWhenIdle $win
    updateViewWhenIdle $win

    if {$wasEmpty} {
	$w xview moveto [lindex [$data(hdrTxt) xview] 0]
    }
}

#------------------------------------------------------------------------------
# tablelist::insertCols
#
# Processes the tablelist insertcolumns and insertcolumnlist subcommands.
#------------------------------------------------------------------------------
proc tablelist::insertCols {win colIdx argList} {
    set argCount [llength $argList]
    if {$argCount == 0} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs

    #
    # Check the syntax of argList and get the number of columns to be inserted
    #
    variable alignments
    set count 0
    for {set n 0} {$n < $argCount} {incr n} {
	#
	# Check the column width
	#
	format "%d" [lindex $argList $n]    ;# integer check with error message

	#
	# Check whether the column title is present
	#
	if {[incr n] == $argCount} {
	    return -code error "column title missing"
	}

	#
	# Check the column alignment
	#
	set alignment left
	if {[incr n] < $argCount} {
	    set next [lindex $argList $n]
	    if {[isInteger $next]} {
		incr n -1
	    } else {
		mwutil::fullOpt "alignment" $next $alignments
	    }
	}

	incr count
    }

    #
    # Shift the elements of data and attribs corresponding to the
    # column indices >= colIdx to the right by count positions
    #
    set selCells [curCellSelection $win]
    for {set oldCol $data(lastCol); set newCol [expr {$oldCol + $count}]} \
	{$oldCol >= $colIdx} {incr oldCol -1; incr newCol -1} {
	moveColData data data imgs $oldCol $newCol
	moveColAttribs attribs attribs $oldCol $newCol
	set selCells [replaceColInCellList $selCells $oldCol $newCol]
    }

    #
    # Update the item list
    #
    set emptyStrs {}
    for {set n 0} {$n < $count} {incr n} {
	lappend emptyStrs ""
    }
    set newItemList {}
    foreach item $data(itemList) {
	set item [eval [list linsert $item $colIdx] $emptyStrs]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Set up and adjust the columns, and rebuild some columns-related lists
    #
    setupColumns $win \
	[eval [list linsert $data(-columns) [expr {3*$colIdx}]] $argList] 1
    makeColFontAndTagLists $win
    makeSortAndArrowColLists $win
    set limit [expr {$colIdx + $count}]
    set colIdxList {}
    for {set col $colIdx} {$col < $limit} {incr col} {
	lappend colIdxList $col
    }
    adjustColumns $win $colIdxList 1

    #
    # Redisplay the items
    #
    redisplay $win 0 $selCells

    #
    # Reconfigure the relevant column labels
    #
    for {set col $limit} {$col < $data(colCount)} {incr col} {
	reconfigColLabels $win imgs $col
    }

    #
    # Update the indices anchorCol and activeCol
    #
    if {$colIdx <= $data(anchorCol)} {
	incr data(anchorCol) $argCount
	adjustColIndex $win data(anchorCol) 1
    }
    if {$colIdx <= $data(activeCol)} {
	incr data(activeCol) $argCount
	adjustColIndex $win data(activeCol) 1
    }

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::doScan
#
# Processes the tablelist scan subcommand.
#------------------------------------------------------------------------------
proc tablelist::doScan {win opt x y} {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    incr x -[winfo x $w]
    incr y -[winfo y $w]

    if {$data(-titlecolumns) == 0} {
	set textIdx [$data(body) index @0,$y]
	set row [expr {int($textIdx) - 1}]
	$w scan $opt $x $y
	$data(hdrTxt) scan $opt $x 0

	if {[string compare $opt "dragto"] == 0} {
	    adjustElidedText $win
	    redisplayVisibleItems $win
	    updateColors $win
	    adjustSepsWhenIdle $win
	    updateVScrlbarWhenIdle $win
	}
    } elseif {[string compare $opt "mark"] == 0} {
	$w scan mark 0 $y

	set data(scanMarkX) $x
	set data(scanMarkXOffset) \
	    [scrlColOffsetToXOffset $win $data(scrlColOffset)]
    } else {
	set textIdx [$data(body) index @0,$y]
	set row [expr {int($textIdx) - 1}]
	$w scan dragto 0 $y

	#
	# Compute the new scrolled x offset by amplifying the
	# difference between the current horizontal position and
	# the place where the scan started (the "mark" position)
	#
	set scrlXOffset \
	    [expr {$data(scanMarkXOffset) - 10*($x - $data(scanMarkX))}]
	set maxScrlXOffset [scrlColOffsetToXOffset $win \
			    [getMaxScrlColOffset $win]]
	if {$scrlXOffset > $maxScrlXOffset} {
	    set scrlXOffset $maxScrlXOffset
	    set data(scanMarkX) $x
	    set data(scanMarkXOffset) $maxScrlXOffset
	} elseif {$scrlXOffset < 0} {
	    set scrlXOffset 0
	    set data(scanMarkX) $x
	    set data(scanMarkXOffset) 0
	}

	#
	# Change the scrolled column offset and adjust the elided text
	#
	changeScrlColOffset $win [scrlXOffsetToColOffset $win $scrlXOffset]
	adjustElidedText $win
	redisplayVisibleItems $win
	updateColors $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::populate
#
# Helper procedure invoked in searchcolumnSubCmd.
#------------------------------------------------------------------------------
proc tablelist::populate {win index fully} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    set col $data(treeCol)
    if {![info exists data($key,$col-indent)] ||
	[string match "*indented*" $data($key,$col-indent)]} {
	return ""
    }

    if {[llength $data($key-children)] == 0} {
	uplevel #0 $data(-populatecommand) [list $win $index]
    }

    if {$fully} {
	#
	# Invoke this procedure recursively on the children
	#
	foreach childKey $data($key-children) {
	    populate $win [keyToRow $win $childKey] 1
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::doesMatch
#
# Helper procedure invoked in searchcolumnSubCmd.
#------------------------------------------------------------------------------
proc doesMatch {win row col pattern value mode numeric noCase checkCmd} {
    switch -- $mode {
	-exact {
	    if {$numeric} {
		set result [expr {$pattern == $value}]
	    } else {
		if {$noCase} {
		    set value [string tolower $value]
		}
		set result [expr {[string compare $pattern $value] == 0}]
	    }
	}

	-glob {
	    if {$noCase} {
		set value [string tolower $value]
	    }
	    set result [string match $pattern $value]
	}

	-regexp {
	    if {$noCase} {
		set result [regexp -nocase $pattern $value]
	    } else {
		set result [regexp $pattern $value]
	    }
	}
    }

    if {!$result || [string length $checkCmd] == 0} {
	return $result
    } else {
	return [uplevel #0 $checkCmd [list $win $row $col $value]]
    }
}

#------------------------------------------------------------------------------
# tablelist::seeRow
#
# Processes the tablelist see subcommand.
#------------------------------------------------------------------------------
proc tablelist::seeRow {win index} {
    #
    # This might be an "after 0" callback; check whether the window exists
    #
    if {![array exists ::tablelist::ns${win}::data]} {
	return ""
    }

    #
    # Adjust the index to fit within the existing items
    #
    adjustRowIndex $win index
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    if {$data(itemCount) == 0 || [info exists data($key-hide)]} {
	return ""
    }

    #
    # Expand as many ancestors as needed
    #
    while {[info exists data($key-elide)]} {
	set key $data($key-parent)
	expandSubCmd $win [list $key -partly]
    }

    #
    # Bring the given row into the window and restore
    # the horizontal view in the body text widget
    #
    if {![seeTextIdx $win [expr {double($index + 1)}]]} {
	return ""
    }
    $data(body) xview moveto [lindex [$data(hdrTxt) xview] 0]

    updateView $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::seeCell
#
# Processes the tablelist seecell subcommand.
#------------------------------------------------------------------------------
proc tablelist::seeCell {win row col} {
    #
    # This might be an "after 0" callback; check whether the window exists
    #
    if {![array exists ::tablelist::ns${win}::data]} {
	return ""
    }

    #
    # Adjust the row and column indices to fit within the existing elements
    #
    adjustRowIndex $win row
    adjustColIndex $win col
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    if {[info exists data($key-hide)] ||
	($data(colCount) != 0 && $data($col-hide))} {
	return ""
    }

    #
    # Expand as many ancestors as needed
    #
    while {[info exists data($key-elide)]} {
	set key $data($key-parent)
	expandSubCmd $win [list $key -partly]
    }

    set b $data(body)
    if {$data(colCount) == 0} {
	$b see [expr {double($row + 1)}]
	return ""
    }

    #
    # Force any geometry manager calculations to be completed first
    #
    update idletasks
    if {![array exists ::tablelist::ns${win}::data]} {
	return ""
    }

    #
    # If the tablelist is empty then insert a temporary row
    #
    set h $data(hdrTxt)
    if {$data(itemCount) == 0} {
	variable canElide
	for {set n 0} {$n < $data(colCount)} {incr n} {
	    if {!$data($n-hide) || $canElide} {
		$b insert end "\t\t"
	    }
	}

	$b xview moveto [lindex [$h xview] 0]
    }

    if {$data(-titlecolumns) == 0} {
	findTabs $win [expr {$row + 1}] $col $col tabIdx1 tabIdx2
	set nextIdx [$b index $tabIdx2+1c]
	set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	set lX [winfo x $data(hdrTxtFrLbl)$col]
	set rX [expr {$lX + [winfo width $data(hdrTxtFrLbl)$col] - 1}]

	switch $alignment {
	    left {
		#
		# Bring the cell's left edge into view
		#
		if {![seeTextIdx $win $tabIdx1]} {
		    return ""
		}
		$h xview moveto [lindex [$b xview] 0]

		#
		# Shift the view in the header text widget until the right
		# edge of the cell becomes visible but finish the scrolling
		# before the cell's left edge would become invisible
		#
		while {![isHdrTxtFrXPosVisible $win $rX]} {
		    $h xview scroll 1 units
		    if {![isHdrTxtFrXPosVisible $win $lX]} {
			$h xview scroll -1 units
			break
		    }
		}
	    }

	    center {
		#
		# Bring the cell's left edge into view
		#
		if {![seeTextIdx $win $tabIdx1]} {
		    return ""
		}
		set winWidth [winfo width $h]
		if {[winfo width $data(hdrTxtFrLbl)$col] > $winWidth} {
		    #
		    # The cell doesn't fit into the window:  Bring its
		    # center into the window's middle horizontal position
		    #
		    $h xview moveto \
		       [expr {double($lX + $rX - $winWidth)/2/$data(hdrPixels)}]
		} else {
		    #
		    # Shift the view in the header text widget until
		    # the right edge of the cell becomes visible
		    #
		    $h xview moveto [lindex [$b xview] 0]
		    while {![isHdrTxtFrXPosVisible $win $rX]} {
			$h xview scroll 1 units
		    }
		}
	    }

	    right {
		#
		# Bring the cell's right edge into view
		#
		if {![seeTextIdx $win $nextIdx]} {
		    return ""
		}
		$h xview moveto [lindex [$b xview] 0]

		#
		# Shift the view in the header text widget until the left
		# edge of the cell becomes visible but finish the scrolling
		# before the cell's right edge would become invisible
		#
		while {![isHdrTxtFrXPosVisible $win $lX]} {
		    $h xview scroll -1 units
		    if {![isHdrTxtFrXPosVisible $win $rX]} {
			$h xview scroll 1 units
			break
		    }
		}
	    }
	}

	$b xview moveto [lindex [$h xview] 0]

    } else {
	#
	# Bring the cell's row into view
	#
	if {![seeTextIdx $win [expr {double($row + 1)}]]} {
	    return ""
	}

	set scrlWindowWidth [getScrlWindowWidth $win]

	if {($col < $data(-titlecolumns)) ||
	    (!$data($col-elide) &&
	     [getScrlContentWidth $win $data(scrlColOffset) $col] <=
	     $scrlWindowWidth)} {
	    #
	    # The given column index specifies either a title column or
	    # one that is fully visible; restore the horizontal view
	    #
	    $b xview moveto [lindex [$h xview] 0]
	} elseif {$data($col-elide) ||
		  [winfo width $data(hdrTxtFrLbl)$col] > $scrlWindowWidth} {
	    #
	    # The given column index specifies either an elided column or one
	    # that doesn't fit into the window; shift the horizontal view to
	    # make the column the first visible one among all scrollable columns
	    #
	    set scrlColOffset 0
	    for {incr col -1} {$col >= $data(-titlecolumns)} {incr col -1} {
		if {!$data($col-hide)} {
		    incr scrlColOffset
		}
	    }
	    changeScrlColOffset $win $scrlColOffset
	} else {
	    #
	    # The given column index specifies a non-elided
	    # scrollable column; shift the horizontal view
	    # repeatedly until the column becomes visible
	    #
	    set scrlColOffset [expr {$data(scrlColOffset) + 1}]
	    while {[getScrlContentWidth $win $scrlColOffset $col] >
		   $scrlWindowWidth} {
		incr scrlColOffset
	    }
	    changeScrlColOffset $win $scrlColOffset
	}
    }

    #
    # Delete the temporary row if any
    #
    if {$data(itemCount) == 0} {
	$b delete 1.0 end
    }

    updateView $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::rowSelection
#
# Processes the tablelist selection subcommand.
#------------------------------------------------------------------------------
proc tablelist::rowSelection {win opt first last} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) && [string compare $opt "includes"] != 0} {
	return ""
    }

    switch $opt {
	anchor {
	    #
	    # Adjust the index to fit within the existing viewable items
	    #
	    adjustRowIndex $win first 1

	    set data(anchorRow) $first
	    return ""
	}

	clear {
	    #
	    # Swap the indices if necessary
	    #
	    if {$last < $first} {
		set tmp $first
		set first $last
		set last $tmp
	    }

	    set fromTextIdx [expr {$first + 1}].0
	    set toTextIdx [expr {$last + 1}].end
	    $data(body) tag remove select $fromTextIdx $toTextIdx

	    updateColorsWhenIdle $win
	    return ""
	}

	includes {
	    set w $data(body)
	    set line [expr {$first + 1}]
	    set selRange [$w tag nextrange select $line.0 $line.end]
	    return [expr {[llength $selRange] > 0}]
	}

	set {
	    #
	    # Swap the indices if necessary and adjust
	    # the range to fit within the existing items
	    #
	    if {$last < $first} {
		set tmp $first
		set first $last
		set last $tmp
	    }
	    if {$first < 0} {
		set first 0
	    }
	    if {$last > $data(lastRow)} {
		set last $data(lastRow)
	    }

	    set w $data(body)
	    variable canElide
	    variable elide
	    for {set row $first; set line [expr {$first + 1}]} \
		{$row <= $last} {set row $line; incr line} {
		#
		# Check whether the row is selectable
		#
		set key [lindex $data(keyList) $row]
		if {![info exists data($key-selectable)]} {
		    $w tag add select $line.0 $line.end
		}
	    }

	    #
	    # If the selection is exported and there are any selected
	    # cells in the widget then make win the new owner of the
	    # PRIMARY selection and register a callback to be invoked
	    # when it loses ownership of the PRIMARY selection
	    #
	    if {$data(-exportselection) &&
		[llength [$w tag nextrange select 1.0]] != 0} {
		selection own -command \
			[list ::tablelist::lostSelection $win] $win
	    }

	    updateColorsWhenIdle $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::moveTo
#
# Adjusts the view in the tablelist window win so that the non-hidden item
# given by data(fraction) appears at the top of the window.  
#------------------------------------------------------------------------------
proc tablelist::moveTo win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(moveToId)]} {
	after cancel $data(moveToId)
	unset data(moveToId)
    }

    set totalViewableCount \
	[expr {$data(itemCount) - $data(nonViewableRowCount)}]
    set offset [expr {int($data(fraction)*$totalViewableCount + 0.5)}]
    set row [viewableRowOffsetToRowIndex $win $offset]

    set w $data(body)
    set topTextIdx [$w index @0,0]
    set topRow [expr {int($topTextIdx) - 1}]
    foreach {x y width height baselinePos} [$w dlineinfo $topTextIdx] {}
    if {$y < 0} {
	incr topRow		;# top row incomplete in vertical direction
    }

    if {$row != $topRow} {
	if {[yviewTextRow $win $row]} {
	    updateView $win
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::seeTextIdx
#
# Wraps the "see" command of the body text widget of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::seeTextIdx {win textIdx} {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    $w see $textIdx

    if {[llength [$w tag nextrange elidedWin 1.0 end]] == 0} {
	return 1
    }

    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"
    $w tag remove elidedWin $fromTextIdx $toTextIdx
    update idletasks
    if {![array exists ::tablelist::ns${win}::data]} {
	return 0
    }

    $w see $textIdx
    return 1
}

#------------------------------------------------------------------------------
# tablelist::yviewTextRow
#
# Wraps the "yview <row>" command of the body text widget of the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::yviewTextRow {win row} {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    $w yview $row

    if {[llength [$w tag nextrange elidedWin 1.0 end]] == 0} {
	return 1
    }

    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"
    $w tag remove elidedWin $fromTextIdx $toTextIdx
    update idletasks
    if {![array exists ::tablelist::ns${win}::data]} {
	return 0
    }

    $w yview $row
    return 1
}

#
# Private callback procedures
# ===========================
#

#------------------------------------------------------------------------------
# tablelist::fetchSelection
#
# This procedure is invoked when the PRIMARY selection is owned by the
# tablelist widget win and someone attempts to retrieve it as a STRING.  It
# returns part or all of the selection, as given by offset and maxChars.  The
# string which is to be (partially) returned is built by joining all of the
# selected viewable elements of the (partly) selected viewable rows together
# with tabs and the rows themselves with newlines.
#------------------------------------------------------------------------------
proc tablelist::fetchSelection {win offset maxChars} {
    upvar ::tablelist::ns${win}::data data
    if {!$data(-exportselection)} {
	return ""
    }

    set selection ""
    set prevRow -1
    foreach cellIdx [curCellSelection $win 0 2] {
	scan $cellIdx "%d,%d" row col
	if {$row != $prevRow} {
	    if {$prevRow != -1} {
		append selection "\n"
	    }

	    set prevRow $row
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set isFirstCol 1
	}

	set text [lindex $item $col]
	if {[lindex $data(fmtCmdFlagList) $col]} {
	    set text [formatElem $win $key $row $col $text]
	}

	if {!$isFirstCol} {
	    append selection "\t"
	}
	append selection $text

	set isFirstCol 0
    }

    return [string range $selection $offset [expr {$offset + $maxChars - 1}]]
}

#------------------------------------------------------------------------------
# tablelist::lostSelection
#
# This procedure is invoked when the tablelist widget win loses ownership of
# the PRIMARY selection.  It deselects all items of the widget with the aid of
# the rowSelection procedure if the selection is exported.
#------------------------------------------------------------------------------
proc tablelist::lostSelection win {
    upvar ::tablelist::ns${win}::data data
    if {$data(-exportselection)} {
	rowSelection $win clear 0 $data(lastRow)
	event generate $win <<TablelistSelectionLost>>
    }
}

#------------------------------------------------------------------------------
# tablelist::activeTrace
#
# This procedure is executed whenever the array element data(activeRow),
# data(activeCol), or data(-selecttype) is written.  It moves the "active" tag
# to the line or cell that displays the active item or element of the widget in
# its body text child if the latter has the keyboard focus.
#------------------------------------------------------------------------------
proc tablelist::activeTrace {win varName index op} {
    #
    # Conditionally move the "active" tag to the line
    # or cell that displays the active item or element
    #
    upvar ::tablelist::ns${win}::data data
    if {$data(ownsFocus) && ![info exists data(dispId)]} {
	moveActiveTag $win
    }
}

#------------------------------------------------------------------------------
# tablelist::listVarTrace
#
# This procedure is executed whenever the global variable specified by varName
# is written or unset.  It makes sure that the contents of the widget will be
# synchronized with the value of the variable at idle time, and that the
# variable is recreated if it was unset.
#------------------------------------------------------------------------------
proc tablelist::listVarTrace {win varName index op} {
    upvar ::tablelist::ns${win}::data data
    switch $op {
	w {
	    if {![info exists data(syncId)]} {
		#
		# Arrange for the contents of the widget to be synchronized
		# with the value of the variable ::$varName at idle time
		#
		set data(syncId) [after idle [list tablelist::synchronize $win]]
	    }
	}

	u {
	    #
	    # Recreate the variable ::$varName by setting it according to
	    # the value of data(itemList), and set the trace on it again
	    #
	    if {[string length $index] != 0} {
		set varName ${varName}($index)
	    }
	    set ::$varName {}
	    foreach item $data(itemList) {
		lappend ::$varName [lrange $item 0 $data(lastCol)]
	    }
	    trace variable ::$varName wu $data(listVarTraceCmd)
	}
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/scripts/tclIndex.

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
# Tcl autoload index file, version 2.0
# This file is generated by the "auto_mkindex" command
# and sourced to set up indexing information for one or
# more commands.  Typically each line is a command that
# sets an element in the auto_index array, where the
# element name is the name of a command and the value is
# a script that loads the command.

set auto_index(::tablelist::addTkCoreWidgets) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addTileWidgets) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addBWidgetEntry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addBWidgetSpinBox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addBWidgetComboBox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrEntryfield) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrDateTimeWidget) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrSpinner) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrSpinint) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addCtext) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addOakleyCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addDateMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addTimeMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addDateTimeMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addFixedPointMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIPAddrMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIPv6AddrMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::checkEditWinName) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createCheckbutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createMenubutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::postMenuCmd) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileEntry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileSpinbox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileCheckbutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileMenubutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createBWidgetComboBox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createIncrCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createOakleyCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::doEditCell) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::doCancelEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::doFinishEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::clearTakefocusOpt) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::adjustTextHeight) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::setMentryCursor) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::adjustEditWindow) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::setEditWinFont) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::saveEditData) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::saveEditConfigOpts) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::restoreEditData) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::restoreEditConfigOpts) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::defineTablelistEdit) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::insertChar) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::cancelEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::finishEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goToNextPrevCell) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goLeftRight) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goUpDown) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goToPrevNextLine) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goToPriorNextPage) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::genMouseWheelEvent) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::genOptionMouseWheelEvent) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::isKeyReserved) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::hasMouseWheelBindings) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::isComboTopMapped) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::getCurrentTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::setThemeDefaults) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::altTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::aquaTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::AquativoTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::blueTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::clamTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::classicTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::defaultTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::keramikTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::keramik_altTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::krocTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::plastikTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::srivTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::srivlgTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::stepTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::tileqtTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::vistaTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::winnativeTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::winxpblueTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::xpnativeTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::rgb2hsv) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::hsv2rgb) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::getKdeConfigVal) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::makeKdeDirList) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::readKdeConfigVal) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::sortByColumn) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::addToSortColumns) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::sortItems) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::sortChildren) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::sortList) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::compareNoCase) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::moveRow) [list source [file join $dir tablelistMove.tcl]]
set auto_index(::tablelist::moveNode) [list source [file join $dir tablelistMove.tcl]]
set auto_index(::tablelist::moveCol) [list source [file join $dir tablelistMove.tcl]]
set auto_index(::mwutil::makeFocusProcs) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::getChildren) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::wrongNumArgs) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::getAncestorByClass) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::convEventFields) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::defineKeyNav) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::processTraversal) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::configureWidget) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::fullConfigOpt) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::fullOpt) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::enumOpts) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::configureSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::attribSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::hasattribSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::unsetattribSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::getScrollInfo) [list source [file join $dir mwutil.tcl]]
set auto_index(::tablelist::rowIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::colIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::cellIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustRowIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustColIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::nodeIndexToKey) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::depth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::topLevelKey) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::descCount) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::nodeRow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::keyToRow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateKeyToRowMap) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::findTabs) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::sortStretchableColList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::deleteColData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::deleteColAttribs) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::moveColData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::moveColAttribs) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::deleteColFromCellList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::extractColFromCellList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::replaceColInCellList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::condUpdateListVar) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::reconfigColLabels) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::charsToPixels) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::strRange) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustItem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::formatElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::formatItem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hasChars) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getListWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::joinList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::displayIndent) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::displayImage) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::displayText) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getAuxData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getIndentData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getMaxTextWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustMlElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getElemWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::insertOrUpdateIndent) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::insertElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::insertMlElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateCell) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateMlCell) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::setImgLabelWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::setImgLabelAnchor) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::appendComplexElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeColFontAndTagLists) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeSortAndArrowColLists) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::setupColumns) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::createSeps) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustSepsWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustSeps) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getSepX) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustColumns) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustLabel) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::computeColWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::computeLabelWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustHeaderHeight) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::stretchColumnsWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::stretchColumns) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::moveActiveTag) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateColorsWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateColors) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateScrlColOffsetWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateScrlColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateHScrlbarWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateHScrlbar) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateVScrlbarWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateVScrlbar) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::forceRedraw) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::purgeWidgets) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustElidedText) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplay) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayVisibleItems) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayColWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayCol) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeStripesWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeStripes) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::showLineNumbersWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::showLineNumbers) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateViewWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateView) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::destroyWidgets) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::synchronize) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getSublabels) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::parseLabelPath) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::configLabel) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::createArrows) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::configCanvas) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::fillArrows) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getShadows) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::raiseArrow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::isHdrTxtFrXPosVisible) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getScrlContentWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getScrlWindowWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getMaxScrlColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::changeScrlColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::scrlXOffsetToColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::scrlColOffsetToXOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getViewableRowCount) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::viewableRowOffsetToRowIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getTablelistColumn) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::getTablelistPath) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::convEventFields) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::addActiveTag) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::removeActiveTag) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cleanup) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateCanvases) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateConfigSpecs) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cleanupWindow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistBody) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::invokeMotionHandler) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::handleMotionDelayed) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::handleMotion) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::showOrHideTooltip) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateExpCollCtrl) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateCursor) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::makeEditCursor) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::wasExpCollCtrlClicked) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condEditContainingCell) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condBeginMove) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::beginSelect) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condAutoScan) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::autoScan) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::minScrollableX) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::motion) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condShowTarget) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::moveOrActivate) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condEvalInvokeCmd) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cancelMove) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::beginExtend) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::beginToggle) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condEditActiveCell) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::plusMinus) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::nextPrevCell) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::upDown) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::leftRight) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::priorNext) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::homeEnd) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::firstLast) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendUpDown) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendLeftRight) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendToHomeEnd) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendToFirstLast) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cancelSelection) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::selectAll) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::isDragSrc) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::normalizedRect) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cellInRect) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::firstViewableRow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::lastViewableRow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::firstViewableCol) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::lastViewableCol) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condChangeSelection) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::changeSelection) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistSubLabel) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistArrow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelEnter) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelLeave) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Down) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Motion) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Enter) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Leave) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Up) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB3Down) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelDblB1) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::escape) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::horizAutoScan) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::inResizeArea) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendConfigSpecs) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doColConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doColCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doRowConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doRowCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doCellConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doCellCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::makeListVar) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::isRowViewable) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::getCellFont) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::reconfigWindows) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::isCellEditable) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::getEditWindow) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::getVAlignment) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::flat5x3Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat5x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat6x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat7x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat7x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat7x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat8x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat8x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat9x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat9x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat11x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat15x8Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle7x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle7x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle9x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle9x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle9x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle10x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle10x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle11x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle15x8Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo7x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo7x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo9x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo11x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo15x8Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::sunken8x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::sunken10x9Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::sunken12x11Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createSortRankImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createCheckbuttonImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::adwaitaTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ambianceTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::aquaTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::baghiraTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor3TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor4TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic3TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic4TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::dustTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::dustSandTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::gtkTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::klearlooksTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::mateTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::mintTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::mint2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::newWaveTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::oxygen1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::oxygen2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::phaseTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain3TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain4TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plastikTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plastiqueTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::radianceTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ubuntuTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ubuntu2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_100) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_125) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_150) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_200) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_100) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_125) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_150) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_200) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win7AeroTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win7ClassicTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_100) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_125) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_150) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_200) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winnativeTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winxpBlueTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winxpOliveTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winxpSilverTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::yuyoTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createTileAliases) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::restrictCmdOpts) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::restrictArrowStyles) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::createBindings) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::tablelist) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::tablelistWidgetCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::activateSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::activatecellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::applysortingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::attribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::bboxSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::bodypathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::bodytagSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cancelededitingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::canceleditingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellbboxSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellcgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellindexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellselectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::childcountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::childindexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::childkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::collapseSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::collapseallSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columncgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columncountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnindexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnwidthSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcelllistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configrowlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configrowsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cornerlabelpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cornerpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curcellselectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curselectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deleteSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deletecolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::depthSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::descendantcountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editinfoSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editwinpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editwintagSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::entrypathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::expandSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::expandallSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::expandedkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::fillcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::findcolumnnameSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::findrownameSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::finisheditingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::formatinfoSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getformattedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getformattedcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getformattedcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getfullkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hasattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hascellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hascolumnattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hasrowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hidetargetmarkSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::imagelabelpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::indexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertchildlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertchildrenSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertcolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::iselemsnippedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::isexpandedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::istitlesnippedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::isviewableSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::itemlistvarSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::labelpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::labelsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::labeltagSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::moveSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::movecolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::nearestSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::nearestcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::nearestcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::noderowSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::parentkeySubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::refreshsortingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rejectinputSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::resetsortinfoSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowcgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::scanSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::searchcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seecellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seecolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::selectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::separatorpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::separatorsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::showtargetmarkSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sizeSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortbycolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortbycolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortcolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortorderSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortorderlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::targetmarkpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::targetmarkposSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::togglecolumnhideSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::togglerowhideSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::toplevelkeySubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetcellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetcolumnattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetrowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::viewablerowcountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::windowpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::xviewSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::yviewSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::colWidth) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingRow) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingCol) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curCellSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deleteRows) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deleteCols) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertRows) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::displayItems) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertCols) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::doScan) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::populate) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(doesMatch) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeRow) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeCell) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::moveTo) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeTextIdx) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::yviewTextRow) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::fetchSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::lostSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::activeTrace) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::listVarTrace) [list source [file join $dir tablelistWidget.tcl]]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted libs/tablelist5.16/tablelist.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#==============================================================================
# Main Tablelist package module.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tcl 8
package require Tk  8
package require -exact tablelist::common 5.16

package provide tablelist $::tablelist::version
package provide Tablelist $::tablelist::version

::tablelist::useTile 0
::tablelist::createBindings
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted libs/tablelist5.16/tablelistPublic.tcl.

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
#==============================================================================
# Main Tablelist and Tablelist_tile package module.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

namespace eval ::tablelist {
    #
    # Gets the scaling percentage (100, 125, 150, or 200).
    #
    proc scalingPercentage {} {
	set factor [tk scaling]
	if {$factor < 1.50} {
	    return 100 
	} elseif {$factor < 1.83} {
	    return 125 
	} elseif {$factor < 2.33} {
	    return 150 
	} else {
	    return 200
	}
    }

    #
    # Public variables:
    #
    variable version	5.16
    variable library
    if {$tcl_version >= 8.4} {
	set library	[file normalize [DIR]]
    } else {
	set library	[DIR]			;# no "file normalize" yet
    }
    variable scalingpct	[scalingPercentage]

    #
    # Creates a new tablelist widget:
    #
    namespace export	tablelist

    #
    # Sort the items of a tablelist widget by one or more of its columns:
    #
    namespace export	sortByColumn addToSortColumns

    #
    # Helper procedures used in binding scripts:
    #
    namespace export	convEventFields getTablelistPath getTablelistColumn

    #
    # Register various widgets for interactive cell editing:
    #
    namespace export	addBWidgetEntry addBWidgetSpinBox addBWidgetComboBox
    namespace export    addIncrEntryfield addIncrDateTimeWidget \
			addIncrSpinner addIncrSpinint addIncrCombobox
    namespace export	addCtext addOakleyCombobox
    namespace export	addDateMentry addTimeMentry addDateTimeMentry \
			addFixedPointMentry addIPAddrMentry addIPv6AddrMentry
}

package provide tablelist::common $::tablelist::version

#
# The following procedure, invoked in "tablelist.tcl" and "tablelist_tile.tcl",
# sets the variable ::tablelist::usingTile to the given value and sets a trace
# on this variable.
#
proc ::tablelist::useTile {bool} {
    variable usingTile $bool
    trace variable usingTile wu [list ::tablelist::restoreUsingTile $bool]
}

#
# The following trace procedure is executed whenever the variable
# ::tablelist::usingTile is written or unset.  It restores the variable to its
# original value, given by the first argument.
#
proc ::tablelist::restoreUsingTile {origVal varName index op} {
    variable usingTile $origVal
    switch $op {
	w {
	    return -code error "it is not allowed to use both Tablelist and\
				Tablelist_tile in the same application"
	}
	u {
	    trace variable usingTile wu \
		  [list ::tablelist::restoreUsingTile $origVal]
	}
    }
}

interp alias {} ::tk::frame {} ::frame
interp alias {} ::tk::label {} ::label

#
# Everything else needed is lazily loaded on demand, via the dispatcher
# set up in the subdirectory "scripts" (see the file "tclIndex").
#
lappend auto_path [file join $::tablelist::library scripts]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted libs/tablelist5.16/tablelist_tile.tcl.

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
#==============================================================================
# Main Tablelist_tile package module.
#
# Copyright (c) 2000-2016  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tcl 8.4
package require Tk  8.4
if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
    package require tile 0.6
}
package require -exact tablelist::common 5.16

package provide tablelist_tile $::tablelist::version
package provide Tablelist_tile $::tablelist::version

::tablelist::useTile 1
::tablelist::createBindings

namespace eval ::tablelist {
    #
    # Commands related to tile themes:
    #
    namespace export	getThemes getCurrentTheme setTheme setThemeDefaults
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































Added libs/tablelist6.0/CHANGES.txt.









































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
What is new in Tablelist 6.0?
-----------------------------

1. Added support for header items (aka title rows) with the aid of the
   new "header", "headerpath", and "headertag" subcommands.  The first
   one supports a great number of subcommands itself, like
   "insert(list)", "delete", "size", "rowconfigure", "cellconfigure",
   "get(formatted)", "get(formatted)cells", etc. (thanks to Hemang
   Lavana, Kenneth Green, and Ralf Fassel for their proposals).  The
   demo scripts "embeddedWindows.tcl" and "embeddedWindows_tile.tcl" now
   contain invocations of "header insert" and "header rowconfigure".

2. Added the "embed(ttk)checkbutton" and "embed(ttk)checkbuttons"
   subcommands, which provide interactive cell editing with the aid of
   persistently embedded checkbuttons (thanks to Mark Garvey and Holger
   Jakobs for their proposal).  The Tablelist Programmer's Guide now
   contains an example of usage of the "embedcheckbuttons" subcommand.

3. Compatibility with the revised implementation of the text widget,
   which will be contained in Tk 8.7 (thanks to Brad Lanam, Gregor
   Cramer, and Francois Vogel for their valuable assistance).

4. The "dicttoitem" and "itemtodict" subcommands are now supported in
   the presence of alternative, Tcl-only "dict" implementations, too
   (thanks to Andy Goth for his proposal).

5. Deleting all items has become by orders of magnitude faster (thanks
   to Martin Lemburg for requesting this performance improvement).

6. Guarded against invocations of the "update" command from within the
   command specified as the value of the "-tooltipaddcommand" option
   (thanks to Alexandru Dadalau for his bug report and discussions on
   this subject).

7. Made sure that the "xview" and "yview" subcommands work as expected
   even if the script was started from wthin a C application in which
   the decimal point is different from "." (thanks to Paul Obermeier for
   his bug report).

8. Numerous further improvements in the code, demo scripts, and
   documentation.

What was new in Tablelist 5.18?
-------------------------------

1. Improved the performance of the vertical scrolling (thanks to
   Alexandru Dadalau and Olivier Jolet for discussions on this subject).

2. Added the "-displayondemand" configuration option, which can be used
   to speed up the scrolling even further.

3. Added the "tablelist::delaySashPosUpdates" command (described in the
   manual page "Commands Related to Binding Scripts"), designed to
   control the frequency of the sash position updates for a given
   panedwindow widget, which might be necessary to eliminate some
   artifacts if some of the panes contain tablelist widgets with
   embedded images (thanks to Nicolas Robert for his input).

4. Added support for the themes "Arc" and "clearlooks"; updated the
   support for the themes "Aquativo", "blue", "clam","keramik",
   "keramik_alt", and "plastik".

5. Extended the reference manual by the description of an important use
   case for the "-formatcommand" column configuration option, related to
   tablelist columns whose "-sortmode" option was set to "integer" or
   "real" (thanks to Alexandru Dadalau for discussions on this subject).

6. Fixed a bug related to retrieving the current cell selection (thanks
   to Alexandru Dadalau for his bug report).

7. Fixed a bug related to excluding the "dicttoitem" and "itemtodict"
   subcommands for Tk 8.4 and earlier (thanks to Andy Goth for his bug
   report).

8. Numerous further improvements in the code, demo scripts, and
   documentation.

What was new in Tablelist 5.17?
-------------------------------

1. Added the tree styles "arc", "blueMenta", "menta", "ubuntuMate", and
   "ubuntu3", inspired by the Arc icon theme (of the GTK 2/3 theme Arc)
   and some GTK 3 themes of the latest versions of the MATE desktop and
   Ubuntu Linux distribution, respectively.

2. Added the "dicttoitem" and "itemtodict" subcommands (thanks to Denis
   Rheault for his proposal).

3. Support for the new virtual event <<TablelistViewUpdated>>,
   generated when the tablelist widget has finished updating its view
   (thanks to Martyn Smith for his proposal).

4. Added the boolean variable tablelist::strictTk, which controls the
   strict listbox-compatibility of the default bindings.  If its value
   is false (which is the default) then <Control-Button-1> now toggles
   the selection state of the item or element under the mouse in all
   selection modes, and <Control-space> and <Control-Select> toggle the
   selection state of the active item or element (thanks to Alexandru
   Dadalau for discussions on a related subject).

5. The default bindings on X11 and Windows now support the keyboard
   shortcuts <Control-a> and <Shift-Control-A> as alternatives to the
   key sequences <Control-slash> (for "Select All") and
   <Control-backslash> (for "Deselect All") (thanks to Juge, Alexandru
   Dadalau, Christian Gollwitzer, Rich, and Andreas Leitgeb for
   discussions on a related subject).

6. Improvements related to vertical scrolling, especially in the
   presence of embedded images or multi-line elements (thanks to Olivier
   Jolet for discussions on this subject).

7. Improvements in the documentation (thanks to Adam Jensen for his
   input).

What was new in Tablelist 5.16?
-------------------------------

1.  Added the "-autofinishediting" configuration option, relevant for
    interactive cell editing via a combobox or menubutton widget (thanks
    to Alexandru Dadalau for his proposal).

2.  On Windows Vista, 7, 8, and 10, the sort arrows are now shown
    horizontally centered in the header labels and attached to their top
    edges.

3.  Added the arrow style "photo7x4" as well as its automatically scaled
    versions "photo9x5", "photo11x6", and "photo15x8", used as defaults
    on Windows Vista, 7, and 8.

4.  Added the tree style "mint2", suiting version 18 of the Linux Mint
    distribution.

5.  Support for fully qualified edit window names of the form "::ttk::*"
    (thanks to Adrian Medrano Calvo for his proposal).

6.  Worked around a text widget issue introduced in Tk 8.6.6 (thanks to
    Peter Spjuth, Harald Oehlmann, and Rene Zaumseil for their valuable
    input).

7.  Improvements related to the "move" and "movecolumn" subcommands as
    well as to the management of the images used in sort arrows (thanks
    to Adrian Medrano Calvo and Torsten Berg for their proposals).

8   Drastically increased the speed of the "collapse" and "collapseall"
    subcommands with the "-fully" option (thanks to Ulrich Seidl for
    reporting the pure performance of "collapseall -fully").

9.  Adapted the implementation of the "delete" subcommand to the changed
    text widget behavior in Tk 8.6.5 (thanks to Ulrich Seidl for his bug
    report).

10. Fixed a bug related to the "curcellselection" subcommand (thanks to
    Juge for his bug report).

What was new in Tablelist 5.15?
-------------------------------

1. Support for Windows 10, including the new tree style "win10", whose
   size is automatically adapted to the display's scaling level.

2. Added the arrow styles "flatAngle11x6" and "flatAngle15x8", needed
   for automatic scaling of the default arrow style "flatAngle7x4" on
   Windows 10.

3. The variable "tablelist::scalingpct", used by Tablelist when adapting
   the sizes of several tree styles to the display's DPI scaling level,
   is now documented in Tablelist Programmer's Guide.

4. Worked around a text widget bug introduced in Tk 8.5.18 and 8.6.4
   (fixed for the next Tk versions).

5. Fixed a bug that prevented the subcommands "see end", "see last", and
   "yview moveto 1" from working as expected if the tablelist widget
   contains multi-line cells or large images (thanks to Harald Oehlmann
   for his bug report and to Francois Vogel for discussions on this
   subject).

What was new in Tablelist 5.14?
-------------------------------

1. Added the "-colorizecommand" configuration option, enabling you to
   change the colors of arbitrary character regions within the cells of
   the currently visible tablelist rows (thanks to Peter Spjuth for his
   proposal).

2. The "curcellselection" and "curselection" subcommands now accept an
   optional argument with the possible values "-all", "-nonhidden", and
   "-viewable" (thanks to Will Duquette for his proposal).

3. Added the tree styles "plain1", ..., "plain4", "bicolor1", ...,
   "bicolor4", and "classic1", ..., "classic4", suitable for use with
   large fonts and images (needed on high-resolution displays).  In
   addition, the sizes used by the tree styles "vistaAero",
   "vistaClassic", "win7Aero", and "win7Classic" are now automatically
   adapted to the display's scaling level (thanks to Harald Oehlmann for
   his proposal).

4. On Windows Vista and later, automatic scaling is now performed for
   the default arrow style, too.  This made is necessary to add the
   arrow styles "flat11x6" and "flat15x8".

5  Added the arrow style "flat8x4" and the tree style "ubuntu2", suiting
   version 15.04 of the Ubuntu Linux distribution.  Similarly, added the
   tree style "yuyo", inspired by the GTK+ theme Yuyo on Ubuntu MATE.

6. Changed the default arrow color "" and arrow style "sunken10x9" to
   "black" and "flat7x5" on the windowing system "x11" and for the tile
   themes "alt", "clam", "default", "kroc", "sriv", "srivlg", and "step"
   (POTENTIAL INCOMPATIBILITY!).

7. In case of "-selecttype cell", the row containing the active cell is
   now displayed with raised relief (thanks to Holger Jakobs for his
   proposal).

8. Guarded against invocations of the "update" command from within
   binding scripts associated with the <<TablelistSelect>> virtual
   event (thanks to Martyn Smith for his bug report and discussions on
   this topic).

9. Worked around some unexpected events in certain X11 environments,
   which prevented Tablelist 5.13 from starting the interactive cell
   editing in such environments (thanks to Toni Giorgino for his bug
   report and helping me to reproduce this problem).

What was new in Tablelist 5.13?
-------------------------------

1. Added support for Mac OS X 10.10 (Yosemite) (thanks to Kevin Walzer
   for his proposal).

2. Renamed the four arrow styles having the shape of an angle from
   "flat7x5", ..., "flat10x6" to "flatAngle7x5", ..., "flatAngle10x6"
   (POTENTIAL INCOMPATIBILITY!); added the arrow styles "flat7x5",
   "flat9x6", "flatAngle7x4" (which is now the default on Yosemite),
   "flatAngle9x5", and "flatAngle10x7".

3. Added the tree style "mate", inspired by a few GTK+ themes of the
   MATE desktop.

4. Added the "-showeditcursor" configuration option, used to let the
   cursor take on the shape of a pencil whenever a mouse click would
   start an editing session (thanks to Rene Zaumseil and Cesare
   Bavazzano for their proposals).

5. New column configuration option "-changetitlesnipside", which allows
   you to override the alignment-specific default snip side for the
   column's title (thanks to John Vella for his proposal).

6. Support for the word "last" as row, column, cell, or child index,
   indicating the last row/column/cell of the tablelist or the last
   child of a given parent node (remember that the meaning of "end" as a
   row, column, or child index is subcommand-specific).

7. The description of the "imagelabelpath" subcommand in the reference
   manual now contains an example showing how to define bindings for the
   embedded images.

8. Eliminated the endless loop generated by the "yview" subcommand when
   synchronizing two or more tablelist widgets (thanks to Paul Obermeier
   for his bug report).

What was new in Tablelist 5.12.1?
---------------------------------

This is a bugfix-only release.  The corrected files in the "scripts"
directory are "tablelistEdit.tcl" and "tablelistUtil.tcl".

1. Appended the missing 4th argument to the two invocations of the
   procedure "tablelist::moveOrActivate" in the file
   "tablelistEdit.tcl" (thanks to Patrick Fradin and Ralf Fassel for
   their bug reports).

2. Fixed a typo in the file "tablelistUtil.tcl" (thanks to Patrick
   Fradin for reporting this bug).

What was new in Tablelist 5.12?
-------------------------------

1. Added the "-customdragsource" configuration option, used to indicate
   whether the tablelist widget is a drag source for some drag & drop
   implementation other than TkDND and the drag & drop framework
   included in BWidget.

2. Improvements and extensions in the default binding scripts.  Besides
   providing full compatibility with the Tk listbox, they now perform an
   automatic drag-friendly handling of the selection and of pointer
   movements with mouse button 1 down if the "-customdragsource" option
   was set to true or the tablelist's body was registered as a TkDND or
   BWidget drag source (thanks to Will Duquette for his proposal).  The
   same holds true for the local drag & drop via the "move" subcommand.

3. Added the "hidetargetmark", "showtargetmark", "targetmarkpath", and
   "targetmarkpos" subcommands, for enhanced drop target support (thanks
   to Trevor Williams for his proposal).

4. Added a "Drag & Drop Support" section to the reference manual, with
   examples demonstrating the use of the new subcommands mentioned
   above in a tablelist widget registered as a TkDND or BWidget drop
   target.

5. The visibility of the horizontal separator placed just below the last
   tablelist row if the value of the "-showseparators" option is true
   and that of the "-fullseparators" option is false, can now be 
   controlled with the aid of the new "-showhorizseparator"
   configuration option (thanks to Martyn Smith for his proposal).

6. New values "flat5x3" and "flat5x4" for the "-arrowstyle"
   configuration option, suiting current versions of the Ubuntu Linux
   distribution.

7. Adapted the look & feel of the tree styles "adwaita", "ubuntu", and
   "mint" to current versions of the GTK+ 3 theme Adwaita and of the
   Linux distributions Ubuntu Linux and Linux Mint, respectively.

8. Fixed a long-standing bug related to horizontal scrolling in an empty
   tablelist widget with positve "-titlecolumns" value (thanks to Ulrich
   Seidl for his bug report).

What was new in Tablelist 5.11?
-------------------------------

1. Added the "findrowname" and "findcolumnname" subcommands (thanks to
   Adrian Medrano Calvo for his proposal and discussions on this
   subject).

2. Collapsing a row no longer leads to renumbering the lines for the
   purpose of updating a column configured to display the line numbers
   (thanks to Will Duquette for his proposal).

3. For improved appearance, if the value of the "-showseparators" option
   is true and that of the "-fullseparators" option is false, then a
   horizontal separator is now placed just below the last tablelist row
   (thanks to Allan Silverstein for his proposal).

4. Worked around a peculiarity of Tk on Windows, which caused problems
   when resizing the tablelist window in the presence of embedded images
   or multi-line elements (thanks to Will Duquette for his bug report).

5. Added the missing actualization of the active and anchor row indices
   after moving an item to a different position (thanks to Will Duquette
   for his bug report).

6. Fixed two bugs in Tablelist_tile, related to header labels with
   embedded images (thanks to Ulrich Seidl for his bug reports).

7. Numerous further improvements in the code and documentation.

What was new in Tablelist 5.10?
-------------------------------

1.  Added the "-acceptdropcommand" configuration option, used to control
    whether the local drag & drop may move a specified item just before
    a given row (thanks to Nagu and Georgios Petasis for discussions on
    this subject).

2.  Added the "-instanttoggle" configuration option, related to the cell
    editing with the aid of a Tk or tile checkbutton (thanks to Rich
    Wellner for his proposal and discussions on this topic).

3.  Added the "-tight" configuration option, used to eliminate the
    one-pixel additional space left below each tablelist row for Tk
    listbox compatibility (thanks to Koen Breugelmans for his proposal
    and discussions on this subject).

4.  Added the "isviewable" and "viewablerowcount" subcommands (thanks to
    Nagu for proposing the latter).

5.  Improvements related to the value of the "-data" option for the
    virtual events <<TablelistColumnMoved>> and <<TablelistRowMoved>>
    (thanks to Georgios Petasis for discussions on this topic).

6.  The item deletion has become significantly faster, especially in
    tablelists used as tree widgets and in the presence of embedded
    images and/or multi-line elements (thanks to Rob Ratcliff and Rene
    Zaumseil for requesting this performance improvement).

7.  Guarded against column deletions from within non-default binding
    scripts for the header labels (thanks to Ulrich Seidl for his
    input).

8.  Restored the support for Tcl/Tk versions earlier than 8.3, by
    cleaning up the use of elided text in the underlying text widget.
    Similarly, restored the support for Tcl/Tk 8.0, by cleaning up the
    use of "regsub" and that of the <MouseWheel> event (thanks to Joerg
    Mueck for reporting the first two issues).

9.  Improved the package loading mechanism (thanks to Paul Obermeier for
    his bug report).

10. Guarded against potential item insertions or deletions from within
    the command specified as the value of the "-editendcommand" option
    (thanks to Julian H J Loaring for his bug report).

11. Guarded against deletion of embedded images or windows from within
    the command specified as the value of the "-tooltipaddcommand"
    option (thanks to Jan Kandziora for his bug report).

12. Fixed a bug related to column deletion if the "-selecttype" option
    has the value "cell" (thanks to Ulrich Seidl for his bug report).

13. Several further code improvements and minor bug fixes.

What was new in Tablelist 5.9?
------------------------------

1. Added the "-valign" column and cell configuration option, for
   controlling the vertical alignment of embedded images and windows
   (thanks to Trevor Williams for his proposal).

2. The "-stripebackground" and "-stripeforeground" options can now be
   specified at column level, too (thanks to Christian Gollwitzer for
   his proposal).

3. Improvements related to the Windows 7 platform.

4. Worked around a text widget bug in Tk versions 8.5 and later, related
   to getting the index of the last line in the window if some of the
   lines are elided (thanks to Bernhard Wallner for his bug report).

5. Corrected a typo in the implementation of the "rowconfigure"
   subcommand, introduced in the last Tablelist version (thanks to Jerzy
   Witkowski for reporting this bug).

6. Fixed a bug related to resetting the "-(select)background" and
   "-(select)foreground options at column, row, and cell levels,
   introduced in the previous Tablelist version (thanks to Christian
   Gollwitzer for his bug report).

7. Several further improvements in the code, demo scripts, and
   documentation.

What was new in Tablelist 5.8?
------------------------------

1.  Support for interactive cell editing with the aid of the ctext
    widget (thanks to Sait Dogru for his proposal).

2.  Added the "canceledediting" subcommand (thanks to Martyn Smith for
    his proposal).

3.  The "selection" and "cellselection" subcommands have become by
    orders of magnitude faster (thanks to Jean-Francois Beaud for his
    input that motivated me to speed up these subcommands).

4.  The "-(select)background" and "-(select)foreground options at
    column, row, and cell levels now impose by far less performance
    penalty than in earlier Tablelist versions.

5.  The keyboard traversal during interactive cell editing is now aware
    of changes like appending a new row, performed by the procedure
    specified as the value of the "-editendcommand" configuration option
    (thanks to Andreas Leitgeb for his proposal).

6.  For Tk versions 8.5 or later, most virtual events are now generated
    with the "-data" option set to a suitable event-specific value
    (thanks to Christian Gollwitzer, Andreas Leitgeb, and Nagu for their
    proposals).

7.  Improvements related to the selection mode "extended".

8.  Worked around a peculiarity of Tk on Windows, related to deleting an
    embedded window while resizing a text widget interactively (thanks
    to Harald Oehlmann for his bug report and discussions on this
    topic).

9.  Eliminated a regression introduced in Tablelist version 5.6, related
    to vertical scrolling under Tk 8.5 or later in the presence of
    embedded images or windows (thanks to Patrick Fradin for reporting
    this bug).

10. Fixed a screen refresh problem introduced in Tablelist version 5.6,
    related to wrapped multiline elements (thanks to Rob for his bug
    report).

11. Further code improvements (thanks to Harald Oehlmann for his
    valuable contribution).

12. Added a "Virtual Events" section to the reference manual (thanks to
    Andreas Leitgeb for his proposal).

What was new in Tablelist 5.7?
------------------------------

1.  Added the "cellbbox" subcommand.

2.  Added the "editinfo" subcommand (thanks to Trevor Williams for his
    proposal).

3.  Adapted the tree styles "ubuntu" and "mint" to the latest Ubuntu
    Linux and Linux Mint releases.

4.  Minor change related to the ttk::combobox widget used as edit window
    (thanks to Julian H J Loaring for his input).

5.  Improved the multi-platform support by increased use of virtual
    events.

6.  Worked around a bug in some earlier Tk versions, related to
    checkbuttons without indicator (thanks to Allan Silverstein for his
    input).

7.  Restored the support for Tcl/Tk versions earlier than 8.4, which has
    been broken since the previous Tablelist release, due to the use of
    the "namespace exists" command, introduced in Tcl 8.4 (thanks to
    Ralf Fassel for drawing my attention to this issue).

8.  Fixed a copy & paste bug related to embedded windows, introduced in
    the previous Tablelist version (thanks to Heng Li and David Hanks
    for their bug reports).

9.  Fixed a long-standing bug related to the "cancelediting" subcommand
    and the "-forceeditendcommand" option (thanks to Julian H J Loaring
    for his bug report).

10. Fixed a long-standing minor bug that caused the "-labelbg" column
    configuration option to be accepted by Tablelist_tile, contrary to
    the option of the same name at widget level (thanks to Bernhard
    Wallner for his bug report).

11. Several further improvements in the code and demo scripts (thanks to
    Patrick Fradin for his valuable contribution and to Marianne Baumann
    for her input related to the "-showlabels" option).

What was new in Tablelist 5.6?
------------------------------

1.  Added the tree styles "adwaita", "mint", and "ubuntu", inspired by a
    few GTK+ 3 themes on popular Linux distributions.

2.  Added the "-windowupdate" cell configuration option (thanks to
    Trevor Williams for his valuable contribution).

3.  The item insertion and sorting have become significantly faster,
    especially when using static-width columns.

4.  Embedded windows are now hidden during interactive cell editing
    (thanks to Trevor Williams for discussions on this subject).

5.  Extended the support for the "tileqt" theme to work on KDE 4, too.

6.  Improvements in the documentation (thanks to Glenn Herteg for his
    proposal).

7.  Guarded against the case that a tablelist widget is deleted and its
    name is reused for a widget of a different class (thanks to Roger
    Niva for his valuable input).

8.  Guarded against scripts that start by destroying all children of the
    root window (thanks to Helmut Giese and Gerhard Kraus for drawing my
    attention to this case).

9.  Fixed two bugs related to the "move" subcommand, introduced in
    Tablelist version 5.2 (thanks to "DrS" and Trevor Williams for their
    bug reports).

10. Several further improvements and minor bug fixes.

What was new in Tablelist 5.5?
------------------------------

1. Hidden tablelist elements are no longer excluded from the selection
   (thanks to Martyn Smith for his proposal).  (They are, however,
   ignored when exporting the selection.)

2. Added the "cornerpath" and "cornerlabelpath" subcommands.  The first
   one makes it quite easy to respect the native Mac OS X look & feel,
   where the vertical scrollbar appears placed under the header (thanks
   to Torsten Berg for a related page on the Wiki, which provided me the
   idea for these subcommands).  The "cornerpath" subcommand is now used
   in all demo scrips that contain vertical scrollbars.

3. Added support for the appearance-related changes introduced in Mac
   OS X 10.7 (Lion).

4. On Mac OS X Aqua, the default values of the "-move(column)cursor"
   and "-resizecursor" options are now native cursors.  Besides
   improving the look & feel of tablelist widgets on the Mac, this
   change also works around the problem that on Mac OS X 10.7, Tk
   versions 8.5 and 8.6 can only use native and native-mapped cursors.

5. Removed the "-labelbackground" option from Tablelist_tile, because
   current versions of the tile engine no longer support setting the
   background color for the header labels (and even with earlier tile
   versions, some themes ignored any attempt to change the background
   color of the header labels).

6. Adapted the code to some changes in current tile versions, to make
   sure that in disabled state the tile-based column labels will appear
   in the theme-specific disabled foreground color, as it was the case
   with earlier tile versions (thanks to "tombert" for his related
   posting on comp.lang.tcl).

7. Improved a few binding scripts (thanks to Ulrich Seidl for his bug
   report and testing).

8. Fixed a bug related to embedded windows in a tablelist used as a
   tree widget (again, thanks to Ulrich Seidl for his bug report and
   testing).

9. Several further improvements in the code, demo scripts, and
   documentation.

What was new in Tablelist 5.4?
------------------------------

1. Added the "-populatecommand" configuration option, used by the
   "searchcolumn" subcommand to insert child items on demand before
   checking whether they contain the specified pattern.
   
2. Added the "-autoscan" configuration option, which can be used to
   deactivate the automatic scrolling triggered by leaving the
   tablelist window with mouse button 1 down, in order to avoid any
   conflicts with drag & drop via tkdnd (thanks to Patrick Fradin for
   his valuable contribution).

3. New "isexpanded" subcommand.

4. New value "flat9x6" for the "-arrowstyle" configuration option.

5. Adapted the tree style "oxygen2" to the look of current KDE 4
   versions.

6. Worked around some peculiarities of Tk on Mac OS X Aqua (thanks to
   Torsten Berg for her problem report and discussions on this topic).

7. Improved the check for PNG support in Tk (thanks to Ian Gay for his
   posting on the Wiki related to this subject).

8. Fixed a bug related to the tree style "aqua", introduced in
   Tablelist version 5.3 (thanks to Julian H J Loaring for his bug
   report).

9. Numerous further improvements in the code and documentation.

What was new in Tablelist 5.3.1?
--------------------------------

This release contains just one bug-fix and an enhancement:

1. Fixed a bug related to the "-hide" row configuration option,
   introduced in the previous Tablelist version (thanks to Ralf Fassel
   and Michal Sosnowski for their bug reports).

2. Extended the support for the native "Aqua-blue" background for the
   header label of the sort column (which in the previous Tablelist
   release was restricted to Tk versions 8.6 and above) to the Cocoa-
   based Tk patch levels 8.5.9 and above (thanks to Kevin Walzer for
   discussions on this topic and to Paul Obermeier for enabling me to
   access the ActiveTcl 8.5.8 distribution for the Mac).

What was new in Tablelist 5.3?
------------------------------

1. The interactive row move operation (i.e., local drag & drop) now
   supports moving an item outside its parent and dropping it under
   another item as a child (thanks to Dr. Detlef Groth for his
   proposal, thorough testing, and discussions on this topic).

2. Added the "-acceptchildcommand" configuration option, related to the
   local drag & drop.

3. New "searchcolumn" subcommand, supporting a rich set of options
   (thanks to Matthew Callaghan, Adrian Davis, and Jeff Godfrey for
   their proposals).

4. New "getformatted", "getformattedcolumns", and "getformattedcells"
   subcommands.

5. Support for interactive cell editing with the aid of the Tk core and
   tile menubutton widgets (thanks to Georgios Petasis for his
   proposal).

6. Support for the row indices "top" and "bottom" (thanks to Julian H J
   Loaring and Paul Obermeier for their proposals).  Likewise, support
   for the column indices "left" and "right".

7. New value "photo7x7" for the "-arrowstyle" configuration option,
   needed for the "aqua" theme.

8. Adapted the appearance of tablelist widgets on the Macintosh to
   current versions of OS X Aqua.

9. Numerous further improvements and minor bug fixes.

What was new in Tablelist 5.2?
------------------------------

1.  Added the "-fullseparators" configuration option (thanks to Kevin
    Partin, Martyn Smith, and Harald Oehlmann for their proposals).

2.  Added the tree styles "ambiance", "dust", "dustSand", "newWave",
    "plastik", and "radiance".

3.  The implementation of the "collapse(all)" and "expand(all)"
    subcommands no longer makes use of the "-hide" row configuration
    option, hence you are now free to set the latter (via
    "rowconfigure", "configrowlist", "configrows", or "togglerowhide"),
    regardless of whether the tablelist widget displays a tree
    hierarchy or just a plain list.

4.  The "move" subcommand now supports moving an item outside its
    parent.

5.  Deleting the whole content of a tablelist widget has become
    significantly faster (thanks to Harold Campbell for his input).

6.  Worked around a peculiarity of the text widget related to tag
    handling when deleting a range of lines from its end (thanks to
    Batox for his bug report).

7.  Minor improvements and bug-fixes in the binding scripts (thanks to
    Bernhard Wallner, Batox, and Roger Niva for their bug reports).

8.  Fixed a bug related to the "-selecttype cell" configuration option,
    (re)introduced in Tablelist version 5.0 (thanks to Harold Campbell
    and Dietmar Mueller for their bug reports).

9.  Fixed a bug related to row hiding via "configrowlist" or
    "configrows", introduced in Tablelist version 5.0 (thanks to Michal
    Sosnowski for his bug report).

10. Fixed a long-standing bug related to tooltip support (thanks to
    Trevor Williams for his bug report).

11. Several further improvements and minor bug fixes.

What was new in Tablelist 5.1?
------------------------------

This is a bugfix-only release.  The corrected files in the "scripts"
directory are "tablelistBind.tcl", "tablelistSort.tcl",
"tablelistUtil.tcl", and "tablelistWidget.tcl".

1. Fixed a bug related to item deletion, introduced in the previous
   Tablelist version (thanks to Aric Bills and Roger Niva for their bug
   reports).

2. Fixed a bug related to multi-column sorting, introduced in the
   previous Tablelist version (thanks to Albrecht Mucha for his bug
   report).

3. Fixed a long-standing bug related to column deletion (thanks to
   Liang Sian Yin for his bug report).

4. Fixed a few further minor bugs and typos, introduced in the previous
   Tablelist version (thanks to Patrick Fradin, Roger Niva, Harald
   Oehlmann, and Peter Spjuth for their bug reports).

What was new in Tablelist 5.0?
------------------------------

1.  A tablelist widget is now not only a multi-column listbox, but also
    a multi-column tree widget (thanks to Sebastien Barre, Tillmann
    Basien, Jos Decoster, Dr. Detlef Groth, Kai Morich, Georgios
    Petasis, and Kevin Walzer for their proposals, as well as to Paul
    Obermeier for testing the preliminary version).  This is achieved
    with the aid of the new configuration options "-collapsecommand",
    "-expandcommand", "-treecolumn", and "-treestyle", along with the
    new subcommands "childcount", "childindex", "childkeys", "collapse",
    "collapseall", "depth", "descendantcount", "expand", "expandall",
    "expandedkeys", "insertchild(ren)", "insertchildlist", "noderow",
    "parentkey", and "toplevelkey".

2.  Added the "-editselectedonly" configuration option, related to
    starting the interactive cell editing with mouse button 1 (thanks to
    Julian H J Loaring for discussions on this topic).

3.  New values "flat6x4", "flat9x7", and "flat10x6" for the
    "-arrowstyle" configuration option.

4.  New value "asciinocase" for the "-sortmode" column configuration
    option.

5.  New subcommands "applysorting", "getfullkeys", and "refreshsorting".

6.  Two new demo scripts (and their tile-based counterparts)
    illustrating the use of a tablelist as multi-column tree widget.

7.  The subcommands "insert", "insertlist", "insertchild(ren)", and
    "insertchildlist" now return the list of full keys corresponding to
    the items just inserted.

8.  Fixed a long-standing bug related to the "-labelfont" option (thanks
    to Jacek Jendrysik for his bug report).

9.  Fixed a bug related to the "-text" column configuration option
    (thanks to Paul Obermeier for his bug report).

10. Fixed a long-standing bug related to embedded windows in right-
    aligned columns (thanks to Jerzy Witkowski for his bug report).

11. Numerous further improvements in the code and documentation.

What was new in Tablelist 4.12?
-------------------------------

1.  Added the "labeltag" subcommand and the helper command "tablelist::
    getTablelistColumn", designed to be used in non-default binding
    scripts for the header labels.

2.  Support for interactive cell editing with the aid of the tile
    spinbox widget.  The demo script "tileWidgets.tcl" now uses this
    widget when available.

3.  Support for interactive cell editing with the aid of the new mentry
    widget for IPv6 addresses.

4.  Improved the support for Windows Vista and added explicit support
    for the "vista" theme.

5.  Updated the support for the themes "plastik" and "keramik"; added
    support for the "keramik_alt" theme.

6.  Support for the native "Aqua-blue" background, set for the header
    label of the sort column (thanks to Kevin Walzer for his proposal
    and valuable contribution).  For technical reasons, this feature is
    only supported for Mac-Tk versions using Cocoa.

7.  Further improvements in the support for Mac OS X Aqua (thanks to
    Daniel Steffen and Kevin Walzer for their valuable feedback).

8.  Improvements in the binding scripts related to interactive cell
    editing (thanks to Hadas Porat for discussions on this subject).

9.  The binding for the <Double-Button-1> event in the resize area of a
    column header now works as expected for large lists, too.

10. Eliminated a minor regression related to interactive cell editing,
    introduced in the previous Tablelist version (thanks to Kai Morich
    for his valuable input).

11. Fixed a small bug related to interactive cell editing with the aid
    of a text widget (thanks to Bryan Oakley for his bug report and
    valuable suggestion).

12. Fixed a long-standing bug related to the "-listvariable" option in
    disabled state (thanks to Ralf Fassel for his bug report).

13. Added a version-related hint to the "How to use it?" section of the
    Tablelist Programmer's Guide.

What was new in Tablelist 4.11?
-------------------------------

1.  Added the "-columntitles" configuration option, which is mainly a
    simplified form of the "-columns" option (thanks to Roy Terry for
    his proposal).

2.  Added the virtual events <<TablelistColHiddenStateChanged>> and
    <<TablelistRowHiddenStateChanged>>, generated after toggling the
    hidden state of a column or row, respectively (thanks to Jeff 
    Godfrey for his proposal).

3.  Besides with <Button-3>, the optimal column width can now be set
    with <Double-Button-1> in the resize area of the column's header.
    Similarly, the effect of <Shift-Button-3> can also be achieved with
    <Shift-Double-Button-1> in the column label's resize area.

4.  Support for Windows Vista (thanks to Jeremy Cowgar for his input).

5.  The recommended package name is now "tablelist" rather than
    "Tablelist", for compatibility with the ActiveTcl distribution; the
    demo scripts have been changed accordingly.

6.  Made sure that the "-tooltipdelcommand" configuration option won't
    affect other widgets (thanks to Jeff Godfrey for drawing my
    attention to this issue).

7.  Fixed a long-standing nasty bug related to the "yview" subcommand
    (thanks to Nestor Patino for his bug report and very helpful example
    script).

8.  Fixed two bugs related to the "-listvariable" configuration option
    (again, thanks to Nestor Patino for his valuable input).

9.  Fixed a bug related to the item deletion when using Tcl/Tk 8.5
    (thanks to Jos Decoster and Sven Wuytack for their valuable
    contribution to finding and fixing this bug).

10. Fixed a bug related to the "-windowdestroy" cell configuration
    option, introduced in Tablelist 4.9 (thanks to Sebastien Barre for
    his bug report).

What was new in Tablelist 4.10?
-------------------------------

1.  Support for individual binding scripts controlling the interactive
    cell editing, with the aid of the new "editwintag" subcommand
    (thanks to Oscar Fuentes for his valuable input).

2.  Complemented the "attrib" subcommand with the new subcommands
    "hasattrib" and "unsetattrib".

3.  Support for column-, row-, and cell-specific attributes, with the
    aid of the new subcommands "columnattrib", "hascolumnattrib",
    "unsetcolumnattrib", "rowattrib", "hasrowattrib", "unsetrowattrib",
    "cellattrib", "hascellattrib", and "unsetcellattrib".

4.  Support for interactive cell editing with the aid of the new mentry
    widget of type "DateTime", introduced in version 3.2 of the Mentry
    package (thanks to Florian Murr for his proposal).

5.  Made sure that the default bindings are set up immediately when
    loading the package, prior to creating any tablelist widget (thanks
    to Schelte Bron for his proposal and discussions on this topic).

6.  Re-established the support for tile widgets as edit windows in non-
    tile-based tablelist widgets (again, thanks to Schelte Bron for
    reporting that this was broken in the last few Tablelist versions).

7.  Adapted the handling of the tile checkbutton as edit window in the
    "xpnative" theme to some changes made in tile 0.8 (thanks to Jeff
    Godfrey for his bug report).

8.  Guarded against potential widget deletion from within user-defined
    binding scripts or "update (idletasks)" (thanks to Schelte Bron and
    Jan Kandziora for their bug reports).

9.  Updated the (very rarely needed) distribution file "repair.tcl" to
    work with current Tablelist versions (thanks to Robert Stollf for
    his bug report).

10. Corrected the description of the "-height" option in the reference
    manual (thanks to Glenn Herteg for his bug report concerning the
    case "-height 0").

11. Improved the color handling in the "disabled" state (thanks to Rolf
    Ade for his bug report and discussions on this topic).

12. Made the handling of elided text more robust (thanks to Jos Decoster
    for his bug report and valuable contribution).

13. Several further improvements and minor bug fixes (thanks to Albrecht
    Mucha for his valuable input).

What was new in Tablelist 4.9?
------------------------------

1.  Added the "-wrap" column configuration option, which makes it
    possible to display long texts in word-wrapped multi-line rather
    than snipped form (thanks to Alexander Schoepe and Anant Adke for
    their proposals).  Also, added support for interactive cell editing
    with a word- or char-wrapped text widget when using Tk 8.5 (thanks
    to Juberi Rajib for discussions on this topic).

2.  Support for dynamic-width embedded windows, with the aid of the new
    "-stretchwindow" cell configuration option (thanks to Kurt Kurczyk,
    Bryan Oakley, and Rasmus Debitsch for their proposals). The demo
    script "embeddedWindows.tcl" and its tile-based counterpart now make
    use of this option.

3.  New "formatinfo" subcommand, returning information about the cell
    whose content is being formatted by a command specified as the value
    of the "-formatcommand" column configuration option (thanks to Goran
    Ivankovic and Sebastien Barre for their proposals).

4.  Changed the default value of the "-activestyle" configuration option
    from "underline" to "frame" and that of the "-setfocus" option from
    0 to 1, making them conform to similar changes in Tk 8.5 related to
    the listbox widget.

5.  Improved the appearance of the header labels for the "aqua" theme
    (thanks to Torsten Berg for discussing this topic on the Wiki).

6.  Eliminated the potential invocation of the "unknown" command from
    within the Tablelist code (thanks to Roger Niva for discussions on
    this topic).

7.  When starting the interactive cell editing with the aid of a
    combobox widget, the list associated with the latter is only dropped
    down if the combobox is read-only (thanks to Bryan Oakley for his
    proposal).

8.  The "setThemeDefaults" command no longer throws an error if the
    current theme is not explicitly supported by Tablelist.  Instead, it
    uses the options set by the current theme and falls back to the
    "default" one for the rest (thanks to Schelte Bron for his valuable
    contribution).

9.  Improved the tablelist widget's appearance when the header labels
    are not shown (thanks to Mark Garvey for his input).

10. Fixed two bugs related to the optimized item insertion (thanks to
    Harold Campbell and Bryan Oakley for their bug reports).

11. Fixed a bug related to the "-showlinenumbers" column configuration
    option (thanks to Martin Lemburg for his bug report).

12. Several further improvements and minor bug fixes.

What was new in Tablelist 4.8?
------------------------------

This release fixes a few nasty bugs related to the optimized item
insertion, introduced in the previous Tablelist version (thanks to
Harold Campbell, Roger Niva, and Joerg Klingseisen for their bug
reports).

What was new in Tablelist 4.7?
------------------------------

1.  Significant performance improvements related to the "insert",
    "rowconfigure", "sort", "sortbycolumn", and "sortbycolumnlist"
    subcommands (thanks to Harold Campbell for his valuable
    contribution to speeding up the item insertion).  The extent of the
    speed-up depends on the configuration options present at column,
    row, and cell levels.

2.  Support for cell- and column label-specific balloon help, with the
    aid of the new configuration options "-tooltipaddcommand" and
    "-tooltipdelcommand".

3.  New subcommands "iselemsnipped" and "istitlesnipped", which make it
    very easy to display the full cell texts and column titles as
    tooltips for cells and header labels with snipped contents.

4.  New subcommands "configcolumnlist", "configcolumns",
    "configrowlist", "configrows", "configcelllist", and "configcells",
    which allow you to configure several columns/rows/cells with a
    single command invocation (thanks to Harold Campbell, Jeff Godfrey,
    and Paul Obermeier for their proposals).

5.  Worked around some performance problems regarding the "switch"
    command in Tcl 8.5a6/8.5b1 and ActiveTcl 8.4.14.

6.  Made sure that ActiveState's "style::as" package won't break the
    mousewheel bindings (thanks to Michael Schlenker for drawing my
    attention to this problem).

7.  Improved the focus handling when resizing a column interactively
    (thanks to Jorge Enderr for his bug report).

8.  Corrected a typo in the adaptation of vertical scrolling to the
    text widget changes made in Tk 8.5 (thanks to Julian M Noble for
    his posting on the Wiki related to this subject).

9.  Fixed a bug related to hidden rows when having "-selecttype cell",
    introduced in Tablelist version 4.3 (thanks to Harold Campbell for
    his bug report and discussions on this subject).

10. Fixed a bug in the "cellconfigure" subcommand, introduced in the
    previous Tablelist release (thanks to Roy Terry for reporting this
    problem on the Wiki).

11. Fixed a bug in the "-changesnipside" option (thanks to Kai Morich
    for his bug report).

12. Numerous further improvements in the code and documentation.

What was new in Tablelist 4.6?
------------------------------

1.  Tablelist_tile now supports tile 0.8 and Tk 8.5a6/8.5b1 (where tile
    is integrated in the core).  The new commands "tablelist::setTheme",
    "tablelist::getCurrentTheme", and "tablelist::getThemes" enable you
    to set and get the current theme and to query the available ones,
    without having to worry about the incompatibilities between the
    various tile versions.

2.  New column configuration option "-changesnipside", which allows you
    to override the alignment-specific default snip side (thanks to
    Georgios Petasis for his proposal).

3.  New "columnwidth" subcommand, with the options "-requested",
    "-stretched", and "-total" (thanks to Matthew Callaghan, Richard
    Finstad, Lieven Forrez, and Tom Roeder for their proposals).

4.  Support for the new virtual event <<TablelistColumnResized>>,
    generated after resizing a column interactively (thanks to Kurt
    Kurczyk for his proposal).

5.  Visual improvement:  Within an active row, the gap to the left or
    right of an embedded image or window no longer appears underlined
    (when the "-activestyle" option has its default value "underline").

6.  Embedded images and windows are no longer hidden during interactive
    cell editing (except the editing with the aid of a Tk or tile
    checkbutton widget).

7.  Significantly improved the redraw and stretching behavior when
    resizing a column interactively.

8.  Eliminated some annoying visual effects caused by hidden columns
    when displaying the items of an already visible tablelist widget
    (thanks to Rolf Ade for discussions on this topic).

9.  Adapted the implementation of vertical scrolling to the text widget
    changes made in Tk 8.5 (thanks to Julian M Noble for his posting on
    the Wiki related to this subject).

10. Fixed a bug related to hidden rows, introduced in Tablelist version
    4.3 (thanks to Matthew Callaghan for his bug report).

11. Eliminated the possible endless loop caused by some option database
    settings in the "seecell" subcommand (thanks to Erik Allaert and
    Mauro Comin for reporting this bug).

12. Added a detailed performance-related hint to the description of the
    "-listvariable" configuration option.

13. Numerous further improvements and minor bug fixes.

What was new in Tablelist 4.5?
------------------------------

1.  Static-width columns are now displayed much faster than in earlier
    Tablelist releases.

2.  Quite significantly reduced the performance penalty imposed by
    various column, row, and cell configuration options when sorting,
    redisplaying, moving, or deleting tablelist items.

3.  Embedded images are now handled much more efficiently and are
    displayed much faster than in earlier Tablelist versions.

4.  New column configuration option "-showlinenumbers" (thanks to Rolf
    Schroedter and Sean Xu for their proposals and to Kathrin Klaes for
    testing the implementation).

5.  Support for tile-based multi-entry widgets (introduced in Mentry
    3.0) used as edit windows.

6.  Significantly improved the handling of the <<ThemeChanged>> virtual
    event.

7.  Defined more reasonable windowing system- and theme-specific default
    values for the "-arrowdisabledcolor" option.

8.  Improved and simplified the package loading mechanism (thanks to
    Andreas Kupries for his valuable contribution).

9.  Eliminated the "togglevisibility" subcommand, which was deprecated
    in the previous Tablelist version in favor of "togglecolumnhide".

10. Fixed a bug in the implementation of the "deletecolumns" subcommand,
    introduced in the previous Tablelist release (thanks to Kai Morich,
    Kurt Kurczyk, and Dave Leslie for their bug reports).

11. Fixed two binding-related bugs (thanks to Mark Garvey and Kurt
    Kurczyk for their bug reports).

12. Fixed a bug related to the handling of the "tileqt" theme (thanks to
    Andres Garcia for his bug report).

13. Fixed a small but annoying bug related to the "-maxwidth" column
    configuration option, introduced in the previous Tablelist version.

14. Numerous further improvements and minor bug fixes (thanks to
    Patrick Fradin and Georgios Petasis for their valuable feedback).

What was new in Tablelist 4.4?
------------------------------

1.  New row configuration option "-hide" (thanks to Jeff Godfrey,
    Patrick Fradin. Hemang Lavana, and Martyn Smith for their
    proposals, and especially to Harold Campbell for providing the
    initial implementation and testing the final one.)  For performance
    reasons this option is implemented by using elided text in the
    underlying text widget, and therefore it is not supported for Tk
    versions earlier than 8.3.

2.  New subcommand "togglerowhide" for hiding/unhiding several rows at
    a time (not supported for Tk versions earlier than 8.3).

3.  Renamed the "togglevisibility" subcommand to "togglecolumnhide".
    The old name is still supported, but will be eliminated in the next
    Tablelist release.

4.  New command "tablelist::setThemeDefaults", which can be used to
    make sure that classical Tk widgets, e.g., text, will have a theme-
    specific appearance, just like the tile widgets.  The tile-based
    demo scripts now make use of this command.

5.  When using the "tileqt" theme, the version number of TileQt must be
    0.3 or higher (thanks to Georgios Petasis for providing the new
    "tileqt" features used in this Tablelist release).

6.  For Tk 8.3 or later, hidden columns are now handled by using elided
    text, which results in very significant performance improvements
    (thanks to Harold Campbell for his valuable contribution).

7.  Improved the handling of the "-listvariable" option in connection
    with snit widgetadaptors (thanks to Rolf Ade for his bug-fix).

8.  Corrected a typo in the implementation of the "move" subcommand,
    introduced in the previous release (thanks to Jerome Siot for his
    bug report).

9.  Improved the handling of the virtual event <<ThemeChanged>> (thanks
    to Wofgang Grosser for his bug report).

10. Fixed a long-standing bug related to hidden columns (thanks to Dave
    Leslie for his bug report).

11. Worked around a peculiarity of the "place" command on Windows,
    which caused refresh problems in column labels with images (thanks
    to Sebastien Barre for his bug report).

12. Numerous further improvements and minor bug fixes.

What was new in Tablelist 4.3?
------------------------------

1. Support for multi-line cells:  Newline characters now force line
   breaks when displaying the items (thanks to Sebastien Barre,
   Tillmann Basien, Cameron Laird, Kai Morich, and Vaclav Snajdr for
   their proposals).  In addition, interactive cell editing can now
   take place with the aid of a text widget, too (this has caused a few
   minor changes in the default key bindings for the edit window).

2. Support for multi-column sorting with the aid of the new subcommands
   "sortbycolumnlist", "sortcolumnlist", and "sortorderlist", as well
   as of the new command "tablelist::addToSortColumns".  The latter is
   designed to be specified as the value of the new widget and column
   configuration option "-labelcommand2", whose value is invoked on 
   <Shift-Button-1> events.  Multi-column sorting is visualized by
   means of multiple sort arrows, which are displayed together with the
   corresponding sort ranks.  (Thanks to Harold Campbell for proposing
   most of these features, providing the initial implementation, and
   testing the final one.)

3. New configuration option "-setfocus", specifying whether mouse
   button 1 should set the focus to the tablelist's body (thanks to
   Tillmann Basien for discussions on this topic).

4. Replaced the contents of the directory "images" with a script file
   containing procedures that create the bitmap images from inline data
   (thanks to Mats Bengtsson, Patrick Fradin, and Kai Morich for their
   proposals).

5. Fixed a bug related to the use of a tile entry within a non-tile-
   based tablelist widget on Windows XP (thanks to Schelte Bron for his
   bug report).

6. The handling of <Command-Key> events during interactive cell editing
   is now explicitly restricted to Mac OS Classic and Mac OS X Aqua,
   because, strangely enough, on Windows these events are generated by
   simple keypresses if Num Lock is active.

7. Numerous further code improvements, minor bug-fixes, and support for
   several recent changes in tile.

8. Cleaned up the documentation, to make sure that the HTML files
   generated for the ActiveTcl distribution with the tool HTML Tidy
   will be syntactically identical to the original ones.

What was new in Tablelist 4.2?
------------------------------

1.  The resize area of the header labels now consists of a few pixels
    on both sides of the right edge (thanks to Bryan Oakley for
    suggesting this improvement).

2.  Made sure that the header labels have the right appearance in the
    "aqua" theme when using tile version 0.6.4 or later (thanks to
    Bryan Oakley for his bug report).

3.  Several further improvements related to Mac OS X Aqua (for example,
    support for the "Command" key during keyboard navigation between
    the editable cells).

4.  Fixed a very long-standing bug in the "containing" subcommand
    (thanks to Mats Bengtsson, Schelte Bron, and Mark Garvey for their
    bug reports).

5.  Fixed a bug related to the "xpnative" theme, introduced in the
    previous release (thanks to Mark Garvey, Jeff Godfrey, and Uwe
    Koloska for their bug reports).

6.  Fixed another very long-standing bug, related to insertion and
    deletion of columns having images in their labels (thanks to
    Sebastien Barre for his bug report).

7.  Fixed an old bug related to embedding images or windows into hidden
    cells (again, thanks to Sebastien Barre for reporting this bug).

8.  The demo scripts now work independently of their location (this
    small improvement reflects the fact that Tablelist is now included
    in tklib, where the examples are in a location different from
    "$tablelist::library/demos").

9.  Adapted two tile-based demo scripts to the recently released tile
    version 0.7.

10. Several further improvements in the code and documentation (thanks
    to Patrick Fradin for his valuable contribution).

What was new in Tablelist 4.1?
------------------------------

1.  Significantly extended the tile support in the Tablelist_tile
    package:  Header labels now look and behave like the column
    headings of treeview widgets, and over a dozen configuration
    options have theme-specific default values (thanks to Paul
    Obermeier for his excellent "poImgview" application, which helped
    me a lot during this work, as well as to Georgios Petasis for his
    Qt-related hints).

2.  Header labels containing the mouse cursor are now set into active
    state.  Their appearance is controlled in the Tablelist package by
    the new configuration options "-labelactivebackground" and
    "-labelactiveforeground", while the Tablelist_tile package uses
    theme-specific background and foreground colors for the active and
    pressed states of the labels.

3.  New configuration option "-arrowstyle", specifying the flat or
    sunken relief and the dimensions of the arrow indicating the
    sorting order.  This option has windowing system- and theme-
    specific default values.

4.  New configuration option "-protecttitlecolumns", used to protect
    the title column boundary from being crossed when moving a column
    interactively (thanks to Schelte Bron for his proposal).

5.  New configuration option "-spacing", specifying additional space to
    provide above and below each tablelist row (thanks to Sebastien
    Barre for his proposal).

6.  New column configuration option "-stretchable", complementing the
    global "-stretch" option (thanks to Sebastien Barre for his
    proposal).

7.  New row configuration option "-name", whose value can also be used
    as a row index and as the first component of a cell index (thanks
    to John Kozura for his proposal).

8.  New cell configuration option "-windowdestroy", specifying a script
    to be invoked when a window embedded into the cell is destroyed
    (thanks to Sebastien Barre for his proposal).

9.  New "imagelabelpath" subcommand (thanks to Schelte Bron for his
    proposal).

10. Keyboard navigation during interactive cell editing now works on
    Mac OS X Aqua, too.

11. Restored the support for Tcl/Tk versions earlier than 8.3, by
    cleaning up the handling of the "-titlecolumns" option (thanks to
    Andreas Flach and Brian O'Hagan for their bug reports).

12. Restored the support for Tcl/Tk versions earlier than 8.0.4, which
    has been broken since release 3.5, due to the use of the
    <MouseWheel> event, introduced in Tk 8.0.4 (thanks to Brian O'Hagan
    for his valuable contribution).

13. Worked around a peculiarity of the text widget's "dump -window"
    command (thanks to Greg Reynolds for his bug-fix).

14. Fixed a binding-related bug in "extended" selection mode (thanks to
    David Mattinson for his bug-fix).

15. Numerous further improvements and minor bug fixes (thanks to
    Schelte Bron, Patrick Fradin, Silas Justiniano, and Uwe Koloska for
    their bug reports and valuable contributions).

What was new in Tablelist 4.0?
------------------------------

1.  Support for the tile entry, combobox, and checkbutton widgets for
    interactive cell editing (thanks to Miguel Bagnon, Andy Black,
    Adrian Chan, and Mark Garvey for their proposals and to Mats
    Bengtsson and Kevin Walzer for their support on the Macintosh).
    See the new reference page "tablelistTile.html" for details.

2.  Support for tile-compatibility:  By just specifying "package
    require Tablelist_tile" instead of "package require Tablelist", the
    tablelist widgets will have a modern theme-specific appearance
    (again, thanks to the above-mentioned Tablelist users for their
    suggestions and assistance).  See the "How to use it?" and "More on
    Tablelist_tile" sections of the tutorial "tablelist.html" for
    details.

3.  New demo script "tileWidgets.tcl", illustrating the use of tile
    widgets for interactive cell editing and of the Tablelist_tile
    package.  All the other demo scripts are now provided in both a
    traditional and a tile-based version.  See the "Tile-based demo
    scripts" section of the tutorial "tablelist.html" for an example
    and some screenshots.

4.  The Tk checkbutton used for interactive cell editing is now a
    platform-specific checkbutton widget on Windows and the Macintosh
    (thanks to Mats Bengtsson for his help related to the Macintosh
    platform).

5.  The "-editwindow" option is now available at cell level, too
    (thanks to Kenneth Green for his proposal).

6.  New subcommand "togglevisibility" for hiding/unhiding several
    columns at a time (thanks to Stefan Finzel and Kai Morich for their
    proposals).

7.  Support for the new virtual event <<TablelistSelectionLost>>,
    generated when a tablelist widget having "-exportselection 1" loses
    the selection (thanks to Aldo Buratti for his proposal).

8.  After sorting the items, the "most important" row is automatically
    brought into view (thanks to Kai Morich for his valuable input).

9.  Worked around a peculiarity of Tk for Windows, related to mouse
    events (thanks to Tore Morkemo and Mike Collins for their bug
    reports).

10. Worked around a problem related to the visibility of the up/down-
    arrow on Mac OS X Aqua (thanks to Kevin Walzer for his bug report).

11. Fixed a bug in the "seecell" subcommand, introduced in Tablelist
    version 3.7 (thanks to Stefan Finzel for his bug report).

12. Fixed a bug in the "rowconfigure" subcommand, introduced in the
    previous Tablelist release (thanks to Tore Morkemo for his bug
    report).

13. Eliminated the memory leak caused by incomplete cleanup on deleting
    rows with embedded windows (thanks to David Cockerell for his bug
    report).

14. Fixed a small timing-related bug in the "editcell" subcommand
    (thanks to Kenneth Green for his bug report).

15. Numerous further improvements and minor bug fixes (thanks to Greg
    Reynolds for his valuable input).

What was new in Tablelist 3.8?
------------------------------

1. New configuration option "-forceeditendcommand", controlling the
   invocation of the script corresponding to the value of the
   "-editendcommand" option (thanks to Nestor Patino for his proposal).
 
2. New subcommands "getcells" and "windowpath" (thanks to Jeff Godfrey
   and Mike Collins for their proposals).

3. Support for the new virtual event <<TablelistCellRestored>>,
   generated by the "cancelediting" subcommand.

4. Significantly improved the performance of the "delete",
   "deletecolumns", and "movecolumn" subcommands for tablelist widgets
   having color or font options set at column, row, or cell level
   (thanks to Michael Bahr for his valuable feedback).

5. Improved the autoscrolling with the left mouse button in both the
   body and the header of a tablelist widget having title columns.

6. Fixed a bug related to the "-titlecolumns" option, introduced in the
   previous Tablelist release (thanks to Alexander Schoepe for his bug
   report).

7. Fixed a typo in the implementation of the "seecell" subcommand,
   introduced in the previous Tablelist release (thanks to Patrick
   Fradin for his bug report).

8. Improved the demo script "embeddedWindows.tcl" (thanks to Patrick
   Fradin for his valuable input).

9. Several further improvements and minor bug fixes.

What was new in Tablelist 3.7?
------------------------------

1. New configuration option "-titlecolumns", specifying the number of
   the non-scrollable columns at the left edge of the window (thanks to
   Goran Ivankovic, Paul Kienzle, Hemang Lavana, and Takeshi Sakamoto
   for their proposals).  For technical reasons (the use of the
   "-elide" option for a text widget tag), this option is not supported
   for Tk versions earlier than 8.3.

2. Extended the "separatorpath" and "separators" subcommands, to
   support the new special separator, which is displayed to mark the
   end of the title columns, independently of the value of the
   "-showseparators" option.

3. The "-stripebackground" and "-stripeforeground" options now have a
   higher priority than the "-background" and "-foreground" column
   configuration options, respectively (see the demo script
   "styles.tcl", which has been extended to illustrate this change).

4. Improved the handling of embedded images with transparent
   background, complementing the changes made in the previous Tablelist
   release (thanks to Kai Morich for his valuable contribution).

5. Improved the implementation of the "seecell" subcommand for centered
   and right-aligned columns.

6. Fixed two bugs related to the "rowconfigure" subcommand, introduced
   in Tablelist version 3.5 (thanks to Ted Branscomb and Roger Niva for
   their bug reports).

7. Fixed an old bug related to the "movecolumn" subcommand.

8. Several further improvements and minor bug fixes.

What was new in Tablelist 3.6?
------------------------------

1.  Support for embedded windows, with the aid of the new cell
    configuration option "-window" (thanks to Wolf Grossi, Glenn
    Herteg, Takeshi Sakamoto, and Keesang Song for proposing this
    option).

2.  New demo script "embeddedWindows.tcl" illustrating the use of
    embedded windows in tablelist widgets; this is discussed in a new
    section of the tutorial "tablelist.html".

3.  Significantly improved and optimized the handling of embedded
    images.

4.  Simplified the support for user-defined binding scripts with the
    aid of the new commands "tablelist::getTablelistPath" and
    "tablelist::convEventFields", as well as of a new binding tag whose
    name is returned by the new "bodytag" subcommand (which is now used
    in the demo script "browse.tcl").

5.  Support for the new virtual events <<TablelistRowMoved>>,
    <<TablelistColumnMoved>>, <<TablelistColumnSorted>> and
    <<TablelistCellUpdated>> (thanks to John Vidolich for his
    proposal).  In addition, the new virtual event <<TablelistSelect>>
    can now be used instead of <<ListboxSelect>> (which is supported
    for compatibility reasons).

6.  New subcommand "itemlistvar", for accessing the tablelist widget's
    internal list (thanks to Patrick Fradin for his valuable input).

7.  Fixed a bug related to the "-listvariable" option, introduced in
    the previous Tablelist release (thanks to Torsten Reincke for his
    bug report).

8.  Fixed two bugs related to the "cellselection" subcommand (thanks to
    John Vidolich for his bug report).

9.  Fixed a few typos and minor bugs in the default binding scripts
    (thanks to Patrick Fradin, Tore Morkemo, and Torsten Reincke for
    their bug reports).

10. Numerous further improvements and minor bug fixes.

What was new in Tablelist 3.5?
------------------------------

1.  New configuration option "-selecttype" with the values "row" and
    "cell", and new binding scripts supporting these two selection
    types (thanks to Kevin Partin for his proposal and to Dietmar
    Mueller for his valuable contribution).

2.  New subcommands "activatecell", "cellselection", and
    "curcellselection", used in the binding scripts mentioned above.

3.  The words "active" and "anchor" are now recognized as valid column
    and cell indices, too.

4.  New configuration options "-movablerows" and "-movecursor", and new
    mouse bindings for moving a row interactively (thanks to Dan Rogahn
    for his valuable contribution).

5.  The key sequences used for navigation between the editable cells
    now also move the active item or element and change the
    (cell)selection and the (cell)selection anchor in the body of the
    tablelist widget.

6.  Improved the handling and appearance of the checkbutton widget when
    used as edit window (thanks to Kevin Partin for reporting a problem
    experienced when the tablelist is embedded into an Iwidgets
    dialogshell).

7.  The "-listvariable" option now supports variable names returned by
    the "itcl::scope" command, too (thanks to Nicolae Mihalache for his
    bug report).

8.  Fixed a very long-standing bug related to horizontal scrolling when
    using a non-default font (thanks to Brand Hilton for his bug report
    and fix).

9.  Fixed another very long-standing bug, related to list variables
    (thanks to Dr. Detlef Groth and John R. Smith for their bug
    reports).

10. Numerous further improvements and minor bug fixes (thanks to
    Patrick Fradin for his valuable input).

What was new in Tablelist 3.4?
------------------------------

1.  New column configuration option "-editwindow", specifying the
    widget type used for interactive cell editing in the respective
    column (thanks to Damon Courtney, Patrick Fradin, and Keesang Song
    for their proposals and to Mats Bengtsson and Benny Riefenstein for
    their help related to the Macintosh platform).  The edit window may
    be a Tk core entry, spinbox, or checkbutton, or one of the 16
    supported widgets from the packages BWidget, Iwidgets, combobox (by
    Bryan Oakley), and Mentry.

2.  New subcommand "editwinpath".

3.  Three new demo scripts illustrating the use of the "-editwindow"
    option; these are discussed in a new section of the tutorial
    "tablelist.html".

4.  New column configuration option "-maxwidth" (thanks to Tore Morkemo
    for his proposal).

5.  The <Shift-Button-3> event in a column label now restores the
    column's last static width (thanks to Dietmar Mueller for his
    valuable input).

6.  Changing a tablelist's font now updates the column widths
    accordingly.

7.  Improved the handling of the "-setgrid" option.

8.  Improved the error handling related to the option database in the
    general mega-widget utility module "mwutil.tcl".

9.  Fixed a minor bug in the "containingcolumn" subcommand (thanks to
    David Mattinson for his bug report).

10. Restored the support for Tcl/Tk versions earlier than 8.0.4, which
    has been broken since release 3.0, due to the use of the
    <MouseWheel> event, introduced in Tk 8.0.4.

11. Further code improvements (thanks to Patrick Fradin for his
    valuable input).

12. Many improvements in the documentation, including a new Quick
    Reference section (thanks to Dietmar Mueller for his valuable
    contribution).

What was new in Tablelist 3.3?
------------------------------

1. New column configuration option "-text" (thanks to Paul Kienzle for
   his proposal).

2. New subcommands "containing", "containingcolumn", "containingcell",
   and "fillcolumn".

3. New subcommands "deletecolumns", "insertcolumns", and
   "insertcolumnlist" (thanks to Kevin Partin and Paul Kienzle for
   their proposals).

4. Renamed the subcommands "getcolumn" and "getkey" to "getcolumns" and
   "getkeys", respectively.  (This won't break any existing scripts,
   because the old command names are abbreviations of the new ones.)

5. Restored the support for Tcl/Tk versions earlier than 8.4, which was
   broken in Tablelist 3.1 and 3.2, due to the use of the improved
   syntax of the "place configure" command, introduced in Tk 8.4
   (thanks to David Mattinson, Kurt Braganza, and Alexander Baath for
   reporting this problem).

6. Fixed a bug in the "editcell" subcommand, introduced in Tablelist
   3.1 (thanks to Damon Courtney for his bug report).

7. Improved the demo script "config.tcl" (thanks to Mats Bengtsson for
   his input).

8. Restructured the code by moving several procedures from the
   distribution file "tablelistWidget.tcl" into smaller, more
   manageable modules.

9. Numerous further improvements and minor bug fixes.

What was new in Tablelist 3.2?
------------------------------

1. The key associated with a tablelist item can now be used as a row
   index and as the first component of a cell index of the form
   "row,col".

2. The "delete", "get", "getcolumn", "getkey", "selection clear", and
   "selection set" subcommands now also accept a list of indices as
   single argument (thanks to Damon Courtney and Erik Leunissen for
   their proposals).

3. Made the interactive "movecolumn" operation more intuitive and
   compatible with the behavior exhibited by similar actions in popular
   applications on various platforms (thanks to Paul Kienzle for his
   suggestion).  For example, the target position of the column being
   moved is now indicated by a temporary gap displayed in the
   tablelist's header.

4. New configuration option "-targetcolor", used to set the color of
   the gap mentioned above.

5. Fixed a bug related to the <MouseWheel> event, caused by a missing
   close-bracket in the last release (thanks to Patrick Fradin for his
   bug report).

6. Fixed a bug that raised an error in the "movecolumn" command for an
   empty tablelist widget (thanks to Paul Kienzle for his bug report).

7. The workaround in the "xview" and "yview" subcommands for a Tk bug
   under Mac OS X Aqua is now only activated for that windowing system,
   since (as reported by Patrick Fradin) it caused problems on some
   other systems.

8. Further minor code improvements.

What was new in Tablelist 3.1?
------------------------------

1.  New configuration options "-movablecolumns" and
    "-movecolumncursor".

2.  New column configuration option "-name", whose value can also be
    used as a column index and as the second component of a cell index
    of the form "row,col".

3.  New subcommands "move", "movecolumn", "getcolumn", "getkey", and
    "finishediting" (thanks to Damon Courtney, Daniel Fehrenbach, Jeff
    Godfrey, and Kevin Partin for their proposals).

4.  Extended the scope of the "cancelediting" subcommand.

5.  New mouse bindings for moving a column interactively.

6.  The autoscrolling, as described in the "DEFAULT BINDINGS" section
    of the "listbox" manual entry, is now implemented for the header of
    a tablelist widget, too.

7.  The interactive cell editing is now finished by any mouse click in
    the tablelist's body, outside the cell just being edited (thanks to
    Patrick Fradin and Jeff Godfrey for this suggestion).

8.  The value returned by the "selection includes" command no longer
    depends on the tablelist's state.

9.  Worked around a bug in Tk 8.4.0 and 8.4.1 related to the "selection
    handle" command, which caused crashes under KDE 3.0 (thanks to
    Andres Garcia for reporting this and to Joe English for suggesting
    the workaround and fixing the bug in Tk 8.4.2).

10. Improved the support of Mac OS X Aqua and Mac OS Classic (thanks to
    Mats Bengtsson, Raymond Calande, Techin Alex Kang, Bernhard
    Spinnler, and especially to Benny Riefenstein for their valuable
    contributions).

11. Fixed a bug related to the invocation of the "cellconfigure"
    subcommand from within a pre-edit callback (thanks to Dr. Johannes-
    Heinrich Vogeler for his bug report).

12. Several performance improvements (thanks to Patrick Fradin for his
    valuable suggestions).

13. Improved the platform-specific stuff in the demo scripts
    "config.tcl" and "browse.tcl".

14. Numerous further improvements in the code and documentation.

What was new in Tablelist 3.0?
------------------------------

The main new feature provided by this release is the support for
interactive cell editing (thanks to Juri Shimon, Dr. Johannes-Heinrich
Vogeler, and Jeff Godfrey for their proposal).  The first three items
below are related to this subject:

1. New configuration options "-editstartcommand" and "-editendcommand".

2. New column and cell configuration option "-editable".

3. New subcommands "editcell", "entrypath", "cancelediting", and
   "rejectinput".

Further changes:

4. New subcommands "seecolumn" and "seecell".

5. Tabulator and newline characters are now retained in the internal
   list, displayed as "\t" and "\n", and supported by interactive cell
   editing (thanks to Jacek Jenrysik for his query concerning multi-
   line items).

6. The redisplay and sorting of tablelist items have become
   dramatically faster (thanks to Matt Becker for his input that
   determined me to optimize these operations, and also for his
   testing).

7. Further performance improvements (thanks to Patrick Fradin for his
   valuable contribution).

8. The option values displayed by the demo script "config.tcl" can now
   be edited interactively.

9. Minor improvements in the code and documentation.

What was new in Tablelist 2.8?
------------------------------

1. The trailing or leading ellipsis ("...") used when displaying the
   elements that don't fit into their cells can now be replaced with an
   arbitrary string specified with the aid of the new "-snipstring"
   configuration option (thanks to Tore Morkemo for his proposal).

2. New value "none" for the "-activestyle" configuration option.

3. When exporting the selection, the elements of the hidden columns are
   now skipped and the contents of the visible cells are transformed
   according to the value of the "-formatcommand" option for the
   corresponding columns.

4. Improved and simplified the focus control (thanks to Juri Shimon and
   Gopal Reddy for their bug reports).

5. Further minor code improvements.

What was new in Tablelist 2.7?
------------------------------

1. Increased the speed of the "insert" and "insertlist" subcommands as
   well as that of item insertions with the aid of the "-listvariable"
   option by a factor of about 1.3.  The "insert" subcommand is now
   about 2.3 times faster than in version 2.4.  Compared to version
   2.4, item insertion with the aid of the "-listvariable" option has
   become more than 10 times faster.

2. The number of pixels by which a column is stretched is now
   proportional to its width in pixels.  Based on this change,
   significantly improved the stretching behavior after an interactive
   column resize operation (thanks to Mats Bengtsson for his valuable
   suggestions).

3. Fixed a bug in the "-(label)font" and "-labelborderwidth"
   configuration options, introduced in version 2.5 (thanks to Bastien
   Chevreux for his bug report).

4. Fixed a bug in the "columncget", "rowcget", and "cellcget"
   subcommands, introduced in version 2.3 (again, thanks to Bastien
   Chevreux for reporting this bug).

5. Fixed a bug in the binding scripts for the binding tag
   "TablelistBody" (thanks to Miguel Bagnon for his bug report).

6. Applied a patch proposed by Jeff Adamczak that works around a bug in
   the "lsort" command, present in Tcl versions 8.0 - 8.3.2.

7. Applied a patch proposed (in a slightly different form) by Mats
   Bengtsson that works around a bug in the "info script" command on
   the Macintosh.

8. Further minor code improvements.

What was new in Tablelist 2.6?
------------------------------

The only change in this version is a bug-fix eliminating a rather nasty
bug in the "insert" and "insertlist" subcommands, introduced in the
previous release.  Thanks to Mats Bengtsson for his bug report and to
Jeffrey Hobbs for suggesting me to bump the version number to 2.6.

What was new in Tablelist 2.5?
------------------------------

1. Increased the speed of the "insert" subcommand by a factor of about
   1.8 and that of item insertions with the aid of the "-listvariable"
   option by a factor of about 8.  (These figures are based on speed
   measurements made with two tablelist widgets: one having 1000 rows
   and 10 columns and another one with 5000 rows and 20 columns.)

2. The "delete", "sort", and "sortbycolumn" subcommands, as well as row
   and cell updates with the aid of the "rowconfigure" and
   "cellconfigure" operations have also become significantly faster.

3. New "insertlist" subcommand.

4. New "-stripeheight" configuration option (thanks to Gregory Samoluk
   for his proposal).

5. If no columns are to be stretched then the blank space following the
   header labels is now filled with a dummy, insensitive label having
   the same background, borderwidth, and relief as the "normal" header
   labels.

6. Fixed a bug concerning the placement of the arrow indicating the
   sorting order (thanks to Robert Minichino for his bug report).

7. Improved the handling of header labels with embedded images, to
   eliminate some peculiarities experienced on Windows.

8. Several further improvements and minor bug fixes.

What was new in Tablelist 2.4?
------------------------------

1. New column configuration option "-formatcommand" (thanks to Jeff
   Godfrey for his proposal).  This option is now used in the demo
   script "browse.tcl".

2. New row configuration option "-selectable" (thanks to Tore Morkemo
   for this proposal).

3. Significantly improved the performance of the row and cell updates,
   as well as of the "delete" subcommand (thanks to Emanuele Lupi for
   her input that determined me to optimize these operations).

4. The widget implementation is now fully compatible with the recent
   changes made in Tk 8.4a4 (thanks to Patrick Fradin for his input).

5. Pop-up menus as children of a tablelist widget cause no problem any
   longer (thanks to Andres Garcia and Bastien Chevreux for reporting
   this bug, introduced in the previous release).

6. Fixed a bug caused by the delayed redisplay after changing the
   number of columns (thanks to Tore Morkemo for his bug report).

7. Minor improvements in the code and documentation.

What was new in Tablelist 2.3?
------------------------------

1. New configuration option "-activestyle", enabling to surround the
   active item with a frame instead of underlining it.

2. The columns can now be separated with borders, by making use of the
   new configuration option "-showseparators".

3. A nice distinguishing effect for the rows can now be obtained with
   the aid of the new configuration options "-stripebackground" and
   "-stripeforeground".

4. New tablelist widget subcommands "separatorpath" and "separators".

5. Fixed a bug related to the column index if the header labels are
   hidden (thanks to Emanuele Lupi for her bug report).

6. New demo script "styles.tcl", showing several ways to improve the
   appearance of a tablelist widget.

7. The demo scripts "config.tcl" and "browse.tcl" now make use of the
   new "-stripebackground" option.

8. Numerous further improvements and minor bug fixes (thanks to Patrick
   Fradin for his valuable input).

What was new in Tablelist 2.2?
------------------------------

1. The "-font" configuration option can now be specified at column,
   row, and cell level, too (this was proposed and partly implemented
   by Patrick Fradin).  The data will be aligned properly, no matter if
   the fonts are of different sizes.

2. Significantly improved the performance of the Tcl command associated
   with a tablelist widget, especially that of the "delete", "sort",
   and "sortbycolumn" subcommands for a large number (i.e., several
   thousands) of items.

3. Corrected the creation of the arrow indicating the sorting order, to
   make sure that it works under all supported Tcl/Tk versions (thanks
   to Juri Shimon and Andres Garcia for their bug reports).

4. Several improvements in the demo scripts "config.tcl" and
   "browse.tcl".  Among others, the GUIs generated by these scripts now
   have a better platform-specific look & feel (many thanks to Mats
   Bengtsson for his valuable suggestions concerning the Macintosh
   platform).

5. Further minor improvements in the code.

What was new in Tablelist 2.1?
------------------------------

1. The up- or down-arrow indicating the sorting order now has a 3-D
   border, giving the arrow a sunken relief.

2. Due to the new 3-D look of the arrow, the default values of the
   "-arrowcolor" and "-arrowdisabledcolor" configuration options have
   been changed to an empty string, indicating that the arrow will
   inherit the background color of the label in which it is placed.

3. Several improvements in the demo script "browse.tcl".

4. Minor improvements in the code and documentation.

5. The distribution file "tablelist2_1.zip" for Windows now includes
   the "tablelist2.1" directory, hence it is no longer necessary to
   create this folder before unpacking the distribution file (thanks to
   Kevin Partin for this suggestion).

What was new in Tablelist 2.0?
------------------------------

1.  New cell configuration option "-image", used to set and retrieve
    the image to be displayed (by itself or together with a text) in a
    cell of a tablelist widget.

2.  New column configuration option "-labelimage" specifying the image
    to be displayed (by itself or combined with a text) in a column
    label.

3.  The alignment of a header label can now be defined to be different
    from that of the elements contained in its column, by using the new
    column configuration option "-labelalign".

4.  Renamed the column configuration option "-justify" to "-align",
    because (at least in the case of the header labels) this actually
    specifies not only the justification, but also the anchor point.
    Hopefully, this POTENTIAL INCOMPATIBILITY will not break too many
    existing applications, because the column alignments are usually
    specified within the "-columns" global option.

5.  Fixed a bug that raised an error when some configuration options
    were specified at widget creation time before the "-columns" option
    (thanks to Bastien Chevreux for his bug report).

6.  Reverted the implementation of the focus control to that contained
    in the pre-1.6 Tablelist releases, because its simplified version
    from the last release failed to work as expected if a tablelist was
    the only widget taking the focus during keyboard traversal (thanks
    to Juri Shimon for his bug report).

7.  Fixed a bug that caused an erronous return value of the "labels"
    subcommand if the arrow indicating the sorting order was displayed.

8.  Several performance improvements, kindly contributed by Patrick
    Fradin.

9.  To improve the performance even further, the invocations of "info
    exists" for array elements are no longer replaced with a call to a
    helper procedure (introduced in Tablelist 1.2), because the Tcl bug
    that made this necessary for Tcl versions 8.2, 8.3.0 - 8.3.2, and
    8.4a1 was fixed in Tcl 8.3.3 and 8.4a2.  If for some reason you
    cannot upgrade your Tcl/Tk version, then you should patch the file
    "tablelistWidget.tcl" with the aid of the script "repair.tcl", as
    described in the files "README.txt" and "tablelist.html".

10. The demo script "browse.tcl" now inserts an image into the first
    cell of each row of the tablelist widget.

11. Numerous further improvements and minor bug fixes.

What was new in Tablelist 1.6?
------------------------------

1. The value of the "-stretch" configuration option is now ignored if
   the width of the tablelist widget was specified as zero or less.
   This change was necessary in order to improve the behavior of
   dynamic-width tablelist widgets with the "-setgrid" option set to
   true.

2. By pressing mouse button 1 over a header label, the label's relief
   is now only changed to "sunken" if the value of the global or
   column-specific "-labelcommand" option is nonempty.

3. Several improvements concerning hidden columns (thanks to Juri
   Shimon for his bug report).

4. Made the focus control more straight-forward.

5. Extended the "How to use it?" section of the tutorial
   "tablelist.html".

What was new in Tablelist 1.5?
------------------------------

This version contains mainly bug fixes and small improvements.  Many
thanks to Andres Garcia, Bastien Chevreux, and Patrick Fradin for their
valuable contributions.

1. Fixed a bug concerning the "-label*" configuration options.

2. Fixed the erronous invocation of "getSubCmd" in the selection
   handler "fetchSelection" (this bug was introduced in version 1.1).

3. Elements that don't fit into their cells are now displayed with a
   trailing or leading ellipsis ("..."), depending on the column
   alignment.

4. Several further improvements and minor bug fixes.

What was new in Tablelist 1.4?
------------------------------

1. New "-stretch" configuration option specifying the columns that are
   to be stretched in order to eliminate the blank space that might
   appear at the right of the table.

2. Improved the error handling in the "attrib", "configure",
   "columnconfigure", "rowconfigure", and "cellconfigure" subcommands.

3. Improved the demo scripts "browse.tcl" and "config.tcl".

What was new in Tablelist 1.3?
------------------------------

1. The "sortbycolumn" subcommand now per default places an up- or
   down-arrow indicating the sorting order into the respective column's
   label.  This can be enabled or disabled with the new "-showarrow"
   configuration option, at both widget and column level.

2. New configuration options "-arrowcolor", "-arrowdisabledcolor", and
   "-incrarrowtype" to control the appearance of the arrow mentioned
   above.

3. New "resetsortinfo" subcommand, used to reset the information about
   the sorting of the items.

4. Improved the demo script "browse.tcl".

5. Further improvements in the code and documentation.

What was new in Tablelist 1.2?
------------------------------

1. Whereever possible, eliminated the invocations of "info exists" for
   array elements.  This works around a severe bug in Tcl versions 8.2
   and 8.3 (fixed in 8.4a2), which causes excessive memory use when
   calling "info exists" on a non-existent array element.  Some serious
   memory leaks in earlier Tablelist versions when run under Tcl/Tk 8.2
   or 8.3 (reported by Henning Hanusa and Christian Burrini) could be
   tracked down to this very annoying Tcl bug (which I was not aware of
   until recently).

2. The help variables used in the initialization of the "tablelist"
   namespace are now declared with the "variable" keyword, in order to
   avoid any conflicts with global variables.

3. Improved the parsing of configuration and command options.

What was new in Tablelist 1.1?
------------------------------

This version contains mainly bug fixes and small improvements.  Many
thanks to Patrick Fradin, Bastien Chevreux, and Mats Bengtsson for
their valuable contributions.

1. Fixed some bugs in the implementation of the "-listvariable" option.
   Also, the value of this option can now be an array element, not only
   a scalar variable.

2. Fixed a bug in the implementation of the "get" subcommand.

3. New "sortcolumn" and "sortorder" subcommands to query the arguments
   of the last sorting.

4. Improved the look & feel of tablelist widgets on the Macintosh.

5. Worked around a bug in Tk 8.3.0 (fixed in 8.3.1) concerning listbox
   widgets with configured "-cursor" option.

6. Several further improvements and minor bug fixes.

What was new in Tablelist 1.0?
------------------------------

1.  New "-resizable" option for the "columnconfigure" subcommand.

2.  New "labels" subcommand, returning the list of the header labels.

3.  The "-disabledforeground" and "-state" configuration options no
    longer require Tk version 8.3 or higher.

4.  All "-label*" column configuration options can now have an empty
    string as value, meaning that the corresponding global option will
    be used instead of the column-specific one.

5.  Improved the output of the "columnconfigure" subcommand.

6.  The help variables used in the coordinate transformations within
    the scripts defined for the "TablelistBody" binding tag have been
    moved into the "tablelist" namespace, in order to avoid any
    conflicts with global variables.

7.  Improved cross-platform support with the aid of the new <<Button3>>
    virtual event.

8.  Fixed a bug in the "compareAsSet" procedure of the demo script
    "config.tcl".

9.  New demo script "browse.tcl", containing a simple widget browser
    based on a tablelist.

10. Both demo scripts now use a namespace for their procedures, to
    avoid any conflicts when evaluating them with the "source" command.

11. The tutorial "tablelist.html" is now completed and includes a
    detailed discussion of both demo scripts mentioned above.

12. Numerous further improvements in the code and documentation.

What was new in Tablelist 0.9?
------------------------------

1. The documentation now includes the tutorial "tablelist.html" (part
   of which is still work in progress), as well as reference pages for
   the two exported commands "tablelist::tablelist" and
   "tablelist::sortByColumn".

2. The "-listvariable" configuration option is now fully implemented.

3. A column of a tablelist widget can now be made invisible by using
   the new "-hide" option of the "columnconfigure" subcommand.

4. The contents of a row can now be updated with the new "-text" option
   of the "rowconfigure" subcommand.

5. For Tk versions 8.3 or higher the "tablelist::tablelist" command now
   supports the "-disabledforeground", "-labeldisabledforeground", and
   "-state" configuration options.

6. Replaced "[focus]" with "[focus -displayof $win]", so that the code
   will work properly in applications using multiple displays.
   Similarly, the "font measure" command is now invoked with the
   "-displayof $win" option.  This also works around a peculiarity of
   the "font measure" command.

7. Renamed "tablelistBindingTag" to "Tablelist".

8. Fixed a bug in the private procedure "colIndex", for arguments of
   the form "@x,y".  This procedure is invoked (directly or indirectly)
   in the implementation of all commands that take a column or cell
   index or an x coordinate as argument.

9. Numerous further improvements and minor bug fixes.

Added libs/tablelist6.0/COPYRIGHT.txt.





















>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
Multi-column listbox and tree widget package Tablelist, version 6.0
Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)

This library is free software; you can use, modify, and redistribute it
for any purpose, provided that existing copyright notices are retained
in all copies and that this notice is included verbatim in any
distributions.

This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Added libs/tablelist6.0/README.txt.











































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
       The Multi-Column Listbox and Tree Widget Package Tablelist

                                   by

                             Csaba Nemethi

                       csaba.nemethi@t-online.de 


What Is Tablelist?
------------------

Tablelist is a library package for Tcl/Tk versions 8.0 or higher,
written in pure Tcl/Tk code.  It contains:

  - the implementation of the "tablelist" mega-widget, including a
    general utility module for mega-widgets;
  - a demo script containing a useful procedure that displays the
    configuration options of an arbitrary widget in a tablelist and
    enables you to edit their values interactively;
  - a demo script implementing a widget browser based on a tablelist
    used as multi-column listbox;
  - a demo script implementing a widget browser based on a tablelist
    used as multi-column tree widget;
  - a demo script implementing a directory viewer based on a tablelist
    used as multi-column tree widget;
  - a demo script showing several ways to improve the appearance of a
    tablelist widget;
  - four further demo scripts, illustrating the interactive cell
    editing with the aid of various widgets from the Tk core and from
    the packages tile, BWidget, Iwidgets, combobox (by Bryan Oakley),
    and Mentry;
  - one further demo script, with a tablelist widget containing
    embedded windows;
  - tile-based counterparts of the above-mentioned demo scripts;
  - a tutorial in HTML format;
  - reference pages in HTML format.

A tablelist is a multi-column listbox and tree widget.  The width of
each column can be dynamic (i.e., just large enough to hold all its
elements, including the header) or static (specified in characters or
pixels).  The columns are, per default, resizable.  The alignment of
each column can be specified as "left", "right", or "center".

The columns, rows, and cells can be configured individually.  Several
of the global and column-specific options refer to the header titles,
implemented as label widgets.  For instance, the "-labelcommand" option
specifies a Tcl command to be invoked when mouse button 1 is released
over a header label.  The most common value of this option sorts the
items based on the respective column.

The Tablelist package provides a great variety of tree styles
controlling the look & feel of the column that displays the tree
hierarchy with the aid of indentations and expand/collapse controls.

Interactive editing of the elements of a tablelist widget can be
enabled for individual cells and for entire columns.  A great variety
of widgets from the Tk core and from the packages tile, BWidget,
Iwidgets, combobox, ctext, and Mentry (or Mentry_tile) is supported for
being used as embedded edit window.  In addition, a rich set of keyboard
bindings is provided for a comfortable navigation between the editable
cells.

The Tcl command corresponding to a tablelist widget is very similar to
the one associated with a normal listbox.  There are column-, row-, and
cell-specific counterparts of the "configure" and "cget" subcommands
("columnconfigure", "rowconfigure", "cellconfigure", ...).  They can be
used, among others, to insert images into the cells and the header
labels, or to insert embedded windows into the cells.  The "index",
"nearest", and "see" command options refer to the rows, but similar
subcommands are provided for the columns and cells ("columnindex",
"cellindex", ...).  The items can be sorted with the "sort",
"sortbycolumn", and "sortbycolumnlist" command options.

The bindings defined for the body of a tablelist widget make it behave
just like a normal listbox.  This includes the support for the virtual
event <<ListboxSelect>> (which is equivalent to <<TablelistSelect>>).
In addition, version 2.3 or higher of the widget callback package Wcb
(written in pure Tcl/Tk code as well) can be used to define callbacks
for the "activate", "selection set", and "selection clear" commands,
and Wcb version 3.0 or higher also supports callbacks for the
"activatecell", "cellselection set", and "cellselection clear"
commands.  The download location of Wcb is

    http://www.nemethi.de

How to Get It?
--------------

Tablelist is available for free download from the same URL as Wcb.  The
distribution file is "tablelist6.0.tar.gz" for UNIX and
"tablelist6_0.zip" for Windows.  These files contain the same
information, except for the additional carriage return character
preceding the linefeed at the end of each line in the text files for
Windows.

Tablelist is also included in tklib, which has the address

    http://core.tcl.tk/tklib

How to Install It?
------------------

Install the package as a subdirectory of one of the directories given
by the "auto_path" variable.  For example, you can install it as a
directory at the same level as the Tcl and Tk script libraries.  The
locations of these library directories are given by the "tcl_library"
and "tk_library" variables, respectively.

To install Tablelist on UNIX, "cd" to the desired directory and unpack
the distribution file "tablelist6.0ar.gz":

    gunzip -c tablelist6.0ar.gz | tar -xf -

This command will create a directory named "tablelist6.0 with the
subdirectories "demos", "doc", and "scripts".

On Windows, use WinZip or some other program capable of unpacking the
distribution file "tablelist6_0.zip" into the directory "tablelist6.0",
with the subdirectories "demos", "doc", and "scripts".

The file "tablelistEdit.tcl" in the "scripts" directory is only needed
for applications making use of interactive cell editing.  Similarly, the
file "tablelistMove.tcl" in the same directory is only required for
scripts invoking the "move" or "movecolumn" tablelist command.  Finally,
the file "tablelistThemes.tcl" is only needed for applications using
the package Tablelist_tile (see next section).

Next, you should check the exact version number of your Tcl/Tk
distribution, given by the "tcl_patchLevel" and "tk_patchLevel"
variables.  If you are using Tcl/Tk version 8.2.X, 8.3.0 - 8.3.2, or
8.4a1, then you should proceed as described in the "How to Install It?"
section of the file "tablelist.html", located in the "doc" directory.

How to Use It?
--------------

The Tablelist distribution provides two packages, called Tablelist and
Tablelist_tile.  The main difference between the two is that
Tablelist_tile enables the tile-based, theme-specific appearance of
tablelist widgets; this package requires Tcl/Tk 8.4 or higher and tile
0.6 or higher.  It is not possible to use both packages in one and the
same application, because both are implemented in the same "tablelist"
namespace and provide identical commands.

To be able to use the commands and variables implemented in the package
Tablelist, your scripts must contain one of the lines

    package require tablelist ?version?
    package require Tablelist ?version?

Likewise, to be able to use the commands and variables implemented in
the package Tablelist_tile, your scripts must contain one of the lines

    package require tablelist_tile ?version?
    package require Tablelist_tile ?version?

Since the packages Tablelist and Tablelist_tile are implemented in the
"tablelist" namespace, you must either import the procedures you need,
or use qualified names like "tablelist::tablelist".

For a detailed description of the commands and variables provided by
Tablelist and of the examples contained in the "demos" directory, see
the tutorial "tablelist.html" and the reference pages, all located in
the "doc" directory.

Added libs/tablelist6.0/demos/browse.tcl.











































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# the children of an arbitrary widget.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 6.0

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config.tcl]

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Path Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-labelcommand demo::labelCmd -yscrollcommand [list $vsb set] -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"
    button $b2 -text "Parent"
    button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys					;# see config.tcl
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	set choice [tk_messageBox -title "Error" -icon warning \
		    -message "Bad window path name \"$w\" -- replacing\
			      it with nearest existent ancestor" \
		    -type okcancel -default ok -parent [winfo toplevel $tbl]]
	if {[string compare $choice "ok"] == 0} {
	    while {![winfo exists $w]} {
		set last [string last "." $w]
		if {$last != 0} {
		    incr last -1
		}
		set w [string range $w 0 $last]
	    }
	} else {
	    return ""
	}
    }

    set top [winfo toplevel $tbl]
    wm title $top "Children of the [winfo class $w] Widget \"$w\""

    $tbl resetsortinfo
    $tbl delete 0 end

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl insert end $item

	#
	# Insert an image into the first cell of the row
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure end,0 -image $leafImg
	} else {
	    $tbl cellconfigure end,0 -image $compImg
	}
    }

    #
    # Configure the "Refresh" and "Parent" buttons
    #
    $top.bf.b1 configure -command [list demo::putChildren $w $tbl]
    set b2 $top.bf.b2
    set p [winfo parent $w]
    if {[string compare $p ""] == 0} {
	$b2 configure -state disabled
    } else {
	$b2 configure -state normal -command [list demo::putChildren $p $tbl]
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the content of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl cellcget $row,0 -text]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl cellcget [$tbl curselection],0 -text]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}

Added libs/tablelist6.0/demos/browseTree.tcl.

























































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# the children of an arbitrary widget.
#
# Copyright (c) 2010-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.3
package require tablelist 6.0

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config.tcl]

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-expandcommand demo::expandCmd -labelcommand demo::labelCmd \
	-yscrollcommand [list $vsb set] -setgrid no -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"
    button $b2 -text "Parent"
    button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys					;# see config.tcl
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl root
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl, as child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning \
			-message "Bad window path name \"$w\" -- replacing\
				  it with nearest existent ancestor" \
			-type okcancel -default ok \
			-parent [winfo toplevel $tbl]]
	    if {[string compare $choice "ok"] == 0} {
		while {![winfo exists $w]} {
		    set last [string last "." $w]
		    if {$last != 0} {
			incr last -1
		    }
		    set w [string range $w 0 $last]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	set top [winfo toplevel $tbl]
	wm title $top "Children of the [winfo class $w] Widget \"$w\""

	$tbl resetsortinfo
	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl insertchild $nodeIdx end $item

	#
	# Insert an image into the first cell of the row; mark the
	# row as collapsed if the child widget has children itself
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure $row,0 -image $leafImg
	} else {
	    $tbl cellconfigure $row,0 -image $compImg
	    $tbl collapse $row
	}

	$tbl rowattrib $row pathName $c
	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	$top.bf.b1 configure -command [list demo::refreshView $w $tbl]
	set b2 $top.bf.b2
	set p [winfo parent $w]
	if {[string compare $p ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal -command \
		[list demo::putChildren $p $tbl root]
	}
    }
}

#------------------------------------------------------------------------------
# demo::expandCmd
#
# Outputs the data of the children of the widget whose leaf name is displayed
# in the first cell of the specified row of the tablelist widget tbl, as child
# items of the one identified by row.
#------------------------------------------------------------------------------
proc demo::expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set w [$tbl rowattrib $row pathName]
	putChildren $w $tbl $row

	#
	# Apply the last sorting (if any) to the new items
	#
	$tbl refreshsorting $row
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the content of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl rowattrib $row pathName]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl root
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl rowattrib [$tbl curselection] pathName]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# demo::refreshView
#
# Redisplays the data of the children of the widget w in the tablelist widget
# tbl and restores the expanded states of the items as well as the vertical
# view.
#------------------------------------------------------------------------------
proc demo::refreshView {w tbl} {
    #
    # Save the vertical view and get the path names of
    # the child widgets displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedWidgets($pathName) 1
    }

    #
    # Redisplay the data of the widget's (possibly changed) children and
    # restore the expanded states of the children, along with the vertical view
    #
    putChildren $w $tbl root
    restoreExpandedStates $tbl root expandedWidgets
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# demo::restoreExpandedStates
#   
# Expands those children of the parent identified by nodeIdx that display the
# data of child widgets whose path names are the names of the elements of the
# array specified by the last argument.
#------------------------------------------------------------------------------
proc demo::restoreExpandedStates {tbl nodeIdx expandedWidgetsName} {
    upvar $expandedWidgetsName expandedWidgets

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[info exists expandedWidgets($)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedWidgets
	}
    }
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}

Added libs/tablelist6.0/demos/browseTree_tile.tcl.



































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# the children of an arbitrary widget.
#
# Copyright (c) 2010-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config_tile.tcl]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    ttk::frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-expandcommand demo::expandCmd -labelcommand demo::labelCmd \
	-yscrollcommand [list $vsb set] -setgrid no -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    ttk::scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a tile frame child of the top-level widget
    #
    set bf $top.bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -text "Refresh"
    ttk::button $b2 -text "Parent"
    ttk::button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl root
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl, as child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning \
			-message "Bad window path name \"$w\" -- replacing\
				  it with nearest existent ancestor" \
			-type okcancel -default ok \
			-parent [winfo toplevel $tbl]]
	    if {[string compare $choice "ok"] == 0} {
		while {![winfo exists $w]} {
		    set last [string last "." $w]
		    if {$last != 0} {
			incr last -1
		    }
		    set w [string range $w 0 $last]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	set top [winfo toplevel $tbl]
	wm title $top "Children of the [winfo class $w] Widget \"$w\""

	$tbl resetsortinfo
	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl insertchild $nodeIdx end $item

	#
	# Insert an image into the first cell of the row; mark the
	# row as collapsed if the child widget has children itself
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure $row,0 -image $leafImg
	} else {
	    $tbl cellconfigure $row,0 -image $compImg
	    $tbl collapse $row
	}

	$tbl rowattrib $row pathName $c
	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	$top.bf.b1 configure -command [list demo::refreshView $w $tbl]
	set b2 $top.bf.b2
	set p [winfo parent $w]
	if {[string compare $p ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal -command \
		[list demo::putChildren $p $tbl root]
	}
    }
}

#------------------------------------------------------------------------------
# demo::expandCmd
#
# Outputs the data of the children of the widget whose leaf name is displayed
# in the first cell of the specified row of the tablelist widget tbl, as child
# items of the one identified by row.
#------------------------------------------------------------------------------
proc demo::expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set w [$tbl rowattrib $row pathName]
	putChildren $w $tbl $row

	#
	# Apply the last sorting (if any) to the new items
	#
	$tbl refreshsorting $row
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the content of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl rowattrib $row pathName]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item \
		[winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
		[winfo width $c] [winfo height $c] [winfo ismapped $c] \
		[winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl root
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl rowattrib [$tbl curselection] pathName]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl rowattrib [$tbl curselection] pathName]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# demo::refreshView
#
# Redisplays the data of the children of the widget w in the tablelist widget
# tbl and restores the expanded states of the items as well as the vertical
# view.
#------------------------------------------------------------------------------
proc demo::refreshView {w tbl} {
    #
    # Save the vertical view and get the path names of
    # the child widgets displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedWidgets($pathName) 1
    }

    #
    # Redisplay the data of the widget's (possibly changed) children and
    # restore the expanded states of the children, along with the vertical view
    #
    putChildren $w $tbl root
    restoreExpandedStates $tbl root expandedWidgets
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# demo::restoreExpandedStates
#   
# Expands those children of the parent identified by nodeIdx that display the
# data of child widgets whose path names are the names of the elements of the
# array specified by the last argument.
#------------------------------------------------------------------------------
proc demo::restoreExpandedStates {tbl nodeIdx expandedWidgetsName} {
    upvar $expandedWidgetsName expandedWidgets

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[info exists expandedWidgets($pathName)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedWidgets
	}
    }
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}

Added libs/tablelist6.0/demos/browse_tile.tcl.























































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying information about
# children of an arbitrary widget.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
		      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
		      -background yellow -foreground gray50]
}

source [file join $demo::dir config_tile.tcl]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    ttk::frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
	-columns {0 "Path Name"	left
		  0 "Class"	left
		  0 "X"		right
		  0 "Y"		right
		  0 "Width"	right
		  0 "Height"	right
		  0 "Mapped"	center
		  0 "Viewable"	center
		  0 "Manager"	left} \
	-labelcommand demo::labelCmd -yscrollcommand [list $vsb set] -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
	$tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
	$tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    ttk::scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
	bind $l <Configure> [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl <Configure> [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the <Double-1> event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
		      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
		      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <Double-1>   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a tile frame child of the top-level widget
    #
    set bf $top.bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -text "Refresh"
    ttk::button $b2 -text "Parent"
    ttk::button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {![winfo exists $w]} {
	bell
	set choice [tk_messageBox -title "Error" -icon warning \
		    -message "Bad window path name \"$w\" -- replacing\
			      it with nearest existent ancestor" \
		    -type okcancel -default ok -parent [winfo toplevel $tbl]]
	if {[string compare $choice "ok"] == 0} {
	    while {![winfo exists $w]} {
		set last [string last "." $w]
		if {$last != 0} {
		    incr last -1
		}
		set w [string range $w 0 $last]
	    }
	} else {
	    return ""
	}
    }

    set top [winfo toplevel $tbl]
    wm title $top "Children of the [winfo class $w] Widget \"$w\""

    $tbl resetsortinfo
    $tbl delete 0 end

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
	#
	# Insert the data of the current child into the tablelist widget
	#
	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl insert end $item

	#
	# Insert an image into the first cell of the row
	#
	if {[llength [winfo children $c]] == 0} {
	    $tbl cellconfigure end,0 -image $leafImg
	} else {
	    $tbl cellconfigure end,0 -image $compImg
	}
    }

    #
    # Configure the "Refresh" and "Parent" buttons
    #
    $top.bf.b1 configure -command [list demo::putChildren $w $tbl]
    set b2 $top.bf.b2
    set p [winfo parent $w]
    if {[string compare $p ""] == 0} {
	$b2 configure -state disabled
    } else {
	$b2 configure -state normal -command [list demo::putChildren $p $tbl]
    }
}

#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the content of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sort order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}

#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
	$tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row < $rowCount} {incr row} {
	set c [$tbl cellcget $row,0 -text]
	if {![winfo exists $c]} {
	    continue
	}

	set item {}
	lappend item $c [winfo class $c] [winfo x $c] [winfo y $c] \
		     [winfo width $c] [winfo height $c] [winfo ismapped $c] \
		     [winfo viewable $c] [winfo manager $c]
	$tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}

#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    if {[llength [winfo children $w]] == 0} {
	bell
    } else {
	putChildren $w $tbl
    }
}

#------------------------------------------------------------------------------
# demo::dispConfigOfSelWidget
#
# Displays the configuration options of the selected widget within the
# tablelist tbl in a tablelist widget contained in a newly created top-level
# widget.
#------------------------------------------------------------------------------
proc demo::dispConfigOfSelWidget tbl {
    demo::displayConfig [$tbl cellcget [$tbl curselection],0 -text]
}

#------------------------------------------------------------------------------
# demo::postPopupMenu
#
# Posts the pop-up menu $top.menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its first entry, depending upon
# whether the selected widget has children or not.
#------------------------------------------------------------------------------
proc demo::postPopupMenu {top rootX rootY} {
    set tbl $top.tf.tbl
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent $top
	return ""
    }

    set menu $top.menu
    if {[llength [winfo children $w]] == 0} {
	$menu entryconfigure 0 -state disabled
    } else {
	$menu entryconfigure 0 -state normal
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display information about the children of an arbitrary\
	    widget, enter\n\n\tdemo::displayChildren <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}

Added libs/tablelist6.0/demos/bwidget.tcl.



































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the BWidget package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.4				;# because of "-compound"
package require tablelist 6.0
package require BWidget

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*Entry.background white

#
# Register some widgets from the BWidget package for interactive cell editing
#
tablelist::addBWidgetEntry
tablelist::addBWidgetSpinBox
tablelist::addBWidgetComboBox

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow Entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow ComboBox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow SpinBox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow ComboBox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow ComboBox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow ComboBox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow Entry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow Entry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -range {5 8 1} -editable no
	}

	parity {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {None Even Odd Mark Space} -editable no
	}

	stopBits {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {1 1.5 2} -editable no
	}

	handshake {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {XON/XOFF RTS/CTS None} -editable no
	}

	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
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
}

Added libs/tablelist6.0/demos/bwidget_tile.tcl.















































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the BWidget package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0
package require BWidget

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*Entry.background white

#
# Register some widgets from the BWidget package for interactive cell editing
#
tablelist::addBWidgetEntry
tablelist::addBWidgetSpinBox
tablelist::addBWidgetComboBox

#
# 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
#
set f [ttk::frame .f]

#
# 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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow Entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow ComboBox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow SpinBox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow ComboBox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow ComboBox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow ComboBox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow Entry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow Entry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -range {5 8 1} -editable no
	}

	parity {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {None Even Odd Mark Space} -editable no
	}

	stopBits {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {1 1.5 2} -editable no
	}

	handshake {
	    #
	    # Populate the ComboBox and make it non-editable
	    #
	    $w configure -values {XON/XOFF RTS/CTS None} -editable no
	}

	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
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
}

Added libs/tablelist6.0/demos/checked.gif.

cannot compute difference between binary files

Added libs/tablelist6.0/demos/clsdFolder.gif.

cannot compute difference between binary files

Added libs/tablelist6.0/demos/comp.xbm.











>
>
>
>
>
1
2
3
4
5
#define comp_width 14
#define comp_height 12
static unsigned char comp_bits[] = {
   0xff, 0x3f, 0x01, 0x20, 0xfd, 0x3f, 0x05, 0x20, 0xf5, 0x3f, 0x15, 0x20,
   0xd5, 0x3f, 0x55, 0x20, 0x55, 0x3f, 0x55, 0x21, 0x55, 0x21, 0xff, 0x3f};

Added libs/tablelist6.0/demos/config.tcl.























































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying and editing the
# configuration options of an arbitrary widget.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 6.0

namespace eval demo {
    #
    # Get the current windowing system ("x11", "win32", "classic", or "aqua")
    # and add some entries to the Tk option database for the following
    # widget hierarchy within a top-level widget of the class DemoTop:
    #
    # Name		Class
    # -----------------------------
    # tf		Frame
    #   tbl		  Tabellist
    #   vsb, hsb	  Scrollbar
    # bf		Frame
    #   b1, b2, b3	  Button
    #
    variable winSys
    if {[catch {tk windowingsystem} winSys] != 0} {
	switch $::tcl_platform(platform) {
	    unix	{ set winSys x11 }
	    windows	{ set winSys win32 }
	    macintosh	{ set winSys classic }
	}
    }
    if {[string compare $winSys "x11"] == 0} {
	#
	# Create the font TkDefaultFont if not yet present
	#
	catch {font create TkDefaultFont -family Helvetica -size -12}

	option add *DemoTop*Font			TkDefaultFont
	option add *DemoTop*selectBackground		#5294e2
	option add *DemoTop*selectForeground		white
    }
    option add *DemoTop.tf.borderWidth			1
    option add *DemoTop.tf.relief			sunken
    option add *DemoTop.tf.tbl.borderWidth		0
    option add *DemoTop.tf.tbl.highlightThickness	0
    option add *DemoTop.tf.tbl.background		white
    option add *DemoTop.tf.tbl.stripeBackground		#f0f0f0
    option add *DemoTop.tf.tbl.setGrid			yes
    option add *DemoTop.tf.tbl*Entry.background		white
    option add *DemoTop.bf.Button.width			10
}

#------------------------------------------------------------------------------
# demo::displayConfig
#
# Displays the configuration options of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayConfig w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .configTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .configTop$n
    }
    toplevel $top -class DemoTop
    wm title $top "Configuration Options of the [winfo class $w] Widget \"$w\""

    #
    # Create a scrolled tablelist widget with 5 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Command-Line Name"
		  0 "Database/Alias Name"
		  0 "Database Class"
		  0 "Default Value"
		  0 "Current Value"} \
	-labelcommand tablelist::sortByColumn -sortcommand demo::compareAsSet \
	-editendcommand demo::applyValue -height 15 -width 100 -stretch all \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set]
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 3 -maxwidth 30
    $tbl columnconfigure 4 -maxwidth 30 -editable yes
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"     -command [list demo::putConfig $w $tbl]
    button $b2 -text "Sort as Set" -command [list $tbl sort]
    button $b3 -text "Close"       -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the configuration options of the given widget
    #
    putConfig $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putConfig
#
# Outputs the configuration options of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putConfig {w tbl} {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    #
    # Display the configuration options of w in the tablelist widget tbl
    #
    $tbl delete 0 end
    foreach configSet [$w configure] {
	#
	# Insert the list configSet into the tablelist widget
	#
	$tbl insert end $configSet

	if {[llength $configSet] == 2} {
	    $tbl rowconfigure end -foreground gray50 -selectforeground gray75
	    $tbl cellconfigure end -editable no
	} else {
	    #
	    # Change the colors of the first and last cell of the row
	    # if the current value is different from the default one
	    #
	    set default [lindex $configSet 3]
	    set current [lindex $configSet 4]
	    if {[string compare $default $current] != 0} {
		foreach col {0 4} {
		    $tbl cellconfigure end,$col \
			 -foreground red -selectforeground yellow
		}
	    }
	}
    }

    $tbl sortbycolumn 0
    $tbl activate 0
    $tbl attrib widget $w
}

#------------------------------------------------------------------------------
# demo::compareAsSet
#
# Compares two items of a tablelist widget used to display the configuration
# options of an arbitrary widget.  The item in which the current value is
# different from the default one is considered to be less than the other; if
# both items fulfil this condition or its negation then string comparison is
# applied to the two option names.
#------------------------------------------------------------------------------
proc demo::compareAsSet {item1 item2} {
    foreach {opt1 dbName1 dbClass1 default1 current1} $item1 \
	    {opt2 dbName2 dbClass2 default2 current2} $item2 {
	set changed1 [expr {[string compare $default1 $current1] != 0}]
	set changed2 [expr {[string compare $default2 $current2] != 0}]
	if {$changed1 == $changed2} {
	    return [string compare $opt1 $opt2]
	} elseif {$changed1} {
	    return -1
	} else {
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# demo::applyValue
#
# Applies the new value of the configuraton option contained in the given row
# of the tablelist widget tbl to the widget whose options are displayed in it,
# and updates the colors of the first and last cell of the row.
#------------------------------------------------------------------------------
proc demo::applyValue {tbl row col text} {
    #
    # Try to apply the new value of the option contained in
    # the given row to the widget whose options are displayed
    # in the tablelist; reject the value if the attempt fails
    #
    set w [$tbl attrib widget]
    set opt [$tbl cellcget $row,0 -text]
    if {[catch {$w configure $opt $text} result] != 0} {
	bell
	tk_messageBox -title "Error" -icon error -message $result \
	    -parent [winfo toplevel $tbl]
	$tbl rejectinput
	return ""
    }

    #
    # Replace the new option value with its canonical form and
    # update the colors of the first and last cell of the row
    #
    set text [$w cget $opt]
    set default [$tbl cellcget $row,3 -text]
    if {[string compare $default $text] == 0} {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col \
		 -foreground "" -selectforeground ""
	}
    } else {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col \
		 -foreground red -selectforeground yellow
	}
    }

    return $text
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display the configuration options of an arbitrary\
	    widget, enter\n\n\tdemo::displayConfig <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}

Added libs/tablelist6.0/demos/config_tile.tcl.













































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Demonstrates how to use a tablelist widget for displaying and editing the
# configuration options of an arbitrary widget.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0

namespace eval demo {
    #
    # Get the current windowing system ("x11", "win32", or "aqua")
    # and add some entries to the Tk option database for the following
    # widget hierarchy within a top-level widget of the class DemoTop:
    #
    # Name		Class
    # -----------------------------
    # tf		TFrame
    #   tbl		  Tabellist
    #   vsb, hsb	  TScrollbar
    # bf		TFrame
    #   b1, b2, b3	  TButton
    #
    if {[tk windowingsystem] eq "x11"} {
	option add *DemoTop*Font			TkDefaultFont
    }
    tablelist::setThemeDefaults
    set foreground [winfo rgb . $tablelist::themeDefaults(-foreground)]
    set selectFg   [winfo rgb . $tablelist::themeDefaults(-selectforeground)]
    set selectFgEqForeground [expr {$selectFg eq $foreground}]
    variable currentTheme [tablelist::getCurrentTheme]
    if {$currentTheme ne "aqua"} {
	option add *DemoTop*selectBackground \
		   $tablelist::themeDefaults(-selectbackground)
	option add *DemoTop*selectForeground \
		   $tablelist::themeDefaults(-selectforeground)
	option add *DemoTop*selectBorderWidth \
		   $tablelist::themeDefaults(-selectborderwidth)
    }
    option add *DemoTop.tf.borderWidth			1
    option add *DemoTop.tf.relief			sunken
    option add *DemoTop.tf.tbl.borderWidth		0
    option add *DemoTop.tf.tbl.background		white
    option add *DemoTop.tf.tbl.stripeBackground		#f0f0f0
    option add *DemoTop.tf.tbl.setGrid			yes
    option add *DemoTop.tf.tbl*Entry.background		white
    option add *DemoTop.bf.TButton.width		10
}

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {$demo::currentTheme eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# demo::displayConfig
#
# Displays the configuration options of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayConfig w {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\""
	return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .configTop
    for {set n 2} {[winfo exists $top]} {incr n} {
	set top .configTop$n
    }
    toplevel $top -class DemoTop
    wm title $top "Configuration Options of the [winfo class $w] Widget \"$w\""

    #
    # Create a scrolled tablelist widget with 5 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    ttk::frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Command-Line Name"
		  0 "Database/Alias Name"
		  0 "Database Class"
		  0 "Default Value"
		  0 "Current Value"} \
	-labelcommand tablelist::sortByColumn -sortcommand demo::compareAsSet \
	-editendcommand demo::applyValue -height 15 -width 100 -stretch all \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set]
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 3 -maxwidth 30
    $tbl columnconfigure 4 -maxwidth 30 -editable yes
    ttk::scrollbar $vsb -orient vertical   -command [list $tbl yview]
    ttk::scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create three buttons within a tile frame child of the top-level widget
    #
    set bf $top.bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -text "Refresh"     -command [list demo::putConfig $w $tbl]
    ttk::button $b2 -text "Sort as Set" -command [list $tbl sort]
    ttk::button $b3 -text "Close"       -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the configuration options of the given widget
    #
    putConfig $w $tbl
    return $tbl
}

#------------------------------------------------------------------------------
# demo::putConfig
#
# Outputs the configuration options of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putConfig {w tbl} {
    if {![winfo exists $w]} {
	bell
	tk_messageBox -title "Error" -icon error -message \
	    "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
	return ""
    }

    #
    # Display the configuration options of w in the tablelist widget tbl
    #
    $tbl delete 0 end
    foreach configSet [$w configure] {
	#
	# Insert the list configSet into the tablelist widget
	#
	$tbl insert end $configSet

	if {[llength $configSet] == 2} {
	    $tbl rowconfigure end -foreground gray50 -selectforeground gray75
	    $tbl cellconfigure end -editable no
	} else {
	    #
	    # Change the colors of the first and last cell of the row
	    # if the current value is different from the default one
	    #
	    set default [lindex $configSet 3]
	    set current [lindex $configSet 4]
	    if {[string compare $default $current] != 0} {
		foreach col {0 4} {
		    $tbl cellconfigure end,$col -foreground red
		    if {$demo::selectFgEqForeground} {
			$tbl cellconfigure end,$col -selectforeground red
		    } else {
			$tbl cellconfigure end,$col -selectforeground yellow
		    }
		}
	    }
	}
    }

    $tbl sortbycolumn 0
    $tbl activate 0
    $tbl attrib widget $w
}

#------------------------------------------------------------------------------
# demo::compareAsSet
#
# Compares two items of a tablelist widget used to display the configuration
# options of an arbitrary widget.  The item in which the current value is
# different from the default one is considered to be less than the other; if
# both items fulfil this condition or its negation then string comparison is
# applied to the two option names.
#------------------------------------------------------------------------------
proc demo::compareAsSet {item1 item2} {
    foreach {opt1 dbName1 dbClass1 default1 current1} $item1 \
	    {opt2 dbName2 dbClass2 default2 current2} $item2 {
	set changed1 [expr {[string compare $default1 $current1] != 0}]
	set changed2 [expr {[string compare $default2 $current2] != 0}]
	if {$changed1 == $changed2} {
	    return [string compare $opt1 $opt2]
	} elseif {$changed1} {
	    return -1
	} else {
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# demo::applyValue
#
# Applies the new value of the configuraton option contained in the given row
# of the tablelist widget tbl to the widget whose options are displayed in it,
# and updates the colors of the first and last cell of the row.
#------------------------------------------------------------------------------
proc demo::applyValue {tbl row col text} {
    #
    # Try to apply the new value of the option contained in
    # the given row to the widget whose options are displayed
    # in the tablelist; reject the value if the attempt fails
    #
    set w [$tbl attrib widget]
    set opt [$tbl cellcget $row,0 -text]
    if {[catch {$w configure $opt $text} result] != 0} {
	bell
	tk_messageBox -title "Error" -icon error -message $result \
	    -parent [winfo toplevel $tbl]
	$tbl rejectinput
	return ""
    }

    #
    # Replace the new option value with its canonical form and
    # update the colors of the first and last cell of the row
    #
    set text [$w cget $opt]
    set default [$tbl cellcget $row,3 -text]
    if {[string compare $default $text] == 0} {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col \
		 -foreground "" -selectforeground ""
	}
    } else {
	foreach col {0 4} {
	    $tbl cellconfigure $row,$col -foreground red
	    if {$demo::selectFgEqForeground} {
		$tbl cellconfigure $row,$col -selectforeground red
	    } else {
		$tbl cellconfigure $row,$col -selectforeground yellow
	    }
	}
    }

    return $text
}

#------------------------------------------------------------------------------

if {$tcl_interactive} {
    return "\nTo display the configuration options of an arbitrary\
	    widget, enter\n\n\tdemo::displayConfig <widgetName>\n"
} else {
    wm withdraw .
    tk_messageBox -title $argv0 -icon warning -message \
	"Please source this script into\nan interactive wish session"
    exit 1
}

Added libs/tablelist6.0/demos/dirViewer.tcl.



























































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
#!/usr/bin/env wish

#==============================================================================
# Demonstrates how to use a tablelist widget for displaying the content of a
# directory.
#
# Copyright (c) 2010-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.3
package require tablelist 6.0

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create three images
#
image create photo clsdFolderImg -file [file join $dir clsdFolder.gif]
image create photo openFolderImg -file [file join $dir openFolder.gif]
image create photo fileImg       -file [file join $dir file.gif]

#------------------------------------------------------------------------------
# displayContents
#
# Displays the content of the directory dir in a tablelist widget.
#------------------------------------------------------------------------------
proc displayContents dir {
    #
    # Create a scrolled tablelist widget with 3 dynamic-
    # width columns and interactive sort capability
    #
    set tf .tf
    frame $tf -class ScrollArea
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Name"	    left
		  0 "Size"	    right
		  0 "Date Modified" left} \
	-expandcommand expandCmd -collapsecommand collapseCmd \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] \
	-movablecolumns no -setgrid no -showseparators yes -height 18 -width 80
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 0 -formatcommand formatString -sortmode dictionary
    $tbl columnconfigure 1 -formatcommand formatSize -sortmode integer
    $tbl columnconfigure 2 -formatcommand formatString
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create a pop-up menu with one command entry; bind the script
    # associated with its entry to the <Double-1> event, too
    #
    set menu .menu
    menu $menu -tearoff no
    $menu add command -label "Display Contents" \
		      -command [list putContentsOfSelFolder $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list postPopupMenu %X %Y]
    bind $bodyTag <Double-1>   [list putContentsOfSelFolder $tbl]

    #
    # Create three buttons within a frame child of the main widget
    #
    set bf .bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -width 10 -text "Refresh"
    button $b2 -width 10 -text "Parent"
    button $b3 -width 10 -text "Close" -command exit

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    global winSys					;# see option.tcl
    if {[string compare $winSys "aqua"] == 0} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the content of the given directory
    #
    $tbl sortbycolumn 0
    putContents $dir $tbl root
}

#------------------------------------------------------------------------------
# putContents
#
# Outputs the content of the directory dir into the tablelist widget tbl, as
# child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc putContents {dir tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {[string compare $dir ""] != 0 &&
	(![file isdirectory $dir] || ![file readable $dir])} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning -message \
			"Cannot read directory \"[file nativename $dir]\"\
			-- replacing it with nearest existent ancestor" \
			-type okcancel -default ok]
	    if {[string compare $choice "ok"] == 0} {
		while {![file isdirectory $dir] || ![file readable $dir]} {
		    set dir [file dirname $dir]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	if {[string compare $dir ""] == 0} {
	    if {[llength [file volumes]] == 1} {
		wm title . "Contents of the File System"
	    } else {
		wm title . "Contents of the File Systems"
	    }
	} else {
	    wm title . "Contents of the Directory \"[file nativename $dir]\""
	}

	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Build a list from the data of the subdirectories and
    # files of the directory dir.  Prepend a "D" or "F" to
    # each entry's name and modification date & time, for
    # sorting purposes (it will be removed by formatString).
    #
    set itemList {}
    if {[string compare $dir ""] == 0} {
	foreach volume [file volumes] {
	    lappend itemList [list D[file nativename $volume] -1 D $volume]
	}
    } else {
	foreach entry [glob -nocomplain -types {d f} -directory $dir *] {
	    if {[catch {file mtime $entry} modTime] != 0} {
		continue
	    }

	    if {[file isdirectory $entry]} {
		lappend itemList [list D[file tail $entry] -1 \
		    D[clock format $modTime -format "%Y-%m-%d %H:%M"] $entry]
	    } else {
		lappend itemList [list F[file tail $entry] [file size $entry] \
		    F[clock format $modTime -format "%Y-%m-%d %H:%M"] ""]
	    }
	}
    }

    #
    # Sort the above list and insert it into the tablelist widget
    # tbl as list of children of the row identified by nodeIdx
    #
    set itemList [$tbl applysorting $itemList]
    $tbl insertchildlist $nodeIdx end $itemList

    #
    # Insert an image into the first cell of each newly inserted row
    #
    foreach item $itemList {
	set name [lindex $item end]
	if {[string compare $name ""] == 0} {			;# file
	    $tbl cellconfigure $row,0 -image fileImg
	} else {						;# directory
	    $tbl cellconfigure $row,0 -image clsdFolderImg
	    $tbl rowattrib $row pathName $name

	    #
	    # Mark the row as collapsed if the directory is non-empty
	    #
	    if {[file readable $name] && [llength \
		[glob -nocomplain -types {d f} -directory $name *]] != 0} {
		$tbl collapse $row
	    }
	}

	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	.bf.b1 configure -command [list refreshView $dir $tbl]
	set b2 .bf.b2
	if {[string compare $dir ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal
	    set p [file dirname $dir]
	    if {[string compare $p $dir] == 0} {
		$b2 configure -command [list putContents "" $tbl root]
	    } else {
		$b2 configure -command [list putContents $p $tbl root]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# formatString
#
# Returns the substring obtained from the specified value by removing its first
# character.
#------------------------------------------------------------------------------
proc formatString val {
    return [string range $val 1 end]
}

#------------------------------------------------------------------------------
# formatSize
#
# Returns an empty string if the specified value is negative and the value
# itself in user-friendly format otherwise.
#------------------------------------------------------------------------------
proc formatSize val {
    if {$val < 0} {
	return ""
    } elseif {$val < 1024} {
	return "$val bytes"
    } elseif {$val < 1048576} {
	return [format "%.1f KB" [expr {$val / 1024.0}]]
    } elseif {$val < 1073741824} {
	return [format "%.1f MB" [expr {$val / 1048576.0}]]
    } else {
	return [format "%.1f GB" [expr {$val / 1073741824.0}]]
    }
}

#------------------------------------------------------------------------------
# expandCmd
#
# Outputs the content of the directory whose leaf name is displayed in the
# first cell of the specified row of the tablelist widget tbl, as child items
# of the one identified by row, and updates the image displayed in that cell.
#------------------------------------------------------------------------------
proc expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set dir [$tbl rowattrib $row pathName]
	putContents $dir $tbl $row
    }

    if {[$tbl childcount $row] != 0} {
	$tbl cellconfigure $row,0 -image openFolderImg
    }
}

#------------------------------------------------------------------------------
# collapseCmd
#
# Updates the image displayed in the first cell of the specified row of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc collapseCmd {tbl row} {
    $tbl cellconfigure $row,0 -image clsdFolderImg
}

#------------------------------------------------------------------------------
# putContentsOfSelFolder
#
# Outputs the content of the selected folder into the tablelist widget tbl.
#------------------------------------------------------------------------------
proc putContentsOfSelFolder tbl {
    set row [$tbl curselection]
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		bell
	    } else {
		putContents $dir $tbl root
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	bell
    }
}

#------------------------------------------------------------------------------
# postPopupMenu
#
# Posts the pop-up menu .menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its only entry, depending upon
# whether the selected item represents a readable directory or not.
#------------------------------------------------------------------------------
proc postPopupMenu {rootX rootY} {
    set tbl .tf.tbl
    set row [$tbl curselection]
    set menu .menu
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		$menu entryconfigure 0 -state disabled
	    } else {
		$menu entryconfigure 0 -state normal
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	$menu entryconfigure 0 -state disabled
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# refreshView
#
# Redisplays the content of the directory dir in the tablelist widget tbl and
# restores the expanded states of the folders as well as the vertical view.
#------------------------------------------------------------------------------
proc refreshView {dir tbl} {
    #
    # Save the vertical view and get the path names
    # of the folders displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedFolders($pathName) 1
    }

    #
    # Redisplay the directory's (possibly changed) content and restore
    # the expanded states of the folders, along with the vertical view
    #
    putContents $dir $tbl root
    restoreExpandedStates $tbl root expandedFolders
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# restoreExpandedStates
#
# Expands those children of the parent identified by nodeIdx that display
# folders whose path names are the names of the elements of the array specified
# by the last argument.
#------------------------------------------------------------------------------
proc restoreExpandedStates {tbl nodeIdx expandedFoldersName} {
    upvar $expandedFoldersName expandedFolders

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[string compare $pathName ""] != 0 &&
	    [info exists expandedFolders($pathName)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedFolders
	}
    }
}

displayContents ""

Added libs/tablelist6.0/demos/dirViewer_tile.tcl.





































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#!/usr/bin/env wish

#==============================================================================
# Demonstrates how to use a tablelist widget for displaying the content of a
# directory.
#
# Copyright (c) 2010-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option_tile.tcl]

#
# Create three images
#
image create photo clsdFolderImg -file [file join $dir clsdFolder.gif]
image create photo openFolderImg -file [file join $dir openFolder.gif]
image create photo fileImg       -file [file join $dir file.gif]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#------------------------------------------------------------------------------
# displayContents
#
# Displays the content of the directory dir in a tablelist widget.
#------------------------------------------------------------------------------
proc displayContents dir {
    #
    # Create a scrolled tablelist widget with 3 dynamic-
    # width columns and interactive sort capability
    #
    set tf .tf
    ttk::frame $tf -class ScrollArea
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
	-columns {0 "Name"	    left
		  0 "Size"	    right
		  0 "Date Modified" left} \
	-expandcommand expandCmd -collapsecommand collapseCmd \
	-xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] \
	-movablecolumns no -setgrid no -showseparators yes -height 18 -width 80
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }
    $tbl columnconfigure 0 -formatcommand formatString -sortmode dictionary
    $tbl columnconfigure 1 -formatcommand formatSize -sortmode integer
    $tbl columnconfigure 2 -formatcommand formatString
    ttk::scrollbar $vsb -orient vertical   -command [list $tbl yview]
    ttk::scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create a pop-up menu with one command entry; bind the script
    # associated with its entry to the <Double-1> event, too
    #
    set menu .menu
    menu $menu -tearoff no
    $menu add command -label "Display Contents" \
		      -command [list putContentsOfSelFolder $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag <<Button3>>  [bind TablelistBody <Button-1>]
    bind $bodyTag <<Button3>> +[bind TablelistBody <ButtonRelease-1>]
    bind $bodyTag <<Button3>> +[list postPopupMenu %X %Y]
    bind $bodyTag <Double-1>   [list putContentsOfSelFolder $tbl]

    #
    # Create three buttons within a frame child of the main widget
    #
    set bf .bf
    ttk::frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    ttk::button $b1 -width 10 -text "Refresh"
    ttk::button $b2 -width 10 -text "Parent"
    ttk::button $b3 -width 10 -text "Close" -command exit

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    if {[tablelist::getCurrentTheme] eq "aqua"} {
	grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
	grid $vsb	       -row 1 -column 1 -sticky ns
    } else {
	grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the content of the given directory
    #
    $tbl sortbycolumn 0
    putContents $dir $tbl root
}

#------------------------------------------------------------------------------
# putContents
#
# Outputs the content of the directory dir into the tablelist widget tbl, as
# child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc putContents {dir tbl nodeIdx} {
    #
    # The following check is necessary because this procedure
    # is also invoked by the "Refresh" and "Parent" buttons
    #
    if {[string compare $dir ""] != 0 &&
	(![file isdirectory $dir] || ![file readable $dir])} {
	bell
	if {[string compare $nodeIdx "root"] == 0} {
	    set choice [tk_messageBox -title "Error" -icon warning -message \
			"Cannot read directory \"[file nativename $dir]\"\
			-- replacing it with nearest existent ancestor" \
			-type okcancel -default ok]
	    if {[string compare $choice "ok"] == 0} {
		while {![file isdirectory $dir] || ![file readable $dir]} {
		    set dir [file dirname $dir]
		}
	    } else {
		return ""
	    }
	} else {
	    return ""
	}
    }

    if {[string compare $nodeIdx "root"] == 0} {
	if {[string compare $dir ""] == 0} {
	    if {[llength [file volumes]] == 1} {
		wm title . "Contents of the File System"
	    } else {
		wm title . "Contents of the File Systems"
	    }
	} else {
	    wm title . "Contents of the Directory \"[file nativename $dir]\""
	}

	$tbl delete 0 end
	set row 0
    } else {
	set row [expr {$nodeIdx + 1}]
    }

    #
    # Build a list from the data of the subdirectories and
    # files of the directory dir.  Prepend a "D" or "F" to
    # each entry's name and modification date & time, for
    # sorting purposes (it will be removed by formatString).
    #
    set itemList {}
    if {[string compare $dir ""] == 0} {
	foreach volume [file volumes] {
	    lappend itemList [list D[file nativename $volume] -1 D $volume]
	}
    } else {
	foreach entry [glob -nocomplain -types {d f} -directory $dir *] {
	    if {[catch {file mtime $entry} modTime] != 0} {
		continue
	    }

	    if {[file isdirectory $entry]} {
		lappend itemList [list D[file tail $entry] -1 \
		    D[clock format $modTime -format "%Y-%m-%d %H:%M"] $entry]
	    } else {
		lappend itemList [list F[file tail $entry] [file size $entry] \
		    F[clock format $modTime -format "%Y-%m-%d %H:%M"] ""]
	    }
	}
    }

    #
    # Sort the above list and insert it into the tablelist widget
    # tbl as list of children of the row identified by nodeIdx
    #
    set itemList [$tbl applysorting $itemList]
    $tbl insertchildlist $nodeIdx end $itemList

    #
    # Insert an image into the first cell of each newly inserted row
    #
    foreach item $itemList {
	set name [lindex $item end]
	if {[string compare $name ""] == 0} {			;# file
	    $tbl cellconfigure $row,0 -image fileImg
	} else {						;# directory
	    $tbl cellconfigure $row,0 -image clsdFolderImg
	    $tbl rowattrib $row pathName $name

	    #
	    # Mark the row as collapsed if the directory is non-empty
	    #
	    if {[file readable $name] && [llength \
		[glob -nocomplain -types {d f} -directory $name *]] != 0} {
		$tbl collapse $row
	    }
	}

	incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
	#
	# Configure the "Refresh" and "Parent" buttons
	#
	.bf.b1 configure -command [list refreshView $dir $tbl]
	set b2 .bf.b2
	if {[string compare $dir ""] == 0} {
	    $b2 configure -state disabled
	} else {
	    $b2 configure -state normal
	    set p [file dirname $dir]
	    if {[string compare $p $dir] == 0} {
		$b2 configure -command [list putContents "" $tbl root]
	    } else {
		$b2 configure -command [list putContents $p $tbl root]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# formatString
#
# Returns the substring obtained from the specified value by removing its first
# character.
#------------------------------------------------------------------------------
proc formatString val {
    return [string range $val 1 end]
}

#------------------------------------------------------------------------------
# formatSize
#
# Returns an empty string if the specified value is negative and the value
# itself in user-friendly format otherwise.
#------------------------------------------------------------------------------
proc formatSize val {
    if {$val < 0} {
	return ""
    } elseif {$val < 1024} {
	return "$val bytes"
    } elseif {$val < 1048576} {
	return [format "%.1f KB" [expr {$val / 1024.0}]]
    } elseif {$val < 1073741824} {
	return [format "%.1f MB" [expr {$val / 1048576.0}]]
    } else {
	return [format "%.1f GB" [expr {$val / 1073741824.0}]]
    }
}

#------------------------------------------------------------------------------
# expandCmd
#
# Outputs the content of the directory whose leaf name is displayed in the
# first cell of the specified row of the tablelist widget tbl, as child items
# of the one identified by row, and updates the image displayed in that cell.
#------------------------------------------------------------------------------
proc expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
	set dir [$tbl rowattrib $row pathName]
	putContents $dir $tbl $row
    }

    if {[$tbl childcount $row] != 0} {
	$tbl cellconfigure $row,0 -image openFolderImg
    }
}

#------------------------------------------------------------------------------
# collapseCmd
#
# Updates the image displayed in the first cell of the specified row of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc collapseCmd {tbl row} {
    $tbl cellconfigure $row,0 -image clsdFolderImg
}

#------------------------------------------------------------------------------
# putContentsOfSelFolder
#
# Outputs the content of the selected folder into the tablelist widget tbl.
#------------------------------------------------------------------------------
proc putContentsOfSelFolder tbl {
    set row [$tbl curselection]
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		bell
	    } else {
		putContents $dir $tbl root
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	bell
    }
}

#------------------------------------------------------------------------------
# postPopupMenu
#
# Posts the pop-up menu .menu at the given screen position.  Before posting
# the menu, the procedure enables/disables its only entry, depending upon
# whether the selected item represents a readable directory or not.
#------------------------------------------------------------------------------
proc postPopupMenu {rootX rootY} {
    set tbl .tf.tbl
    set row [$tbl curselection]
    set menu .menu
    if {[$tbl hasrowattrib $row pathName]} {		;# directory item
	set dir [$tbl rowattrib $row pathName]
	if {[file isdirectory $dir] && [file readable $dir]} {
	    if {[llength [glob -nocomplain -types {d f} -directory $dir *]]
		== 0} {
		$menu entryconfigure 0 -state disabled
	    } else {
		$menu entryconfigure 0 -state normal
	    }
	} else {
	    bell
	    tk_messageBox -title "Error" -icon error -message \
		"Cannot read directory \"[file nativename $dir]\""
	    return ""
	}
    } else {						;# file item
	$menu entryconfigure 0 -state disabled
    }

    tk_popup $menu $rootX $rootY
}

#------------------------------------------------------------------------------
# refreshView
#
# Redisplays the content of the directory dir in the tablelist widget tbl and
# restores the expanded states of the folders as well as the vertical view.
#------------------------------------------------------------------------------
proc refreshView {dir tbl} {
    #
    # Save the vertical view and get the path names
    # of the folders displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
	set pathName [$tbl rowattrib $key pathName]
	set expandedFolders($pathName) 1
    }

    #
    # Redisplay the directory's (possibly changed) content and restore
    # the expanded states of the folders, along with the vertical view
    #
    putContents $dir $tbl root
    restoreExpandedStates $tbl root expandedFolders
    $tbl yview moveto [lindex $yView 0]
}

#------------------------------------------------------------------------------
# restoreExpandedStates
#
# Expands those children of the parent identified by nodeIdx that display
# folders whose path names are the names of the elements of the array specified
# by the last argument.
#------------------------------------------------------------------------------
proc restoreExpandedStates {tbl nodeIdx expandedFoldersName} {
    upvar $expandedFoldersName expandedFolders

    foreach key [$tbl childkeys $nodeIdx] {
	set pathName [$tbl rowattrib $key pathName]
	if {[string compare $pathName ""] != 0 &&
	    [info exists expandedFolders($pathName)]} {
	    $tbl expand $key -partly
	    restoreExpandedStates $tbl $key expandedFolders
	}
    }
}

displayContents ""

Added libs/tablelist6.0/demos/embeddedWindows.tcl.





























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the use of embedded windows in tablelist widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 6.0

wm title . "Tk Library Scripts"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create the font TkFixedFont if not yet present
#
catch {font create TkFixedFont -family Courier -size -12}

#
# Create an image to be displayed in buttons embedded in a tablelist widget
#
image create photo openImg -file [file join $dir open.gif]

#
# Create a vertically scrolled tablelist widget with 5
# dynamic-width columns and interactive sort capability
#
set tf .tf
frame $tf -class ScrollArea 
set tbl $tf.tbl
set vsb $tf.vsb
tablelist::tablelist $tbl \
    -columns {0 "File Name" left
	      0 "Bar Chart" center
	      0 "File Size" right
	      0 "View"      center
	      0 "Seen"      center} \
    -setgrid no -yscrollcommand [list $vsb set] -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -name fileName
$tbl columnconfigure 1 -formatcommand emptyStr -sortmode integer
$tbl columnconfigure 2 -name fileSize -sortmode integer
$tbl columnconfigure 4 -name seen
scrollbar $vsb -orient vertical -command [list $tbl yview]

proc emptyStr val { return "" }

#
# Create a bold font
#
set tblFont [$tbl cget -font]
set size [font actual $tblFont -size]
if {$size == 0} {					;# e.g., on Ubuntu
    set size -12
}
eval font create BoldFont [font actual $tblFont] -size $size -weight bold

#
# Populate the tablelist widget
#
cd $tk_library
set totalSize 0
set maxSize 0
foreach fileName [lsort [glob *.tcl]] {
    set fileSize [file size $fileName]
    $tbl insert end [list $fileName $fileSize $fileSize "" no]

    incr totalSize $fileSize
    if {$fileSize > $maxSize} {
	set maxSize $fileSize
    }
}
$tbl header insert 0 [list "[$tbl size] *.tcl files" "" $totalSize "" ""]
$tbl header rowconfigure 0 -foreground blue

#------------------------------------------------------------------------------
# createFrame
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget tbl, as well as a child frame representing the size of the
# file whose name is diplayed in the first column of the cell's row.
#------------------------------------------------------------------------------
proc createFrame {tbl row col w} {
    #
    # Create the frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w -width 102 -height 14 -background ivory -borderwidth 1 \
	     -relief solid
    bindtags $w [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Create the child frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w.f -height 12 -background red -borderwidth 1 -relief raised
    bindtags $w.f [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Manage the child frame
    #
    set fileSize [$tbl cellcget $row,fileSize -text]
    place $w.f -relwidth [expr {double($fileSize) / $::maxSize}]
}

#------------------------------------------------------------------------------
# createButton
#
# Creates a button widget w to be embedded into the specified cell of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc createButton {tbl row col w} {
    set key [$tbl getkeys $row]
    button $w -image openImg -highlightthickness 0 -takefocus 0 \
	      -command [list viewFile $tbl $key]
}

#------------------------------------------------------------------------------
# viewFile
#
# Displays the content of the file whose name is contained in the row with the
# given key of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc viewFile {tbl key} {
    set top .top$key
    if {[winfo exists $top]} {
	raise $top
	return ""
    }

    toplevel $top
    set fileName [$tbl cellcget k$key,fileName -text]
    wm title $top "File \"$fileName\""

    #
    # Create a vertically scrolled text widget as a grandchild of the toplevel
    #
    set tf $top.tf
    frame $tf -class ScrollArea 
    set txt $tf.txt
    set vsb $tf.vsb
    text $txt -background white -font TkFixedFont -setgrid yes \
	      -yscrollcommand [list $vsb set]
    catch {$txt configure -tabstyle wordprocessor}	;# for Tk 8.5 and above
    scrollbar $vsb -orient vertical -command [list $txt yview]

    #
    # Insert the file's content into the text widget
    #
    set chan [open $fileName]
    $txt insert end [read $chan]
    close $chan

    set btn [button $top.btn -text "Close" -command [list destroy $top]]

    #
    # Manage the widgets
    #
    grid $txt -row 0 -column 0 -sticky news
    grid $vsb -row 0 -column 1 -sticky ns
    grid rowconfigure    $tf 0 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $btn -side bottom -pady 10
    pack $tf  -side top -expand yes -fill both

    #
    # Mark the file as seen
    #
    $tbl rowconfigure k$key -font BoldFont
    $tbl cellconfigure k$key,seen -text yes
}

#------------------------------------------------------------------------------

#
# Create embedded windows in the columns no. 1 and 3
#
set rowCount [$tbl size]
for {set row 0} {$row < $rowCount} {incr row} {
    $tbl cellconfigure $row,1 -window createFrame -stretchwindow yes
    $tbl cellconfigure $row,3 -window createButton
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
if {[string compare $winSys "aqua"] == 0} {		;# see option.tcl
    grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
    grid $vsb		   -row 1 -column 1 -sticky ns
} else {
    grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
}
grid rowconfigure    $tf 1 -weight 1
grid columnconfigure $tf 0 -weight 1
pack $btn -side bottom -pady 10
pack $tf  -side top -expand yes -fill both

Added libs/tablelist6.0/demos/embeddedWindows_tile.tcl.



































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the use of embedded windows in tablelist widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0

wm title . "Tile Library Scripts"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option_tile.tcl]

#
# Create the font TkFixedFont if not yet present
#
catch {font create TkFixedFont -family Courier -size -12}

#
# Create an image to be displayed in buttons embedded in a tablelist widget
#
image create photo openImg -file [file join $dir open.gif]

if {[tablelist::getCurrentTheme] eq "aqua"} {
    #
    # Work around the improper appearance of the tile scrollbars
    #
    interp alias {} ttk::scrollbar {} ::scrollbar
} else {
    #
    # Make the embedded buttons as small as possible.  Recall that in most
    # themes, the tile buttons consist of the following element hierarchy:
    #
    # Button.border
    #     Button.focus	      (one of its options is -focusthickness)
    #         Button.padding  (two of its options are -padding and -shiftrelief)
    #             Button.label
    #
    if {[info commands "::ttk::style"] ne ""} {
	interp alias {} styleConfig {} ttk::style configure
    } elseif {[string compare $tile::version "0.7"] >= 0} {
	interp alias {} styleConfig {} style configure
    } else {
	interp alias {} styleConfig {} style default
    }
    styleConfig Embedded.TButton -focusthickness 0 -padding 0 -shiftrelief 0
}

#
# Create a vertically scrolled tablelist widget with 5
# dynamic-width columns and interactive sort capability
#
set tf .tf
ttk::frame $tf -class ScrollArea
set tbl $tf.tbl
set vsb $tf.vsb
tablelist::tablelist $tbl \
    -columns {0 "File Name" left
	      0 "Bar Chart" center
	      0 "File Size" right
	      0 "View"      center
	      0 "Seen"      center} \
    -setgrid no -yscrollcommand [list $vsb set] -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -name fileName
$tbl columnconfigure 1 -formatcommand emptyStr -sortmode integer
$tbl columnconfigure 2 -name fileSize -sortmode integer
$tbl columnconfigure 4 -name seen
ttk::scrollbar $vsb -orient vertical -command [list $tbl yview]

proc emptyStr val { return "" }

#
# Create a bold font
#
set tblFont [$tbl cget -font]
set size [font actual $tblFont -size]
if {$size == 0} {					;# e.g., on Ubuntu
    set size -12
}
eval font create BoldFont [font actual $tblFont] -size $size -weight bold

#
# Populate the tablelist widget
#
if {[info exists ttk::library]} {
    cd $ttk::library
} else {
    cd $tile::library
}
set totalSize 0
set maxSize 0
foreach fileName [lsort [glob *.tcl]] {
    set fileSize [file size $fileName]
    $tbl insert end [list $fileName $fileSize $fileSize "" no]

    incr totalSize $fileSize
    if {$fileSize > $maxSize} {
	set maxSize $fileSize
    }
}
$tbl header insert 0 [list "[$tbl size] *.tcl files" "" $totalSize "" ""]
$tbl header rowconfigure 0 -foreground blue

#------------------------------------------------------------------------------
# createFrame
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget tbl, as well as a child frame representing the size of the
# file whose name is diplayed in the first column of the cell's row.
#------------------------------------------------------------------------------
proc createFrame {tbl row col w} {
    #
    # Create the frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w -width 102 -height 14 -background ivory -borderwidth 1 \
	     -relief solid
    bindtags $w [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Create the child frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w.f -height 12 -background red -borderwidth 1 -relief raised
    bindtags $w.f [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Manage the child frame
    #
    set fileSize [$tbl cellcget $row,fileSize -text]
    place $w.f -relwidth [expr {double($fileSize) / $::maxSize}]
}

#------------------------------------------------------------------------------
# createButton
#
# Creates a button widget w to be embedded into the specified cell of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc createButton {tbl row col w} {
    set key [$tbl getkeys $row]
    ttk::button $w -style Embedded.TButton -image openImg -takefocus 0 \
		   -command [list viewFile $tbl $key]
}

#------------------------------------------------------------------------------
# viewFile
#
# Displays the content of the file whose name is contained in the row with the
# given key of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc viewFile {tbl key} {
    set top .top$key
    if {[winfo exists $top]} {
	raise $top
	return ""
    }

    toplevel $top
    set fileName [$tbl cellcget k$key,fileName -text]
    wm title $top "File \"$fileName\""

    #
    # Create a vertically scrolled text widget as a grandchild of the toplevel
    #
    set tf $top.tf
    ttk::frame $tf -class ScrollArea
    set txt $tf.txt
    set vsb $tf.vsb
    text $txt -background white -font TkFixedFont -highlightthickness 0 \
	      -setgrid yes -yscrollcommand [list $vsb set]
    catch {$txt configure -tabstyle wordprocessor}	;# for Tk 8.5 and above
    ttk::scrollbar $vsb -orient vertical -command [list $txt yview]

    #
    # Insert the file's content into the text widget
    #
    set chan [open $fileName]
    $txt insert end [read $chan]
    close $chan

    set bf $top.bf
    ttk::frame $bf
    set btn [ttk::button $bf.btn -text "Close" -command [list destroy $top]]

    #
    # Manage the widgets
    #
    grid $txt -row 0 -column 0 -sticky news
    grid $vsb -row 0 -column 1 -sticky ns
    grid rowconfigure    $tf 0 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $btn -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Mark the file as seen
    #
    $tbl rowconfigure k$key -font BoldFont
    $tbl cellconfigure k$key,seen -text yes
}

#------------------------------------------------------------------------------

#
# Create embedded windows in the columns no. 1 and 3
#
set rowCount [$tbl size]
for {set row 0} {$row < $rowCount} {incr row} {
    $tbl cellconfigure $row,1 -window createFrame -stretchwindow yes
    $tbl cellconfigure $row,3 -window createButton
}

set bf .bf
ttk::frame $bf
set btn [ttk::button $bf.btn -text "Close" -command exit]

#
# Manage the widgets
#
grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
if {[tablelist::getCurrentTheme] eq "aqua"} {
    grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
    grid $vsb		   -row 1 -column 1 -sticky ns
} else {
    grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
}
grid rowconfigure    $tf 1 -weight 1
grid columnconfigure $tf 0 -weight 1
pack $btn -pady 10
pack $bf -side bottom -fill x
pack $tf -side top -expand yes -fill both

Added libs/tablelist6.0/demos/file.gif.

cannot compute difference between binary files

Added libs/tablelist6.0/demos/images.tcl.













































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Creates some images.
#
# Copyright (c) 2011-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Create two images, to be displayed in tablelist cells with boolean values
#
image create photo checkedImg   -file [file join $dir checked.gif]
image create photo uncheckedImg -file [file join $dir unchecked.gif]

#
# Create 16 images representing different colors
#
set colorNames {
    "red" "green" "blue" "magenta"
    "yellow" "cyan" "light gray" "white"
    "dark red" "dark green" "dark blue" "dark magenta"
    "dark yellow" "dark cyan" "dark gray" "black"
}
set colorValues {
    #FF0000 #00FF00 #0000FF #FF00FF
    #FFFF00 #00FFFF #C0C0C0 #FFFFFF
    #800000 #008000 #000080 #800080
    #808000 #008080 #808080 #000000
}
foreach name $colorNames value $colorValues {
    set colors($name) $value
}
foreach value $colorValues {
    image create photo img$value -height 13 -width 13
    img$value put gray50 -to 0 0 13 1				;# top edge
    img$value put gray50 -to 0 1 1 12				;# left edge
    img$value put gray75 -to 0 12 13 13				;# bottom edge
    img$value put gray75 -to 12 1 13 12				;# right edge
    img$value put $value -to 1 1 12 12
}

Added libs/tablelist6.0/demos/iwidgets.tcl.



































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the Iwidgets package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.4				;# because of "-compound"
package require tablelist 6.0
if {[catch {package require iwidgets} result1] != 0 &&
    [catch {package require Iwidgets} result2] != 0} {
    error "$result1; $result2"
}

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*textBackground			white
option add *Tablelist*Entry.disabledBackground		white
option add *Tablelist*Entry.disabledForeground		black
option add *Tablelist*Dateentry*Label.background	white
option add *Tablelist*Timeentry*Label.background	white

#
# Register some widgets from the Iwidgets package for interactive cell editing
#
tablelist::addIncrEntryfield
tablelist::addIncrSpinint
tablelist::addIncrCombobox
tablelist::addIncrDateTimeWidget dateentry -seconds
tablelist::addIncrDateTimeWidget timeentry -seconds

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entryfield \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinint
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -pasting no -fixed 20
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w insert list end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    $w configure -pasting no -fixed 6 -validate numeric
	}

	dataBits {
	    #
	    # Configure the spinint widget
	    #
	    $w configure -range {5 8} -wrap no -pasting no -fixed 1 \
			 -validate {regexp {^[5-8]$} %c}
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end None Even Odd Mark Space
	    $w configure -editable no -listheight 120
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end 1 1.5 2
	    $w configure -editable no -listheight 90
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end XON/XOFF RTS/CTS None
	    $w configure -editable no -listheight 90
	}

	actDate {
	    #
	    # Set the date format "%Y-%m-%d"
	    #
	    $w configure -int yes
	}

	actTime {
	    #
	    # Set the time format "%H:%M:%S"
	    #
	    $w configure -format military
	}

	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
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
	    }
	}

	dataBits {
	    #
	    # Check whether the # of data bits is an integer in the range 5..8
	    #
	    if {![regexp {^[5-8]$} $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message \
		    "The # of data bits must be an integer in the range 5..8"
		$tbl rejectinput
	    }
	}

	actDate {
	    #
	    # 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 $text]
	    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 {
	    #
	    # 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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}

Added libs/tablelist6.0/demos/iwidgets_tile.tcl.















































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the Iwidgets package and of the Tk core checkbutton and
# menubutton widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0
if {[catch {package require iwidgets} result1] != 0 &&
    [catch {package require Iwidgets} result2] != 0} {
    error "$result1; $result2"
}

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*textBackground			white
option add *Tablelist*Entry.disabledBackground		white
option add *Tablelist*Entry.disabledForeground		black
option add *Tablelist*Dateentry*Label.background	white
option add *Tablelist*Timeentry*Label.background	white

#
# Register some widgets from the Iwidgets package for interactive cell editing
#
tablelist::addIncrEntryfield
tablelist::addIncrSpinint
tablelist::addIncrCombobox
tablelist::addIncrDateTimeWidget dateentry -seconds
tablelist::addIncrDateTimeWidget timeentry -seconds

#
# 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
#
set f [ttk::frame .f]

#
# 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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entryfield \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinint
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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 -pasting no -fixed 20
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w insert list end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    $w configure -pasting no -fixed 6 -validate numeric
	}

	dataBits {
	    #
	    # Configure the spinint widget
	    #
	    $w configure -range {5 8} -wrap no -pasting no -fixed 1 \
			 -validate {regexp {^[5-8]$} %c}
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end None Even Odd Mark Space
	    $w configure -editable no -listheight 120
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end 1 1.5 2
	    $w configure -editable no -listheight 90
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w insert list end XON/XOFF RTS/CTS None
	    $w configure -editable no -listheight 90
	}

	actDate {
	    #
	    # Set the date format "%Y-%m-%d"
	    #
	    $w configure -int yes
	}

	actTime {
	    #
	    # Set the time format "%H:%M:%S"
	    #
	    $w configure -format military
	}

	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
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
	    }
	}

	dataBits {
	    #
	    # Check whether the # of data bits is an integer in the range 5..8
	    #
	    if {![regexp {^[5-8]$} $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message \
		    "The # of data bits must be an integer in the range 5..8"
		$tbl rejectinput
	    }
	}

	actDate {
	    #
	    # 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 $text]
	    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 {
	    #
	    # 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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}

Added libs/tablelist6.0/demos/leaf.xbm.











>
>
>
>
>
1
2
3
4
5
#define leaf_width 14
#define leaf_height 12
static unsigned char leaf_bits[] = {
   0xff, 0x3f, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20,
   0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0xff, 0x3f};

Added libs/tablelist6.0/demos/miscWidgets.tcl.

























































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of Bryan
# Oakley's combobox, the mentry widgets of type "Date" and "Time", and of the
# Tk core entry, spinbox, checkbutton, and menubutton widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tk 8.4		;# because of "-compound" and the spinbox widget
package require tablelist 6.0
package require combobox
package require mentry

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*Entry.background			white
option add *Tablelist*Spinbox.background		white
option add *Tablelist*Spinbox.readonlyBackground	white
option add *Tablelist*Combobox.background		white
option add *Tablelist*Combobox.elementBorderWidth	2
option add *Tablelist*Mentry.background			white

#
# Register Bryan Oakley's combobox widget as well as the mentry
# widgets of type "Date" and "Time" for interactive cell editing
#
tablelist::addOakleyCombobox
tablelist::addDateMentry Ymd -
tablelist::addTimeMentry HMS :

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinbox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateMentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeMentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both

#------------------------------------------------------------------------------
# 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
	    #
	    wcb::callback $w before insert {wcb::checkEntryLen 20}
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w list insert end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    wcb::callback [$tbl entrypath] before insert \
		{wcb::checkEntryLen 6} {wcb::checkStrForRegExp {^[0-9]*$}}
	}

	dataBits {
	    #
	    # Configure the spinbox
	    #
	    $w configure -from 5 -to 8 -state readonly
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end None Even Odd Mark Space
	    $w configure -editable no
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end 1 1.5 2
	    $w configure -editable no
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end XON/XOFF RTS/CTS None
	    $w configure -editable no
	}

	actDate -
	actTime {
	    #
	    # Configure the mentry widget
	    #
	    $w configure -justify center
	}

	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
}

#
# Message strings corresponding to the values
# returned by mentry::getClockVal on failure
#
array set msgs {
    EMPTY	"Field value missing"
    BAD		"Invalid field value"
    BAD_DATE	"Invalid date"
    BAD_YEAR	"Unsupported year"
}

#------------------------------------------------------------------------------
# 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
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 $text]
	    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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}

Added libs/tablelist6.0/demos/miscWidgets_tile.tcl.





































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of Bryan
# Oakley's combobox, the mentry widgets of type "Date" and "Time", and of the
# Tk core entry, spinbox, checkbutton, and menubutton widgets.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0
package require combobox
package require mentry

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*Entry.background			white
option add *Tablelist*Spinbox.background		white
option add *Tablelist*Spinbox.readonlyBackground	white
option add *Tablelist*Combobox.background		white
option add *Tablelist*Combobox.elementBorderWidth	2
option add *Tablelist*Mentry.background			white

#
# Register Bryan Oakley's combobox widget as well as the mentry
# widgets of type "Date" and "Time" for interactive cell editing
#
tablelist::addOakleyCombobox
tablelist::addDateMentry Ymd -
tablelist::addTimeMentry HMS :

#
# 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
#
set f [ttk::frame .f]

#
# 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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 -name available -editable yes -editwindow checkbutton \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow combobox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow spinbox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow combobox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow combobox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow combobox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow dateMentry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow timeMentry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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
	    #
	    wcb::callback $w before insert {wcb::checkEntryLen 20}
	}

	baudRate {
	    #
	    # Populate the combobox and allow no more
	    # than 6 digits in its entry component
	    #
	    $w list insert end 50 75 110 300 1200 2400 4800 9600 19200 38400 \
			       57600 115200 230400 460800 921600
	    wcb::callback [$tbl entrypath] before insert \
		{wcb::checkEntryLen 6} {wcb::checkStrForRegExp {^[0-9]*$}}
	}

	dataBits {
	    #
	    # Configure the spinbox
	    #
	    $w configure -from 5 -to 8 -state readonly
	}

	parity {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end None Even Odd Mark Space
	    $w configure -editable no
	}

	stopBits {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end 1 1.5 2
	    $w configure -editable no
	}

	handshake {
	    #
	    # Populate the combobox and make it non-editable
	    #
	    $w list insert end XON/XOFF RTS/CTS None
	    $w configure -editable no
	}

	actDate -
	actTime {
	    #
	    # Configure the mentry widget
	    #
	    $w configure -justify center
	}

	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
}

#
# Message strings corresponding to the values
# returned by mentry::getClockVal on failure
#
array set msgs {
    EMPTY	"Field value missing"
    BAD		"Invalid field value"
    BAD_DATE	"Invalid date"
    BAD_YEAR	"Unsupported year"
}

#------------------------------------------------------------------------------
# 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
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 $text]
	    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 {
	    #
	    # Check whether the last argument is a clock value in seconds
	    #
	    if {![string is digit $text]} {
		bell
		tk_messageBox -title "Error" -icon error -message $::msgs($text)
		$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 actDate [$tbl cellcget $row,actDate -text]
	    set actClock [clock scan [formatTime $text] -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,actDate -text $actClock
		return $actClock
	    }
	}

	color {
	    #
	    # Update the image contained in the cell
	    #
	    $tbl cellconfigure $row,$col -image img$::colors($text)
	}
    }

    return $text
}

Added libs/tablelist6.0/demos/open.gif.

cannot compute difference between binary files

Added libs/tablelist6.0/demos/openFolder.gif.

cannot compute difference between binary files

Added libs/tablelist6.0/demos/option.tcl.





















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Contains some Tk option database settings.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Get the current windowing system ("x11", "win32", "classic", or "aqua")
#
if {[catch {tk windowingsystem} winSys] != 0} {
    switch $::tcl_platform(platform) {
	unix      { set winSys x11 }
	windows   { set winSys win32 }
	macintosh { set winSys classic }
    }
}

#
# Add some entries to the Tk option database
#
if {[string compare $winSys "x11"] == 0} {
    #
    # Create the font TkDefaultFont if not yet present
    #
    catch {font create TkDefaultFont -family Helvetica -size -12}

    option add *Font			TkDefaultFont
    option add *selectBackground	#5294e2
    option add *selectForeground	white
}
option add *Tablelist.background	white
option add *Tablelist.stripeBackground	#f0f0f0
option add *Tablelist.setGrid		yes
option add *Tablelist.movableColumns	yes
option add *Tablelist.labelCommand	tablelist::sortByColumn
option add *Tablelist.labelCommand2	tablelist::addToSortColumns
option add *ScrollArea.borderWidth			1
option add *ScrollArea.relief				sunken
option add *ScrollArea.Tablelist.borderWidth		0
option add *ScrollArea.Tablelist.highlightThickness	0
option add *ScrollArea.Text.borderWidth			0
option add *ScrollArea.Text.highlightThickness		0

Added libs/tablelist6.0/demos/option_tile.tcl.







































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Contains some Tk option database settings.
#
# Copyright (c) 2004-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Get the current windowing system ("x11", "win32", or
# "aqua") and add some entries to the Tk option database
#
if {[tk windowingsystem] eq "x11"} {
    option add *Font			TkDefaultFont
}
tablelist::setThemeDefaults
if {[tablelist::getCurrentTheme] eq "aqua"} {
    option add *Listbox.selectBackground \
	       $tablelist::themeDefaults(-selectbackground)
    option add *Listbox.selectForeground \
	       $tablelist::themeDefaults(-selectforeground)
} else {
    option add *selectBackground  $tablelist::themeDefaults(-selectbackground)
    option add *selectForeground  $tablelist::themeDefaults(-selectforeground)
}
option add *selectBorderWidth     $tablelist::themeDefaults(-selectborderwidth)
option add *Tablelist.background	white
option add *Tablelist.stripeBackground	#f0f0f0
option add *Tablelist.setGrid		yes
option add *Tablelist.movableColumns	yes
option add *Tablelist.labelCommand	tablelist::sortByColumn
option add *Tablelist.labelCommand2	tablelist::addToSortColumns
option add *ScrollArea.borderWidth		1
option add *ScrollArea.relief			sunken
option add *ScrollArea.Tablelist.borderWidth	0
option add *ScrollArea.Text.borderWidth		0
option add *ScrollArea.Text.highlightThickness	0

Added libs/tablelist6.0/demos/styles.tcl.













































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates some ways of improving the look & feel of a tablelist widget.
#
# Copyright (c) 2002-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist 6.0

wm title . "Tablelist Styles"

#
# Get the current windowing system ("x11", "win32", "classic",
# or "aqua") and add some entries to the Tk option database
#
if {[catch {tk windowingsystem} winSys] != 0} {
    switch $::tcl_platform(platform) {
	unix      { set winSys x11 }
	windows   { set winSys win32 }
	macintosh { set winSys classic }
    }
}
if {[string compare $winSys "x11"] == 0} {
    #
    # Create the font TkDefaultFont if not yet present
    #
    catch {font create TkDefaultFont -family Helvetica -size -12}

    option add *Font			TkDefaultFont
    option add *selectBackground	#5294e2
    option add *selectForeground	white
}

#
# Create, configure, and populate 8 tablelist widgets
#
frame .f
for {set n 0} { $n < 8} {incr n} {
    set tbl .f.tbl$n
    tablelist::tablelist $tbl \
	-columntitles {"Label 0" "Label 1" "Label 2" "Label 3"} \
	-background white -height 4 -width 40 -stretch all
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }

    switch $n {
	1 {
	    $tbl configure -showseparators yes
	}
	2 {
	    $tbl configure -stripebackground #f0f0f0
	}
	3 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	}
	4 {
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	5 {
	    $tbl configure -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	6 {
	    $tbl configure -stripebackground #f0f0f0
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
	7 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
    }

    foreach row {0 1 2 3} {
	$tbl insert end \
	     [list "Cell $row,0" "Cell $row,1" "Cell $row,2" "Cell $row,3"]
    }
}

button .close -text "Close" -command exit
frame .bottom -height 10

#
# Manage the widgets
#
grid .f.tbl0 .f.tbl1 -sticky news -padx 5 -pady 5
grid .f.tbl2 .f.tbl3 -sticky news -padx 5 -pady 5
grid .f.tbl4 .f.tbl5 -sticky news -padx 5 -pady 5
grid .f.tbl6 .f.tbl7 -sticky news -padx 5 -pady 5
grid rowconfigure    .f {0 1 2 3} -weight 1
grid columnconfigure .f {0 1}     -weight 1
pack .bottom .close -side bottom
pack .f -side top -expand yes -fill both -padx 5 -pady 5

Added libs/tablelist6.0/demos/styles_tile.tcl.















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates some ways of improving the look & feel of a tablelist widget.
#
# Copyright (c) 2002-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0

wm title . "Tablelist Styles"

#
# Improve the window's appearance by using a tile
# frame as a container for the other widgets
#
set f [ttk::frame .f]

#
# Create, configure, and populate 8 tablelist widgets
#
ttk::frame $f.f
for {set n 0} { $n < 8} {incr n} {
    set tbl $f.f.tbl$n
    tablelist::tablelist $tbl \
	-columntitles {"Label 0" "Label 1" "Label 2" "Label 3"} \
	-background white -stripebackground "" -height 4 -width 40 -stretch all
    if {[$tbl cget -selectborderwidth] == 0} {
	$tbl configure -spacing 1
    }

    switch $n {
	1 {
	    $tbl configure -showseparators yes
	}
	2 {
	    $tbl configure -stripebackground #f0f0f0
	}
	3 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	}
	4 {
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	5 {
	    $tbl configure -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow
	    $tbl columnconfigure 3 -background LightCyan
	}
	6 {
	    $tbl configure -stripebackground #f0f0f0
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
	7 {
	    $tbl configure -stripebackground #f0f0f0 -showseparators yes
	    $tbl columnconfigure 1 -background LightYellow \
		-stripebackground #f0f0d2
	    $tbl columnconfigure 3 -background LightCyan \
		-stripebackground #d2f0f0
	}
    }

    foreach row {0 1 2 3} {
	$tbl insert end \
	     [list "Cell $row,0" "Cell $row,1" "Cell $row,2" "Cell $row,3"]
    }
}

ttk::button $f.close -text "Close" -command exit
ttk::frame $f.bottom -height 10

#
# Manage the widgets
#
grid $f.f.tbl0 $f.f.tbl1 -sticky news -padx 5 -pady 5
grid $f.f.tbl2 $f.f.tbl3 -sticky news -padx 5 -pady 5
grid $f.f.tbl4 $f.f.tbl5 -sticky news -padx 5 -pady 5
grid $f.f.tbl6 $f.f.tbl7 -sticky news -padx 5 -pady 5
grid rowconfigure    $f.f {0 1 2 3} -weight 1
grid columnconfigure $f.f {0 1}     -weight 1
pack $f.bottom $f.close -side bottom
pack $f.f -side top -expand yes -fill both -padx 5 -pady 5
pack $f -expand yes -fill both

Added libs/tablelist6.0/demos/tileWidgets.tcl.





















































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Demonstrates the interactive tablelist cell editing with the aid of some
# widgets from the tile package and of the Tk core spinbox widget.
#
# Copyright (c) 2005-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require tablelist_tile 6.0

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
#
set f [ttk::frame .f]

#
# Work around the improper appearance of the tile scrollbars in the aqua theme
#
if {[tablelist::getCurrentTheme] eq "aqua"} {
    interp alias {} ttk::scrollbar {} ::scrollbar
}

#
# 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 \
    -height 0 -width 0
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
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow ttk::entry \
    -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; set the activation
# date & time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i < 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i < 8}] "Line $n" 9600 8 None 1 XON/XOFF \
	$clock $clock [lindex $colorNames $i]]

    set availImg [expr {($i < 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [ttk::button $f.btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
pack $f -expand yes -fill both

#------------------------------------------------------------------------------
# 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
	    #
	    set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
	    $tbl cellconfigure $row,$col -image $img
	}

	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
}

Added libs/tablelist6.0/demos/unchecked.gif.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/adwaita.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/ambiance.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/aqua.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/arc.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/arrowStyles.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/arrowStyles_vista.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/baghira.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/bicolor1.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/bicolor2.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/bicolor3.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/bicolor4.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/blueMenta.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/browse.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/browseTree.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/bwidget.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/classic1.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/classic2.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/classic3.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/classic4.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/config.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/dirViewer.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/dust.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/dustSand.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/embeddedWindows.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/embeddedWindows_tile.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/gtk.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/index.html.



























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>The Multi-Column Listbox and Tree Widget Package Tablelist 6.0</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content=
  "tablelist, multi-column, listbox, tree, widget, tile">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>The Multi-Column Listbox and Tree Widget Package Tablelist 6.0</h1>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>

  <hr>

  <h2>Contents</h2>

  <p><a href="tablelist.html">Tablelist Programmer's Guide</a></p>

  <p><a href="tablelistWidget.html">The <code>tablelist::tablelist</code>
  Command</a></p>

  <p><a href="tablelistColSort.html">Commands for Interactive Sorting by One or
  More Columns</a></p>

  <p><a href="tablelistBinding.html">Commands Related to Binding
  Scripts</a></p>

  <p><a href="tablelistThemes.html">Commands Related to Tile Themes</a></p>

  <p><a href="tablelistTkCore.html">Interactive Tablelist Cell Editing Using Tk
  Core Widgets</a></p>

  <p><a href="tablelistTile.html">Interactive Tablelist Cell Editing Using Tile
  Widgets</a></p>

  <p><a href="tablelistBWidget.html">Interactive Tablelist Cell Editing Using
  the BWidget Package</a></p>

  <p><a href="tablelistIwidgets.html">Interactive Tablelist Cell Editing Using
  the Iwidgets Package</a></p>

  <p><a href="tablelistCombobox.html">Interactive Tablelist Cell Editing Using
  the combobox Package</a></p>

  <p><a href="tablelistCtext.html">Interactive Tablelist Cell Editing Using
  the ctext Package</a></p>

  <p><a href="tablelistMentry.html">Interactive Tablelist Cell Editing Using
  the Mentry Package</a></p>
</body>
</html>

Added libs/tablelist6.0/doc/klearlooks.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/mate.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/menta.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/mint.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/mint2.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/newWave.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/oxygen1.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/oxygen2.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/phase.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/plain1.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/plain2.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/plain3.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/plain4.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/plastik.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/plastique.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/radiance.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/styles.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/stylesheet.css.

















>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
/* generic class defining a top margin whose height equals the font size */
.tm {margin-top: 1em}

/* background and border for the <pre> tag */
pre {background: #F7F7F7; border: silver solid 1px}

/* color for the <span> tag */
span {color: #E00000}

Added libs/tablelist6.0/doc/tablelist.html.













































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
<html>
<head>
  <title>Tablelist Programmer's Guide</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content=
  "tablelist, multi-column, listbox, tree, widget, tile">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Tablelist Programmer's Guide</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <h4><a href="#overview">Overview</a></h4>

  <ul>
    <li><a href="#ov_what">What Is Tablelist?</a></li>

    <li><a href="#ov_get">How to Get It?</a></li>

    <li><a href="#ov_install">How to Install It?</a></li>

    <li><a href="#ov_use">How to Use It?</a></li>

    <li><a href="#ov_tile">More on Tablelist_tile</a></li>
  </ul>

  <h4><a href="#examples">Examples</a></h4>

  <ul>
    <li><a href="#ex_config">A tablelist Widget for Displaying and Editing
    Configuration Options</a></li>

    <li><a href="#ex_browse">Two Widget Browsers Based on a tablelist</a></li>

    <li><a href="#ex_dirViewer">A Directory Viewer Based on a
    tablelist</a></li>

    <li><a href="#ex_styles">Improving the Look &amp; Feel of a tablelist
    Widget</a></li>

    <li><a href="#ex_editing">Advanced Interactive tablelist Cell
    Editing</a></li>

    <li><a href="#ex_windows">A tablelist Widget Containing Embedded
    Windows</a></li>

    <li><a href="#ex_tile">Tile-Based Demo Scripts</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <h3 id="ov_what">What Is Tablelist?</h3>

  <p>Tablelist is a library package for Tcl/Tk versions 8.0 or higher, written
  in pure Tcl/Tk code.&nbsp; It contains:</p>

  <ul>
    <li>the implementation of the <a href=
    "tablelistWidget.html"><b>tablelist</b> mega-widget</a>, including a
    general utility module for mega-widgets;</li>

    <li>a demo script containing a useful procedure that displays the
    configuration options of an arbitrary widget in a tablelist and enables you
    to edit their values interactively;</li>

    <li>a demo script implementing a widget browser based on a tablelist used
    as multi-column listbox;</li>

    <li>a demo script implementing a widget browser based on a tablelist used
    as multi-column tree widget;</li>

    <li>a demo script implementing a directory viewer based on a tablelist used
    as multi-column tree widget;</li>

    <li>a demo script showing several ways to improve the appearance of a
    tablelist widget;</li>

    <li>four further demo scripts, illustrating the interactive cell editing
    with the aid of various widgets from the Tk core and from the packages
    tile, BWidget, Iwidgets, combobox (by Bryan Oakley), and Mentry;</li>

    <li>one further demo script, with a tablelist widget containing embedded
    windows;</li>

    <li>tile-based counterparts of the above-mentioned demo scripts;</li>

    <li>this tutorial;</li>

    <li>reference pages in HTML format.</li>
  </ul>

  <p>A tablelist is a multi-column listbox and tree widget.&nbsp; The width of
  each column can be dynamic (i.e., just large enough to hold all its elements,
  including the header) or static (specified in characters or pixels).&nbsp;
  The columns are, per default, resizable.&nbsp; The alignment of each column
  can be specified as <code>left</code>, <code>right</code>, or
  <code>center</code>.</p>

  <p>The columns, rows, and cells can be configured individually.&nbsp; Several
  of the global and column-specific options refer to the header titles,
  implemented as label widgets.&nbsp; For instance, the
  <code>-labelcommand</code> option specifies a Tcl command to be invoked when
  mouse button 1 is released over a header label.&nbsp; The most common value
  of this option sorts the items based on the respective column.</p>

  <p>The Tablelist package provides a great variety of tree styles controlling
  the look &amp; feel of the column that displays the tree hierarchy with the
  aid of indentations and expand/collapse controls.</p>

  <p>Interactive editing of the elements of a tablelist widget can be enabled
  for individual cells and for entire columns.&nbsp; A great variety of widgets
  from the Tk core and from the packages tile, BWidget, Iwidgets, combobox,
  ctext, and Mentry (or Mentry_tile) is supported for being used as embedded
  edit window.&nbsp; In addition, a rich set of keyboard bindings is provided
  for a comfortable navigation between the editable cells.</p>

  <p>The Tcl command corresponding to a tablelist widget is very similar to the
  one associated with a normal listbox.&nbsp; There are column-, row-, and
  cell-specific counterparts of the <code>configure</code> and
  <code>cget</code> subcommands (<code>columnconfigure</code>,
  <code>rowconfigure</code>, <code>cellconfigure</code>, ...).&nbsp; They can
  be used, among others, to insert images into the cells and the header labels,
  or to insert embedded windows into the cells.&nbsp; The <code>index</code>,
  <code>nearest</code>, and <code>see</code> command options refer to the rows,
  but similar subcommands are provided for the columns and cells
  (<code>columnindex</code>, <code>cellindex</code>, ...).&nbsp; The items can
  be sorted with the <code>sort</code>, <code>sortbycolumn</code>, and
  <code>sortbycolumnlist</code> command options.</p>

  <p>The bindings defined for the body of a tablelist widget make it behave
  just like a normal listbox.&nbsp; This includes the support for the virtual
  event <code>&lt;&lt;ListboxSelect&gt;&gt;</code> (which is equivalent to
  <code>&lt;&lt;TablelistSelect&gt;&gt;</code>).&nbsp; In addition, versions
  2.3 or higher of the widget callback package Wcb (written in pure Tcl/Tk code
  as well) can be used to define callbacks for the <code>activate</code>,&nbsp;
  <code>selection set</code>,&nbsp; and&nbsp; <code>selection
  clear</code>&nbsp; commands, and Wcb versions 3.0 or higher also support
  callbacks for the <code>activatecell</code>,&nbsp; <code>cellselection
  set</code>,&nbsp; and&nbsp; <code>cellselection clear</code>&nbsp;
  commands.&nbsp; The download location of Wcb is</p>

  <blockquote>
    <address>
      <a href="http://www.nemethi.de">http://www.nemethi.de</a>
    </address>
  </blockquote>

  <h3 id="ov_get">How to Get It?</h3>

  <p>Tablelist is available for free download from the same URL as Wcb.&nbsp;
  The distribution file is <code>tablelist6.0.tar.gz</code> for UNIX and
  <code>tablelist6_0.zip</code> for Windows.&nbsp; These files contain the same
  information, except for the additional carriage return character preceding
  the linefeed at the end of each line in the text files for Windows.</p>

  <p>Tablelist is also included in tklib, which has the address</p>

  <blockquote>
    <address>
      <a href="http://core.tcl.tk/tklib">http://core.tcl.tk/tklib</a>
    </address>
  </blockquote>

  <h3 id="ov_install">How to Install It?</h3>

  <p>Install the package as a subdirectory of one of the directories given by
  the <code>auto_path</code> variable.&nbsp; For example, you can install it as
  a directory at the same level as the Tcl and Tk script libraries.&nbsp; The
  locations of these library directories are given by the
  <code>tcl_library</code> and <code>tk_library</code> variables,
  respectively.</p>

  <p>To install Tablelist <i>on UNIX</i>, <code>cd</code> to the desired
  directory and unpack the distribution file
  <code>tablelist6.0.tar.gz</code>:</p>

  <blockquote>
    <pre>
gunzip -c tablelist6.0.tar.gz | tar -xf -
</pre>
  </blockquote>

  <p>This command will create a directory named <code>tablelist6.0</code>, with
  the subdirectories <code>demos</code>, <code>doc</code>, and
  <code>scripts</code>.</p>

  <p><i>On Windows</i>, use WinZip or some other program capable of unpacking
  the distribution file <code>tablelist6_0ip</code> into the directory
  <code>tablelist6.0</code>, with the subdirectories <code>demos</code>,
  <code>doc</code>, and <code>scripts</code>.</p>

  <p>The file <code>tablelistEdit.tcl</code> in the <code>scripts</code>
  directory is only needed for applications making use of interactive cell
  editing.&nbsp; Similarly, the file <code>tablelistMove.tcl</code> in the same
  directory is only required for scripts invoking the <code>move</code> or
  <code>movecolumn</code> command.&nbsp; Finally, the file
  <code>tablelistThemes.tcl</code> is only needed for applications using the
  package Tablelist_tile (see next section).</p>

  <p>Next, you should check the exact version number of your Tcl/Tk
  distribution, given by the <code>tcl_patchLevel</code> and
  <code>tk_patchLevel</code> variables.&nbsp; If you are using Tcl/Tk version
  8.2.X, 8.3.0 - 8.3.2, or 8.4a1, then you should upgrade your Tcl/Tk
  distribution to a higher release.&nbsp; This is because a bug in these Tcl
  versions (fixed in Tcl 8.3.3 and 8.4a2) causes excessive memory use when
  calling&nbsp; <code>info exists</code>&nbsp; on non-existent array elements,
  and Tablelist makes a lot of invocations of this command.</p>

  <p>If for some reason you cannot upgrade your Tcl/Tk version, then you should
  execute the Tcl script <code>repair.tcl</code> in the directory
  <code>scripts</code>.&nbsp; This script makes backup copies of several files
  contained in this directory, and then creates new versions of them by
  replacing all invocations of&nbsp; <code>info exists</code>&nbsp; for array
  elements with a call to the helper procedure
  <code>arrElemExists</code>.&nbsp; The patched files work with all Tcl/Tk
  releases starting with 8.0, but the original ones have a much better
  performance.</p>

  <p>Notice that in tklib the Tablelist <code>demos</code> directory is
  replaced with the subdirectory <code>tablelist</code> of the
  <code>examples</code> directory.&nbsp; Please take this into account when
  reading the <a href="#examples">examples</a> below.</p>

  <h3 id="ov_use">How to Use It?</h3>

  <p>The Tablelist distribution provides two packages, called <b>Tablelist</b>
  and <b>Tablelist_tile</b>.&nbsp; The main difference between the two is that
  Tablelist_tile enables the tile-based, theme-specific appearance of tablelist
  widgets; this package requires Tcl/Tk 8.4 or higher and tile 0.6 or
  higher.&nbsp; It is not possible to use both packages in one and the same
  application, because both are implemented in the same <code>tablelist</code>
  namespace and provide identical commands.</p>

  <p>To be able to access the commands and variables defined in the package
  Tablelist, your scripts must contain one of the lines</p>

  <blockquote>
    <pre>
package require tablelist ?<i>version</i>?
package require Tablelist ?<i>version</i>?
</pre>
  </blockquote>

  <p>You can use either one of the two statements above because the file
  <code>tablelist.tcl</code> contains both lines</p>

  <blockquote>
    <pre>
package provide tablelist ...
package provide Tablelist ...
</pre>
  </blockquote>

  <p>Likewise, to be able to access the commands and variables defined in the
  package Tablelist_tile, your scripts must contain one of the lines</p>

  <blockquote>
    <pre>
package require tablelist_tile ?<i>version</i>?
package require Tablelist_tile ?<i>version</i>?
</pre>
  </blockquote>

  <p>Again, you can use either one of the two statements above because the file
  <code>tablelist_tile.tcl</code> contains both lines</p>

  <blockquote>
    <pre>
package provide tablelist_tile ...
package provide Tablelist_tile ...
</pre>
  </blockquote>

  <p>You are free to remove one of the above lines from
  <code>tablelist.tcl</code> and <code>tablelist_tile.tcl</code>, respectively,
  if you want to prevent the corresponding packages from making themselves
  known under two different names each.&nbsp; Of course, by doing so you
  restrict the argument of&nbsp; <code>package require</code>&nbsp; to a single
  name per package.</p>

  <p>Please note that <b>ActiveTcl versions 8.5 and later use a modified
  package mechanism, which only exports the all-lowercase names
  <code>tablelist</code> and <code>tablelist_tile</code></b>.</p>

  <p><b>REMARK:</b>&nbsp; If you have an earlier Tablelist version as part of
  ActiveTcl 8.5 or above and the new Tablelist release 6.0, then it is highly
  recommended to specify the version number <code>6.0</code> in the&nbsp;
  <code>package require</code>&nbsp; command, because otherwise the interpreter
  will load the old Tablelist version included in ActiveTcl as Tcl
  Module.&nbsp; The <a href="#examples">examples</a> below use the
  statement&nbsp; <code>package require tablelist 6.0</code>,&nbsp; and their
  tile-based counterparts invoke the command&nbsp; <code>package require
  tablelist_tile 6.0</code>.</p>

  <p>Since the packages Tablelist and Tablelist_tile are implemented in the
  <code>tablelist</code> namespace, you must either invoke the</p>

  <blockquote>
    <pre>
namespace import tablelist::<i>pattern</i> ?tablelist::<i>pattern ...</i>?
</pre>
  </blockquote>

  <p>command to import the <i>procedures</i> you need, or use qualified names
  like <code>tablelist::tablelist</code>.&nbsp; In the examples below we have
  chosen the latter approach.</p>

  <p>To access Tablelist <i>variables</i>, you <i>must</i> use qualified
  names.&nbsp; There are only 5 Tablelist variables (and one more when using
  Tablelist_tile) that are designed to be accessed outside the namespace
  <code>tablelist</code>:</p>

  <ul>
    <li>The variable <code>tablelist::version</code> holds the current version
    number of the Tablelist and Tablelist_tile packages.</li>

    <li>The variable <code>tablelist::library</code> holds the location of the
    Tablelist installation directory.</li>

    <li>The variable <code>tablelist::scalingpct</code> holds the scaling
    percentage used by Tablelist when adapting the sizes of the tree styles
    <code>vistaAero</code>, <code>vistaClassic</code>, <code>win7Aero</code>,
    <code>win7Classic</code>, and <code>win10</code> to the display's DPI
    scaling level.&nbsp; The currently supported values are <code>100</code>,
    <code>125</code>, <code>150</code>, and <code>200</code>.&nbsp; You can use
    the value of this variable, e.g., if you want to create images of different
    sizes, depending on the DPI scaling factor.&nbsp; For example, if your
    application uses images of size 16 x 16 on an unscaled display and
    <code>tablelist::scalingpct</code> has the value <code>150</code>, then the
    image size for this display should be 24 x 24.</li>

    <li>The boolean variable <code>tablelist::strictTk</code> (having the
    default value <code>0</code>) controls the strict listbox-compatibility of
    the default bindings.</li>

    <li>The read-only boolean variable <code>tablelist::usingTile</code> has
    the value <code>0</code> in the package Tablelist and the value
    <code>1</code> in Tablelist_tile.</li>

    <li>In Tablelist_tile the array <code>tablelist::themeDefaults</code> holds
    the theme-specific default values of a series of Tablelist configuration
    options.</li>
  </ul>

  <h3 id="ov_tile">More on Tablelist_tile</h3>

  <p>A tablelist widget consists of a body (containing the items) and a header
  (displaying the column titles and optional header items).&nbsp; Both
  components are contained in a hull, implemented as a frame.&nbsp; The header
  has a rather complex structure, consisting, among others, of frame and label
  widgets.&nbsp; While in the Tablelist package all of these components are Tk
  widgets, the Tablelist_tile package uses both Tk and tile frame and label
  widgets.&nbsp; Due to several incompatibilities between Tk and tile, it is
  currently not possible to replace all Tk widgets making up a tablelist with
  their tile counterparts.</p>

  <p>From the above it follows that <b>the package Tablelist_tile will only
  work as expected if the Tk <code>frame</code> and <code>label</code> commands
  haven't been overridden by using&nbsp; <code>namespace import -force
  ttk::*</code>&nbsp; at global scope</b>.&nbsp; While earlier tile releases
  suggested using this command at global scope for the really adventurous, in
  newer tile versions this is considered a Really Bad Idea, causing many things
  to break.&nbsp; Instead, <b>you should explicitly invoke
  <code>ttk::frame</code>, <code>ttk::label</code>, etc. whenever you want to
  use a tile widget</b>.</p>

  <p><b>Overriding some other Tk widgets at global scope may be equally
  dangerous when using various widgets from the Tk core and from the packages
  BWidget, Iwidgets, combobox (by Bryan Oakley), ctext, and Mentry for
  interactive cell editing</b>, because these packages expect Tk widgets, which
  may not always be replaced by their tile counterparts.</p>

  <p>Another restriction to be taken into account is due to the fact that in
  earlier tile versions the&nbsp; <code>(ttk::)style theme use</code>&nbsp;
  command could only be used to set the current theme, but not to retrieve
  it.&nbsp; For this reason, the package Tablelist_tile makes use of the
  variable <code>ttk::currentTheme</code> or <code>tile::currentTheme</code>
  (depending on the tile version), which is set by the
  <code>ttk::setTheme</code> or <code>tile::setTheme</code> procedure.&nbsp;
  From this it follows that <b>the tile-based tablelist widgets will only have
  the expected appearance if the platform-specific default theme is either left
  unchanged or replaced with another theme by invoking the procedure
  <code>ttk::setTheme</code> or <code>tile::setTheme</code>, depending on the
  current tile version</b>.&nbsp; (See also the <code><a href=
  "tablelistThemes.html#setTheme">tablelist::setTheme</a></code> command.)</p>

  <p>After these cautions concerning the use of tile, the rest of this section
  describes the differences between the packages Tablelist and
  Tablelist_tile.</p>

  <p>The Tablelist_tile package checks whether the required Tcl, Tk, and tile
  versions are present, by executing the commands</p>

  <blockquote>
    <pre>
package require Tcl 8.4
package require Tk  8.4
if {$::tk_version &lt; 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
    package require tile 0.6
}
</pre>
  </blockquote>

  <p>The last command above reflects the fact that, beginning with Tk 8.5a6,
  tile is integrated into the Tk core and therefore it should only be loaded
  explicitly when using an earlier Tk version.</p>

  <p>Apart from this and the <code>_tile</code> suffix in the&nbsp;
  <code>package require</code>&nbsp; command, the only difference (from the
  programmer's point of view) between the packages Tablelist and Tablelist_tile
  is related to the supported configuration options:&nbsp; The
  <code>-highlightbackground</code>, <code>-highlightcolor</code>,
  <code>-highlightthickness</code>, <code>-labelbackground</code>,
  <code>-labelactivebackground</code>, <code>-labelactiveforeground</code>,
  <code>-labeldisabledforeground</code>, and <code>-labelheight</code> options
  (the latter at both widget and column levels), present in the Tablelist
  package, are not supported by Tablelist_tile.&nbsp; The first three are
  standard Tk widget options that are not available for tile widgets.&nbsp; The
  <code>-labelbackground</code> option stands for the <code>-background</code>
  option of the column labels, and current versions of the tile engine don't
  support setting the background color for these widgets with a special header
  layout.&nbsp; The remaining options stand for the
  <code>-activebackground</code>, <code>-activeforeground</code>,
  <code>-disabledforeground</code>, and <code>-height</code> options of the
  column labels, and these configuration options are not supported for tile
  label widgets.</p>

  <p>Also, take into account that in some themes, setting the
  <code>-labelborderwidth</code> option (at widget or column level) to a value
  other than the default might be ignored by tile and thus could cause
  alignment problems.&nbsp; This is because the border of tile widgets is drawn
  with theme-specific methods, which will not always produce the results known
  from Tk widgets.</p>

  <p>Finally, notice that, when using the <code>tileqt</code> theme, the
  version number of the <code>tile::theme::tileqt</code> package must be 0.4 or
  higher, and <code>tileqt</code> itself won't work with tile versions earlier
  than 0.7.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="examples">Examples</h2>

  <h3 id="ex_config">A tablelist Widget for Displaying and Editing
  Configuration Options</h3>

  <p>The file <code>config.tcl</code> in the <code>demos</code> directory
  contains a procedure <code>demo::displayConfig</code> that displays the
  configuration options of an arbitrary widget in a tablelist contained in a
  newly created top-level widget and allows you to edit these options.&nbsp;
  This procedure can prove to be quite useful during interactive GUI
  development.&nbsp; To test it, start <code>wish</code> and evaluate the file
  by using the <code>source</code> command as follows:</p>

  <ul>
    <li>
      If <code>wish</code> was started in the <code>demos</code> directory then
      it is sufficient to enter

      <blockquote>
        <pre>
source config.tcl
</pre>
      </blockquote>
    </li>

    <li>
      If <code>wish</code> was started in some other directory then you can use
      the <code>tablelist::library</code> variable to find the location of the
      file.&nbsp; For example, assuming that your Tablelist installation has
      the directory structure described in the <a href="#ov_install">How to
      install it?</a> section, the required commands are:

      <blockquote>
        <pre>
package require tablelist 6.0
source [file join $tablelist::library demos config.tcl]
</pre>
      </blockquote>
    </li>
  </ul>

  <p>In both cases, the script will print the following message to
  <code>stdout</code>:</p>

  <blockquote>
    <pre>
To display the configuration options of an arbitrary widget, enter

        demo::displayConfig &lt;widgetName&gt;
</pre>
  </blockquote>

  <p><code>&lt;widgetName&gt;</code> can be the path name of any already
  existing widget.&nbsp; For example, if you enter</p>

  <blockquote>
    <pre>
demo::displayConfig .
</pre>
  </blockquote>

  <p>then you will see that a tablelist widget <code>.configTop.tf.tbl</code>
  in a new toplevel window is created and its name is printed to
  <code>stdout</code>.&nbsp; If you then enter</p>

  <blockquote>
    <pre>
demo::displayConfig .configTop.tf.tbl
</pre>
  </blockquote>

  <p>then another toplevel window containing the tablelist widget
  <code>.configTop2.tf.tbl</code> will pop up.&nbsp; The latter looks like in
  the following figure:</p>

  <blockquote>
    <img src="config.png" alt="Configuration Options" width="835" height="381">
  </blockquote>

  <p>It is assumed that the Tcl command associated with the widget specified by
  <code>&lt;widgetName&gt;</code> has a <code>configure</code> subcommand
  which, when invoked without any argument, returns a list describing all of
  the available configuration options for the widget, in the common format
  known from the standard Tk widgets.&nbsp; The
  <code>demo::displayConfig</code> procedure inserts the items of this list
  into a scrolled tablelist with 5 dynamic-width columns and interactive sort
  capability, and returns the name of the newly created tablelist widget:</p>

  <blockquote>
    <pre>
package require tablelist 6.0

namespace eval demo {
    #
    # Get the current windowing system ("x11", "win32", "classic", or "aqua")
    # and add some entries to the Tk option database for the following
    # widget hierarchy within a top-level widget of the class DemoTop:
    #
    # Name              Class
    # -----------------------------
    # tf                Frame
    #   tbl               Tabellist
    #   vsb, hsb          Scrollbar
    # bf                Frame
    #   b1, b2, b3        Button
    #
    variable winSys
    if {[catch {tk windowingsystem} winSys] != 0} {
        switch $::tcl_platform(platform) {
            unix        { set winSys x11 }
            windows     { set winSys win32 }
            macintosh   { set winSys classic }
        }
    }
    if {[string compare $winSys "x11"] == 0} {
        #
        # Create the font TkDefaultFont if not yet present
        #
        catch {font create TkDefaultFont -family Helvetica -size -12}

        option add *DemoTop*Font                        TkDefaultFont
        option add *DemoTop*selectBackground            #5294e2
        option add *DemoTop*selectForeground            white
    }
    option add *DemoTop.tf.borderWidth                  1
    option add *DemoTop.tf.relief                       sunken
    option add *DemoTop.tf.tbl.borderWidth              0
    option add *DemoTop.tf.tbl.highlightThickness       0
    option add *DemoTop.tf.tbl.background               white
    option add *DemoTop.tf.tbl.stripeBackground         #f0f0f0
    option add *DemoTop.tf.tbl.setGrid                  yes
    option add *DemoTop.tf.tbl*Entry.background         white
    option add *DemoTop.bf.Button.width                 10
}

#------------------------------------------------------------------------------
# demo::displayConfig
#
# Displays the configuration options of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayConfig w {
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\""
        return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .configTop
    for {set n 2} {[winfo exists $top]} {incr n} {
        set top .configTop$n
    }
    toplevel $top -class DemoTop
    wm title $top "Configuration Options of the [winfo class $w] Widget \"$w\""

    #
    # Create a scrolled tablelist widget with 5 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
        -columns {0 "Command-Line Name"
                  0 "Database/Alias Name"
                  0 "Database Class"
                  0 "Default Value"
                  0 "Current Value"} \
        -labelcommand tablelist::sortByColumn -sortcommand demo::compareAsSet \
        -editendcommand demo::applyValue -height 15 -width 100 -stretch all \
        -xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set]
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }
    $tbl columnconfigure 3 -maxwidth 30
    $tbl columnconfigure 4 -maxwidth 30 -editable yes
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"     -command [list demo::putConfig $w $tbl]
    button $b2 -text "Sort as Set" -command [list $tbl sort]
    button $b3 -text "Close"       -command [list destroy $top]

    #
    # Manage the widgets
    #
    grid $tbl -row 0 -rowspan 2 -column 0 -sticky news
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
        grid [$tbl cornerpath] -row 0 -column 1 -sticky ew
        grid $vsb              -row 1 -column 1 -sticky ns
    } else {
        grid $vsb -row 0 -rowspan 2 -column 1 -sticky ns
    }
    grid $hsb -row 2 -column 0 -sticky ew
    grid rowconfigure    $tf 1 -weight 1
    grid columnconfigure $tf 0 -weight 1
    pack $b1 $b2 $b3 -side left -expand yes -pady 10
    pack $bf -side bottom -fill x
    pack $tf -side top -expand yes -fill both

    #
    # Populate the tablelist with the configuration options of the given widget
    #
    putConfig $w $tbl
    return $tbl
}
</pre>
  </blockquote>

  <p>The procedure invokes the <code><a href=
  "tablelistWidget.html">tablelist::tablelist</a></code> command to create a
  tablelist widget.&nbsp; The value of the <code><a href=
  "tablelistWidget.html#columns">-columns</a></code> option passed to this
  command specifies the widths, titles, and alignments of the 5 columns.&nbsp;
  The width of each column is given as <code>0</code>, specifying that the
  column's width is to be made just large enough to hold all the elements in
  the column, including its title, which is the string following the
  width.&nbsp; We have omitted the alignment specifications (which can
  optionally follow the titles), because the columns shall all be
  left-justified.</p>

  <p>Since all columns are of dynamic width and left-aligned, instead of
  <code>-columns</code> we could have used the <code><a href=
  "tablelistWidget.html#columntitles">-columntitles</a></code> option as
  follows:</p>

  <blockquote>
    <pre>
    tablelist::tablelist $tbl \
        -columntitles {"Command-Line Name"
                       "Database/Alias Name"
                       "Database Class"
                       "Default Value"
                       "Current Value"} \
        . . .
</pre>
  </blockquote>

  <p>The command <code><a href=
  "tablelistColSort.html#sortByColumn">tablelist::sortByColumn</a></code>,
  specified as the value of the <code><a href=
  "tablelistWidget.html#labelcommand">-labelcommand</a></code> option, will be
  invoked whenever mouse button 1 is released over one of the labels.&nbsp;
  This command sorts the items based on the column corresponding to that label,
  in the right order, by invoking the <code><a href=
  "tablelistWidget.html#sortbycolumn">sortbycolumn</a></code> subcommand of the
  Tcl command associated with the tablelist widget.</p>

  <p>As seen from the creation of the button displaying the text&nbsp;
  <code>"Sort as Set"</code>,&nbsp; the items will also be sorted by invoking
  the <code><a href="tablelistWidget.html#sort">sort</a></code>
  subcommand.&nbsp; This makes it necessary to specify a command to be used for
  the comparison of the items, as the value of the <code><a href=
  "tablelistWidget.html#sortcommand">-sortcommand</a></code> option.&nbsp; In
  our example this is the <code>demo::compareAsSet</code> procedure shown
  below.</p>

  <p>The <code><a href=
  "tablelistWidget.html#editendcommand">-editendcommand</a></code> option
  specifies the command to be invoked automatically whenever the interactive
  editing of a cell's content is finished and the final content of the
  temporary embedded entry widget used for the editing are different from its
  original one.&nbsp; Per default, the elements of a tablelist widget can only
  be edited programmatically, but we enable the interactive editing for the
  cells of the last column with the aid of the <code><a href=
  "tablelistWidget.html#col_editable">-editable</a></code> column configuration
  option.</p>

  <p>By specifying the value <code>all</code> for the <code><a href=
  "tablelistWidget.html#stretch">-stretch</a></code> configuration option we
  make sure that all of the columns will be stretched to eliminate the blank
  space that might appear at the right of the table.</p>

  <p>If the default value of the <code>-selectborderwidth</code> option is
  <code>0</code> (this is the case on the Windows and Macintosh platforms, and
  also in an X11 envronment with Tk 8.5 or above) then we use the
  <code><a href="tablelistWidget.html#spacing">-spacing</a></code> option to
  provide some additional space above and below the rows.</p>

  <p>For the last two columns of the tablelist we use the <code><a href=
  "tablelistWidget.html#col_maxwidth">-maxwidth</a></code> column configuration
  option, to make sure that the dynamic widths of these columns won't exceed 30
  average-width characters.</p>

  <p>Besides the options given on the command line, our tablelist widget will
  automatically inherit the ones contained in the Tk option database entries
  specified in the namespace initialization preceding the
  <code>demo::displayConfig</code> procedure.&nbsp; The database name
  <code>stripeBackground</code> corresponds to the <code><a href=
  "tablelistWidget.html#stripebackground">-stripebackground</a></code>
  configuration option.&nbsp; According to this entry, every other row of the
  tablelist widget will be displayed in the background color
  <code>#f0f0f0</code>, which improves the readability of the items and gives
  the widget a nice appearance.</p>

  <p>The option database entries given for the windowing systems other than
  <code>x11</code> are implicitly used when managing the tablelist widget and
  the two scrollbars with the aid of <code>grid</code>.&nbsp; Notice how the
  <code><a href="tablelistWidget.html#cornerpath">cornerpath</a></code>
  subcommand enables us to achieve a native look &amp; feel with respect to the
  vertical scrollbar on the windowing system <code>aqua</code>.</p>

  <p>We populate the tablelist by invoking the <code>demo::putConfig</code>
  procedure discussed below.&nbsp; The same script is associated with the
  <b>Refresh</b> button, as the value of its <code>-command</code>
  configuration option.&nbsp; This procedure is implemented as follows:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::putConfig
#
# Outputs the configuration options of the widget w into the tablelist widget
# tbl.
#------------------------------------------------------------------------------
proc demo::putConfig {w tbl} {
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
        return ""
    }

    #
    # Display the configuration options of w in the tablelist widget tbl
    #
    $tbl delete 0 end
    foreach configSet [$w configure] {
        #
        # Insert the list configSet into the tablelist widget
        #
        $tbl insert end $configSet

        if {[llength $configSet] == 2} {
            $tbl rowconfigure end -foreground gray50 -selectforeground gray75
            $tbl cellconfigure end -editable no
        } else {
            #
            # Change the colors of the first and last cell of the row
            # if the current value is different from the default one
            #
            set default [lindex $configSet 3]
            set current [lindex $configSet 4]
            if {[string compare $default $current] != 0} {
                foreach col {0 4} {
                    $tbl cellconfigure end,$col \
                         -foreground red -selectforeground yellow
                }
            }
        }
    }

    $tbl sortbycolumn 0
    $tbl activate 0
    $tbl attrib widget $w
}
</pre>
  </blockquote>

  <p>After deleting the current items of the tablelist widget <code>tbl</code>,
  the procedure inserts the items of the list returned by the
  <code>configure</code> subcommand of the Tcl command associated with the
  widget <code>w</code>.&nbsp; For each option that is merely an abbreviated
  form of some other one, we use the <code><a href=
  "tablelistWidget.html#rowconfigure">rowconfigure</a></code> tablelist
  subcommand to change the normal and selection foreground colors of the item
  just appended, and we disable the interactive editing in the last inserted
  cell by using the <code><a href=
  "tablelistWidget.html#cell_editable">-editable</a></code> cell configuration
  option.&nbsp; The <code><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></code> tablelist
  operation is also invoked for each real option whose current value is
  different from the default one, to change the values of the
  <code>-foreground</code> and <code>-selectforeground</code> options of the
  cells no. 0 and 4, containing the command-line name of the option and its
  current value.</p>

  <p>Each tablelist widget may have any number of private <b>attributes</b>,
  which can be set and retrieved with the aid of the <code><a href=
  "tablelistWidget.html#attrib">attrib</a></code> subcommand of the Tcl command
  corresponding to the widget.&nbsp; The <code>demo::putConfig</code> procedure
  sets the <code>widget</code> attribute to the name of the widget whose
  options are displayed in the tablelist.</p>

  <p>The implementation of the comparison command
  <code>demo::compareAsSet</code> mentioned above is quite simple:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::compareAsSet
#
# Compares two items of a tablelist widget used to display the configuration
# options of an arbitrary widget.  The item in which the current value is
# different from the default one is considered to be less than the other; if
# both items fulfil this condition or its negation then string comparison is
# applied to the two option names.
#------------------------------------------------------------------------------
proc demo::compareAsSet {item1 item2} {
    foreach {opt1 dbName1 dbClass1 default1 current1} $item1 \
            {opt2 dbName2 dbClass2 default2 current2} $item2 {
        set changed1 [expr {[string compare $default1 $current1] != 0}]
        set changed2 [expr {[string compare $default2 $current2] != 0}]
        if {$changed1 == $changed2} {
            return [string compare $opt1 $opt2]
        } elseif {$changed1} {
            return -1
        } else {
            return 1
        }
    }
}
</pre>
  </blockquote>

  <p>Finally, here is the implementation of the <code>demo::applyValue</code>
  procedure, specified as the value of the <code>-editendcommand</code>
  option:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::applyValue
#
# Applies the new value of the configuraton option contained in the given row
# of the tablelist widget tbl to the widget whose options are displayed in it,
# and updates the colors of the first and last cell of the row.
#------------------------------------------------------------------------------
proc demo::applyValue {tbl row col text} {
    #
    # Try to apply the new value of the option contained in
    # the given row to the widget whose options are displayed
    # in the tablelist; reject the value if the attempt fails
    #
    set w [$tbl attrib widget]
    set opt [$tbl cellcget $row,0 -text]
    if {[catch {$w configure $opt $text} result] != 0} {
        bell
        tk_messageBox -title "Error" -icon error -message $result \
            -parent [winfo toplevel $tbl]
        $tbl rejectinput
        return ""
    }

    #
    # Replace the new option value with its canonical form and
    # update the colors of the first and last cell of the row
    #
    set text [$w cget $opt]
    set default [$tbl cellcget $row,3 -text]
    if {[string compare $default $text] == 0} {
        foreach col {0 4} {
            $tbl cellconfigure $row,$col \
                 -foreground "" -selectforeground ""
        }
    } else {
        foreach col {0 4} {
            $tbl cellconfigure $row,$col \
                 -foreground red -selectforeground yellow
        }
    }

    return $text
}
</pre>
  </blockquote>

  <p>The procedure retrieves the name of the widget whose options are displayed
  in the tablelist, as the value of its <code>widget</code> attribute, and
  invokes the <code><a href="tablelistWidget.html#cellcget">cellcget</a></code>
  tablelist subcommand to get the name of the option specified in the first
  cell of the row whose last element was just edited.&nbsp; Next, it tries to
  apply the new value of the option to the widget, and invokes the
  <code><a href="tablelistWidget.html#rejectinput">rejectinput</a></code>
  subcommand if the attempt fails.&nbsp; Otherwise it replaces the new option
  value with its canonical form and updates the normal and selection foreground
  colors of the cells no. 0 and 4.&nbsp; The canonical form of the option value
  is given by the <code>cget</code> subcommand of the Tcl command associated
  with that widget.&nbsp; For example, a boolean value will always be replaced
  with <code>1</code> or <code>0</code>, even if the entry contains the string
  <code>yes</code> or <code>no</code>.&nbsp; The procedure returns this
  canonical option value, thus making sure that the latter will become the new
  content of the cell that was just edited.</p>

  <h3 id="ex_browse">Two Widget Browsers Based on a tablelist</h3>

  <p>The files <code>browse.tcl</code> and <code>browseTree.tcl</code> in the
  <code>demos</code> directory contain a procedure
  <code>demo::displayChildren</code> that displays information about the
  children of an arbitrary widget in a tablelist contained in a newly created
  top-level widget.&nbsp; To test it, start <code>wish</code> and evaluate the
  chosen file by using the <code>source</code> command, in a similar way as in
  the case of the <a href="#ex_config">previous example</a>.</p>

  <p>Both scripts will print the following message to <code>stdout</code>:</p>

  <blockquote>
    <pre>
To display information about the children of an arbitrary widget, enter

        demo::displayChildren &lt;widgetName&gt;
</pre>
  </blockquote>

  <p><code>&lt;widgetName&gt;</code> can be the path name of any already
  existing widget.&nbsp; For example, if you enter</p>

  <blockquote>
    <pre>
demo::displayChildren .
</pre>
  </blockquote>

  <p>then you will see that a tablelist widget <code>.browseTop.tf.tbl</code>
  in a new toplevel window is created and its name is printed to
  <code>stdout</code>.</p>

  <p>The tablelist created by the procedure <code>demo::displayChildren</code>
  in the file <code>browse.tcl</code> is a multi-column listbox:</p>

  <blockquote>
    <img src="browse.png" alt="Widget Browser" width="605" height="283">
  </blockquote>

  <p>The tablelist created by the procedure of the same name in the file
  <code>browseTree.tcl</code> is a multi-column tree widget:</p>

  <blockquote>
    <img src="browseTree.png" alt="Widget Browser" width="623" height="283">
  </blockquote>

  <p>The <code>demo::displayChildren</code> command inserts some data of the
  children of the widget specified by <code>&lt;widgetName&gt;</code> into a
  vertically scrolled tablelist with 9 dynamic-width columns and interactive
  sort capability, and returns the name of the newly created tablelist
  widget.&nbsp; By double-clicking an item (e.g., the one containing the path
  name <code>.browseTop</code> in <code>browse.tcl</code> and the name
  <code>browseTop</code> in <code>browseTree.tcl</code>) or invoking the first
  entry of a pop-up menu within the body of the tablelist, you can display the
  data of the children of the widget corresponding to the selected item, and
  with the second menu entry you can display its configuration options (see the
  <a href="#ex_config">previous example</a> for details).&nbsp; To go one level
  up, click on the <b>Parent</b> button.</p>

  <p>There is a lot of code common to the scripts <code>browse.tcl</code> and
  <code>browseTree.tcl</code>.&nbsp; We will restrict the description below to
  the second one, which requires Tk 8.3 or later, due to the use of several
  tree-related tablelist options and subcommands.</p>

  <blockquote>
    <pre>
package require Tk 8.3
package require tablelist 6.0

namespace eval demo {
    variable dir [file dirname [info script]]

    #
    # Create two images, needed in the procedure putChildren
    #
    variable leafImg [image create bitmap -file [file join $dir leaf.xbm] \
                      -background coral -foreground gray50]
    variable compImg [image create bitmap -file [file join $dir comp.xbm] \
                      -background yellow -foreground gray50]
}

source [file join $demo::dir config.tcl]

#------------------------------------------------------------------------------
# demo::displayChildren
#
# Displays information on the children of the widget w in a tablelist widget
# contained in a newly created top-level widget.  Returns the name of the
# tablelist widget.
#------------------------------------------------------------------------------
proc demo::displayChildren w {
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\""
        return ""
    }

    #
    # Create a top-level widget of the class DemoTop
    #
    set top .browseTop
    for {set n 2} {[winfo exists $top]} {incr n} {
        set top .browseTop$n
    }
    toplevel $top -class DemoTop

    #
    # Create a vertically scrolled tablelist widget with 9 dynamic-width
    # columns and interactive sort capability within the top-level
    #
    set tf $top.tf
    frame $tf
    set tbl $tf.tbl
    set vsb $tf.vsb
    tablelist::tablelist $tbl \
        -columns {0 "Name"      left
                  0 "Class"     left
                  0 "X"         right
                  0 "Y"         right
                  0 "Width"     right
                  0 "Height"    right
                  0 "Mapped"    center
                  0 "Viewable"  center
                  0 "Manager"   left} \
        -expandcommand demo::expandCmd -labelcommand demo::labelCmd \
        -yscrollcommand [list $vsb set] -setgrid no -width 0
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }
    foreach col {2 3 4 5} {
        $tbl columnconfigure $col -sortmode integer
    }
    foreach col {6 7} {
        $tbl columnconfigure $col -formatcommand demo::formatBoolean
    }
    scrollbar $vsb -orient vertical -command [list $tbl yview]

    #
    # When displaying the information about the children of any
    # ancestor of the label widgets, the widths of some of the
    # labels and thus also the widths and x coordinates of some
    # children may change.  For this reason, make sure the items
    # will be updated after any change in the sizes of the labels
    #
    foreach l [$tbl labels] {
        bind $l &lt;Configure&gt; [list demo::updateItemsDelayed $tbl]
    }
    bind $tbl &lt;Configure&gt; [list demo::updateItemsDelayed $tbl]

    #
    # Create a pop-up menu with two command entries; bind the script
    # associated with its first entry to the &lt;Double-1&gt; event, too
    #
    set menu $top.menu
    menu $menu -tearoff no
    $menu add command -label "Display Children" \
                      -command [list demo::putChildrenOfSelWidget $tbl]
    $menu add command -label "Display Config" \
                      -command [list demo::dispConfigOfSelWidget $tbl]
    set bodyTag [$tbl bodytag]
    bind $bodyTag &lt;Double-1&gt;   [list demo::putChildrenOfSelWidget $tbl]
    bind $bodyTag &lt;&lt;Button3&gt;&gt;  [bind TablelistBody &lt;Button-1&gt;]
    bind $bodyTag &lt;&lt;Button3&gt;&gt; +[bind TablelistBody &lt;ButtonRelease-1&gt;]
    bind $bodyTag &lt;&lt;Button3&gt;&gt; +[list demo::postPopupMenu $top %X %Y]

    #
    # Create three buttons within a frame child of the top-level widget
    #
    set bf $top.bf
    frame $bf
    set b1 $bf.b1
    set b2 $bf.b2
    set b3 $bf.b3
    button $b1 -text "Refresh"
    button $b2 -text "Parent"
    button $b3 -text "Close" -command [list destroy $top]

    #
    # Manage the widgets
    #
    . . .

    #
    # Populate the tablelist with the data of the given widget's children
    #
    putChildren $w $tbl root
    return $tbl
}
</pre>
  </blockquote>

  <p>The procedure invokes the <code><a href=
  "tablelistWidget.html">tablelist::tablelist</a></code> command to create a
  tablelist widget.&nbsp; The value of the <code><a href=
  "tablelistWidget.html#columns">-columns</a></code> option passed to this
  command specifies the widths, titles, and alignments of the 9 columns.&nbsp;
  The width of each column is given as <code>0</code>, specifying that the
  column's width is to be made just large enough to hold all the elements in
  the column, including its title, which is the string following the
  width.&nbsp; Each of the titles is followed by an alignment, which indicates
  how to justify both the elements and the title of the respective column.</p>

  <p>We want to display not only the data of the given widget's children, but
  also those of its further descendants.&nbsp; To this end, we need a command
  to be invoked whenever an item corresponding to a widget with children gets
  expanded.&nbsp; This command is specified as the value of the <code><a href=
  "tablelistWidget.html#expandcommand">-expandcommand</a></code> option.&nbsp;
  As discussed later, the <code>demo::expandCmd</code> procedure will insert
  the children of the row that is about to be expanded, if it has no children
  yet.</p>

  <p>The command <code>demo::labelCmd</code>, specified as the value of the
  <code><a href="tablelistWidget.html#labelcommand">-labelcommand</a></code>
  option, will be invoked whenever mouse button 1 is released over one of the
  labels.&nbsp; We will discuss this procedure later.</p>

  <p>We specify the value <code>0</code> for the widget's <code><a href=
  "tablelistWidget.html#width">-width</a></code> option, meaning that the
  tablelist's width shall be made just large enough to hold all its
  columns.</p>

  <p>After creating the tablelist widget, we make sure that the elements of its
  columns 2, 3, 4, and 5 (displaying the x and y coordinates as well as the
  widths and heights of the children) will be compared as integers when sorting
  the items based on one of these columns.&nbsp; We do this with the aid of the
  <code><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></code> tablelist
  operation.</p>

  <p>The same <code>columnconfigure</code> subcommand enables us to specify
  that, when displaying the elements of columns 6 and 7 (having the titles
  <code>"Mapped"</code> and <code>"Viewable"</code>, respectively), the boolean
  values <code>1</code> and <code>0</code> will be replaced with the strings
  <code>"yes"</code> and <code>"no"</code>, returned by the
  <code>demo::formatBoolean</code> command shown below.</p>

  <p>After creating the vertical scrollbar, we iterate over the elements of the
  list containing the path names of all header labels of the tablelist widget,
  returned by the <code><a href="tablelistWidget.html#labels">labels</a></code>
  subcommand of the Tcl command corresponding to the widget.&nbsp; For each
  element of the list, we bind the procedure
  <code>demo::updateItemsDelayed</code> to the <code>&lt;Configure&gt;</code>
  event.&nbsp; In this way we make sure the procedure will be invoked whenever
  the header label indicated by that list element changes size.</p>

  <p>The four invocations of the <code>bind</code> command following the
  creation of the pop-up menu make use of a binding tag whose name depends on
  the path name of the tablelist widget and is returned by the <code><a href=
  "tablelistWidget.html#bodytag">bodytag</a></code> subcommand of the Tcl
  command associated with the tablelist widget.&nbsp; The advantage of using
  this tag instead of the path name of the tablelist's body is that this
  binding tag is associated not only with the body but also with the separator
  frames and with the labels displaying embedded images.&nbsp; This is
  important in our example because we want to make sure the
  <code>&lt;&lt;Button3&gt;&gt;</code> and <code>&lt;Double-1&gt;</code> events
  will be handled in the same way within a label containing an embedded image
  as in the rest of the tablelist's body.&nbsp; Both the <code><a href=
  "tablelistWidget.html#button3">&lt;&lt;Button3&gt;&gt;</a></code> virtual
  event (used in the first three <code>bind</code> commands) and the
  <code><a href="tablelistWidget.html#body_bindings">TablelistBody</a></code>
  binding tag (used in the first binding script) are created by the Tablelist
  package.&nbsp; The first three <code>bind</code> commands make sure that a
  <code>&lt;&lt;Button3&gt;&gt;</code> virtual event will select and activate
  the nearest item and will post a pop-up menu with two command entries that
  refer to the widget described by that item.</p>

  <p>We populate the tablelist by invoking the <code>demo::putChildren</code>
  procedure, implemented as follows:</p>

  <blockquote id="putChildren">
    <pre>
#------------------------------------------------------------------------------
# demo::putChildren
#
# Outputs the data of the children of the widget w into the tablelist widget
# tbl, as child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc demo::putChildren {w tbl nodeIdx} {
    . . .

    if {[string compare $nodeIdx "root"] == 0} {
        set top [winfo toplevel $tbl]
        wm title $top "Children of the [winfo class $w] Widget \"$w\""

        $tbl resetsortinfo
        $tbl delete 0 end
        set row 0
    } else {
        set row [expr {$nodeIdx + 1}]
    }

    #
    # Display the data of the children of the
    # widget w in the tablelist widget tbl
    #
    variable leafImg
    variable compImg
    foreach c [winfo children $w] {
        #
        # Insert the data of the current child into the tablelist widget
        #
        set item {}
        lappend item \
                [winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
                [winfo width $c] [winfo height $c] [winfo ismapped $c] \
                [winfo viewable $c] [winfo manager $c]
        $tbl insertchild $nodeIdx end $item

        #
        # Insert an image into the first cell of the row; mark the
        # row as collapsed if the child widget has children itself
        #
        if {[llength [winfo children $c]] == 0} {
            $tbl cellconfigure end,0 -image $leafImg
        } else {
            $tbl cellconfigure end,0 -image $compImg
            $tbl collapse $row
        }

        $tbl rowattrib $row pathName $c
        incr row
    }

    if {[string compare $nodeIdx "root"] == 0} {
        #
        # Configure the "Refresh" and "Parent" buttons
        #
        $top.bf.b1 configure -command [list demo::refreshView $w $tbl]
        set b2 $top.bf.b2
        set p [winfo parent $w]
        if {[string compare $p ""] == 0} {
            $b2 configure -state disabled
        } else {
            $b2 configure -state normal -command \
                [list demo::putChildren $p $tbl root]
        }
    }
}
</pre>
  </blockquote>

  <p>The last argument of this procedure indicates the tree node to become the
  parent of the items displaying the data of the children of the widget passed
  as first argument.&nbsp; If this parent is the invisible <code>root</code>
  node then we first reset the sorting information by invoking the
  <code><a href="tablelistWidget.html#resetsortinfo">resetsortinfo</a></code>
  tablelist subcommand and delete the current items of the tablelist widget
  <code>tbl</code>.&nbsp; The procedure then iterates over the children of the
  specified widget and inserts the items built from some data retrieved by
  using the <code>winfo</code> command.&nbsp; Each new item is added to the end
  of the parent node's list of children with the aid of the <code><a href=
  "tablelistWidget.html#insertchildren">insertchild(ren)</a></code>
  subcommand.</p>

  <p>For each child widget, we invoke the <code><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></code> tablelist
  operation to set the value of the <code>-image</code> option of the
  corresponding row's first cell, containing the leaf name of the child.&nbsp;
  In this way, the procedure inserts the image <code>$leafImg</code> or
  <code>$compImg</code> into the first cell, depending on whether the child in
  question is a leaf or a composite widget.&nbsp; (Remember that both images
  were created outside this procedure, within the initialization of the
  <code>demo</code> namespace.)</p>

  <p>We mark every newly created row corresponding to a child widget that has
  children itself as collapsed by invoking the <code><a href=
  "tablelistWidget.html#collapse">collapse</a></code> subcommand.&nbsp; This
  will prepend an expand/collapse control to the content of the first column,
  whose column index <code>0</code> is the default value of the <code><a href=
  "tablelistWidget.html#treecolumn">-treecolumn</a></code> configuration
  option.</p>

  <p>We use the <code><a href=
  "tablelistWidget.html#rowattrib">rowattrib</a></code> tablelist subcommand to
  remember the full path name of every child widget as a private attribute
  associated with the corresponding tablelist row, because it will be needed at
  several places later on.</p>

  <p>As mentioned above, the <code>demo::expandCmd</code> procedure will be
  invoked automatically when expanding a row that contains an expand/collapse
  control:</p>

  <blockquote>
    <pre>
------------------------------------------------------------------------------
# demo::expandCmd
#
# Outputs the data of the children of the widget whose leaf name is displayed
# in the first cell of the specified row of the tablelist widget tbl, as child
# items of the one identified by row.
#------------------------------------------------------------------------------
proc demo::expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
        set w [$tbl rowattrib $row pathName]
        putChildren $w $tbl $row

        #
        # Apply the last sorting (if any) to the new items
        #
        $tbl refreshsorting $row
    }
}
</pre>
  </blockquote>

  <p>The procedure invokes the <code><a href=
  "tablelistWidget.html#childcount">childcount</a></code> subcommand to check
  whether the children of the row that is about to be expanded have already
  been inserted into the tablelist widget, and inserts them if this is not the
  case.&nbsp; It also makes sure that the child items will be displayed in the
  order corresponding to the last sorting (if any), with the aid of the
  <code><a href="tablelistWidget.html#refreshsorting">refreshsorting</a></code>
  tablelist subcommand.&nbsp; Any sorting (if needed) will only be performed on
  the child items just inserted into the tablelist widget.</p>

  <p>The <code>demo::formatBoolean</code> and <code>demo::labelCmd</code>
  procedures mentioned above are trivial:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::formatBoolean
#
# Returns "yes" or "no", according to the specified boolean value.
#------------------------------------------------------------------------------
proc demo::formatBoolean val {
    return [expr {$val ? "yes" : "no"}]
}

#------------------------------------------------------------------------------
# demo::labelCmd
#
# Sorts the content of the tablelist widget tbl by its col'th column and makes
# sure the items will be updated 500 ms later (because one of the items might
# refer to a canvas containing the arrow that displays the sorting order).
#------------------------------------------------------------------------------
proc demo::labelCmd {tbl col} {
    tablelist::sortByColumn $tbl $col
    updateItemsDelayed $tbl
}
</pre>
  </blockquote>

  <p>The command <code><a href=
  "tablelistColSort.html#sortByColumn">tablelist::sortByColumn</a></code> sorts
  the items of the tablelist widget by the specified column in the right order,
  by invoking the <code><a href=
  "tablelistWidget.html#sortbycolumn">sortbycolumn</a></code> subcommand of the
  Tcl command associated with the tablelist widget.</p>

  <p>The implementation of the <code>demo::updateItemsDelayed</code> command,
  invoked in this procedure and already encountered in the
  <code>demo::displayChildren</code> procedure above, is quite simple:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::updateItemsDelayed
#
# Arranges for the items of the tablelist widget tbl to be updated 500 ms later.
#------------------------------------------------------------------------------
proc demo::updateItemsDelayed tbl {
    #
    # Schedule the demo::updateItems command for execution
    # 500 ms later, but only if it is not yet pending
    #
    if {[string compare [$tbl attrib afterId] ""] == 0} {
        $tbl attrib afterId [after 500 [list demo::updateItems $tbl]]
    }
}

#------------------------------------------------------------------------------
# demo::updateItems
#
# Updates the items of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc demo::updateItems tbl {
    #
    # Reset the tablelist's "afterId" attribute
    #
    $tbl attrib afterId ""

    #
    # Update the items
    #
    set rowCount [$tbl size]
    for {set row 0} {$row &lt; $rowCount} {incr row} {
        set c [$tbl cellcget $row,0 -text]
        if {![winfo exists $c]} {
            continue
        }

        set item {}
        lappend item \
                [winfo name $c] [winfo class $c] [winfo x $c] [winfo y $c] \
                [winfo width $c] [winfo height $c] [winfo ismapped $c] \
                [winfo viewable $c] [winfo manager $c]
        $tbl rowconfigure $row -text $item
    }

    #
    # Repeat the last sort operation (if any)
    #
    $tbl refreshsorting
}
</pre>
  </blockquote>

  <p>As already mentioned in the <a href="#ex_config">previous example</a>,
  each tablelist widget may have any number of private attributes, which can be
  set and retrieved with the aid of the <code><a href=
  "tablelistWidget.html#attrib">attrib</a></code> subcommand of the Tcl command
  corresponding to the widget.&nbsp; The <code>afterId</code> attribute is set
  by the <code>demo::updateItemsDelayed</code> procedure when sheduling the
  <code>demo::updateItems</code> command for execution 500 ms later, but only
  if its value is an empty string.&nbsp; For this reason, the
  <code>demo::updateItems</code> procedure resets this attribute.&nbsp; It also
  makes use of the <code><a href=
  "tablelistWidget.html#cellcget">cellcget</a></code> tablelist subcommand to
  get the path names contained in the first cell of each row, and updates the
  data of the children with the aid of the <code><a href=
  "tablelistWidget.html#rowconfigure">rowconfigure</a></code> subcommand.&nbsp;
  After updating the items, the procedure repeats the most recent sorting based
  on a column (if there was one), with the aid of the <code><a href=
  "tablelistWidget.html#refreshsorting">refreshsorting</a></code>
  subcommand.</p>

  <p>The procedures <code>demo::putChildrenOfSelWidget</code>,
  <code>demo::dispConfigOfSelWidget</code>, and
  <code>demo::postPopupMenu</code> (see <code>demo::displayChildren</code>) are
  also straight-forward.&nbsp; For example, the
  <code>demo::putChildrenOfSelWidget</code> command shown below makes use of
  the <code><a href="tablelistWidget.html#curselection">curselection</a></code>
  subcommand to get the index of the selected row.&nbsp; More precisely,
  <code>curselection</code> returns a list, but in our case this list will have
  exactly one element, hence it can be used directly as the first component of
  a cell index.</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::putChildrenOfSelWidget
#
# Outputs the data of the children of the selected widget into the tablelist
# widget tbl.
#------------------------------------------------------------------------------
proc demo::putChildrenOfSelWidget tbl {
    set w [$tbl cellcget [$tbl curselection],0 -text]
    if {![winfo exists $w]} {
        bell
        tk_messageBox -title "Error" -icon error -message \
            "Bad window path name \"$w\"" -parent [winfo toplevel $tbl]
        return ""
    }

    if {[llength [winfo children $w]] == 0} {
        bell
    } else {
        putChildren $w $tbl
    }
}
</pre>
  </blockquote>

  <p>The procedure <code>demo::refreshView</code>, associated with the
  <b>Refresh</b> button, is implemented as follows:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# demo::refreshView
#
# Redisplays the data of the children of the widget w in the tablelist widget
# tbl and restores the expanded states of the items as well as the vertical
# view.
#------------------------------------------------------------------------------
proc demo::refreshView {w tbl} {
    #
    # Save the vertical view and get the path names of
    # the child widgets displayed in the expanded rows
    #
    set yView [$tbl yview]
    foreach key [$tbl expandedkeys] {
        set pathName [$tbl rowattrib $key pathName]
        set expandedWidgets($pathName) 1
    }

    #
    # Redisplay the data of the widget's (possibly changed) children and
    # restore the expanded states of the children, along with the vertical view
    #
    putChildren $w $tbl root
    restoreExpandedStates $tbl root expandedWidgets
    $tbl yview moveto [lindex $yView 0]
}
</pre>
  </blockquote>

  <p>Before redisplaying the tablelist's content via
  <code>demo::putChildren</code>, we get the full keys of the currently
  expanded items with the aid of the <code><a href=
  "tablelistWidget.html#expandedkeys">expandedkeys</a></code> tablelist
  subcommand and insert the correspondig widget paths into the array
  <code>expandedWidgets</code>.&nbsp; After redisplaying the data of the
  (possibly changed) children of the widget given as first argument, we pass
  this array to the <code>demo::restoreExpandedStates</code> procedure shown
  below:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# restoreExpandedStates
#
# Expands those children of the parent identified by nodeIdx that display the
# data of child widgets whose path names are the names of the elements of the
# array specified by the last argument.
#------------------------------------------------------------------------------
proc demo::restoreExpandedStates {tbl nodeIdx expandedWidgetsName} {
    upvar $expandedWidgetsName expandedWidgets

    foreach key [$tbl childkeys $nodeIdx] {
        set pathName [$tbl rowattrib $key pathName]
        if {[info exists expandedWidgets($pathName)]} {
            $tbl expand $key -partly
            restoreExpandedStates $tbl $key expandedWidgets
        }
    }
}
</pre>
  </blockquote>

  <p>The procedure retrieves the list of full keys of the children of the
  parent node indicated by <code>nodeIdx</code>, by means of the <code><a href=
  "tablelistWidget.html#childkeys">childkeys</a></code> tablelist
  subcommand.&nbsp; It then loops over this list, and for each key for which
  the corresponding row was previously expanded, it invokes the <code><a href=
  "tablelistWidget.html#expand">expand</a></code> tablelist subcommand and then
  calls itself recursively to restore the expanded states of that row's
  children.</p>

  <h3 id="ex_dirViewer">A Directory Viewer Based on a tablelist</h3>

  <p>The script <code>dirViewer.tcl</code> in the <code>demos</code> directory
  displays the contents of the volumes mounted on the system (e.g., the root
  <code>/</code> on UNIX and the local drives on Windows) in a tablelist used
  as multi-column tree widget:</p>

  <blockquote>
    <img src="dirViewer.png" alt="Directory Viewer" width="675" height="432">
  </blockquote>

  <p>By double-clicking an item or invoking the single entry of a pop-up menu
  within the body of the tablelist, you can display the content of the folder
  corresponding to the selected item.&nbsp; To go one level up, click on the
  <b>Parent</b> button.</p>

  <p>There are a lot of similarities between this script and the one discussed
  in the <a href="#ex_browse">previous section</a>.&nbsp; In the following we
  will only present a few procedures that invoke tablelist commands not
  encountered in the examples above:</p>

  <blockquote>
    <pre>
package require Tk 8.3
package require tablelist 6.0

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create three images
#
image create photo clsdFolderImg -file [file join $dir clsdFolder.gif]
image create photo openFolderImg -file [file join $dir openFolder.gif]
image create photo fileImg       -file [file join $dir file.gif]

#------------------------------------------------------------------------------
# displayContents
#
# Displays the content of the directory dir in a tablelist widget.
#------------------------------------------------------------------------------
proc displayContents dir {
    #
    # Create a scrolled tablelist widget with 3 dynamic-
    # width columns and interactive sort capability
    #
    set tf .tf
    frame $tf -class ScrollArea
    set tbl $tf.tbl
    set vsb $tf.vsb
    set hsb $tf.hsb
    tablelist::tablelist $tbl \
        -columns {0 "Name"          left
                  0 "Size"          right
                  0 "Date Modified" left} \
        -expandcommand expandCmd -collapsecommand collapseCmd \
        -xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] \
        -movablecolumns no -setgrid no -showseparators yes -height 20 -width 80
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }
    $tbl columnconfigure 0 -formatcommand formatString -sortmode dictionary
    $tbl columnconfigure 1 -formatcommand formatSize -sortmode integer
    $tbl columnconfigure 2 -formatcommand formatString
    scrollbar $vsb -orient vertical   -command [list $tbl yview]
    scrollbar $hsb -orient horizontal -command [list $tbl xview]

    . . .

    #
    # Populate the tablelist with the content of the given directory
    #
    $tbl sortbycolumn 0
    putContents $dir $tbl root
}
</pre>
  </blockquote>

  <p>The procedure <code>displayContents</code> creates the tablelist widget
  and the two scrollbars as children of a frame of class
  <code>ScrollArea</code>.&nbsp; For this class, the file
  <code>option.tcl</code>, <code>source</code>d into the main script, contains
  some look &amp; feel related settings similar to the ones encountered in our
  <a href="#ex_config">first example</a>:</p>

  <blockquote>
    <pre>
option add *ScrollArea.borderWidth                      1
option add *ScrollArea.relief                           sunken
option add *ScrollArea.Tablelist.borderWidth            0
option add *ScrollArea.Tablelist.highlightThickness     0
</pre>
  </blockquote>

  <p>The procedure specifies a value not only for the <code><a href=
  "tablelistWidget.html#expandcommand">-expandcommand</a></code> option of the
  tablelist it creates, but also for its <code><a href=
  "tablelistWidget.html#collapsecommand">-collapsecommand</a></code>
  option.&nbsp; The latter will merely restore the image shown in the first
  column to the one displaying a closed folder (see below).</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# putContents
#
# Outputs the content of the directory dir into the tablelist widget tbl, as
# child items of the one identified by nodeIdx.
#------------------------------------------------------------------------------
proc putContents {dir tbl nodeIdx} {
    . . .

    if {[string compare $nodeIdx "root"] == 0} {
        if {[string compare $dir ""] == 0} {
            if {[llength [file volumes]] == 1} {
                wm title . "Contents of the File System"
            } else {
                wm title . "Contents of the File Systems"
            }
        } else {
            wm title . "Contents of the Directory \"[file nativename $dir]\""
        }

        $tbl delete 0 end
        set row 0
    } else {
        set row [expr {$nodeIdx + 1}]
    }

    #
    # Build a list from the data of the subdirectories and
    # files of the directory dir.  Prepend a "D" or "F" to
    # each entry's name and modification date &amp; time, for
    # sorting purposes (it will be removed by formatString).
    #
    set itemList {}
    if {[string compare $dir ""] == 0} {
        foreach volume [file volumes] {
            lappend itemList [list D[file nativename $volume] -1 D $volume]
        }
    } else {
        foreach entry [glob -nocomplain -types {d f} -directory $dir *] {
            if {[catch {file mtime $entry} modTime] != 0} {
                continue
            }

            if {[file isdirectory $entry]} {
                lappend itemList [list D[file tail $entry] -1 \
                    D[clock format $modTime -format "%Y-%m-%d %H:%M"] $entry]
            } else {
                lappend itemList [list F[file tail $entry] [file size $entry] \
                    F[clock format $modTime -format "%Y-%m-%d %H:%M"] ""]
            }
        }
    }

    #
    # Sort the above list and insert it into the tablelist widget
    # tbl as list of children of the row identified by nodeIdx
    #
    set itemList [$tbl applysorting $itemList]
    $tbl insertchildlist $nodeIdx end $itemList

    #
    # Insert an image into the first cell of each newly inserted row
    #
    foreach item $itemList {
        set name [lindex $item end]
        if {[string compare $name ""] == 0} {                   ;# file
            $tbl cellconfigure $row,0 -image fileImg
        } else {                                                ;# directory
            $tbl cellconfigure $row,0 -image clsdFolderImg
            $tbl rowattrib $row pathName $name

            #
            # Mark the row as collapsed if the directory is non-empty
            #
            if {[file readable $name] &amp;&amp; [llength \
                [glob -nocomplain -types {d f} -directory $name *]] != 0} {
                $tbl collapse $row
            }
        }

        incr row
    }

    . . .
}
</pre>
  </blockquote>

  <p>The main difference between the procedure <code>putContents</code> above
  and the procedure <code><a href="#putChildren">demo::putChildren</a></code>
  described in the <a href="#ex_browse">previous section</a> is related to the
  way child items are inserted into the tablelist widget.&nbsp; Instead of
  inserting them individually with the aid of the <code><a href=
  "tablelistWidget.html#insertchildren">insertchild(ren)</a></code> tablelist
  subcommand, here we add the relevant data to a list of items and then invoke
  the much more performant <code><a href=
  "tablelistWidget.html#insertchildlist">insertchildlist</a></code>
  subcommand.&nbsp; Also, instead of first inserting the items and then sorting
  them via <code><a href=
  "tablelistWidget.html#refreshsorting">refreshsorting</a></code>, we first
  perform the necessary sortings on the above-mentioned list of items by
  invoking the <code><a href=
  "tablelistWidget.html#applysorting">applysorting</a></code> subcommand.&nbsp;
  Again, this is much faster than sorting the already inserted child items.</p>

  <p>This procedure also illustrates an effective technique based on the
  <code><a href=
  "tablelistWidget.html#col_formatcommand">-formatcommand</a></code> column
  configuration option:&nbsp; In the tablelist widget's internal list, the
  names and modification times of the directories and files are preceded by a
  <code>D</code> and <code>F</code>, respectively.&nbsp; This makes sure that
  the directories will sort before the files (when sorting in ascending
  order).&nbsp; When displaying the items, the Tablelist code will
  automatically invoke the <code>formatString</code> procedure, which removes
  the first character.&nbsp; Similarly, in the widget's internal list, the size
  of a directory is set to <code>-1</code>, which sorts before the sizes of the
  files.&nbsp; The <code>formatSize</code> procedure, invoked automatically
  when displaying the items, replaces this value with an empty string:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# formatString
#
# Returns the substring obtained from the specified value by removing its first
# character.
#------------------------------------------------------------------------------
proc formatString val {
    return [string range $val 1 end]
}

#------------------------------------------------------------------------------
# formatSize
#
# Returns an empty string if the specified value is negative and the value
# itself in user-friendly format otherwise.
#------------------------------------------------------------------------------
proc formatSize val {
    if {$val &lt; 0} {
        return ""
    } elseif {$val &lt; 1024} {
        return "$val bytes"
    } elseif {$val &lt; 1048576} {
        return [format "%.1f KB" [expr {$val / 1024.0}]]
    } elseif {$val &lt; 1073741824} {
        return [format "%.1f MB" [expr {$val / 1048576.0}]]
    } else {
        return [format "%.1f GB" [expr {$val / 1073741824.0}]]
    }
}
</pre>
  </blockquote>

  <p>Besides its common task of inserting the children of the row to be
  expanded, the <code>expandCmd</code> procedure shown below also changes the
  image contained in the first column to the one displaying an open
  folder.&nbsp; The <code>collapseCmd</code> procedure restores the image to
  the one displaying a closed folder:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# expandCmd
#
# Outputs the content of the directory whose leaf name is displayed in the
# first cell of the specified row of the tablelist widget tbl, as child items
# of the one identified by row, and updates the image displayed in that cell.
#------------------------------------------------------------------------------
proc expandCmd {tbl row} {
    if {[$tbl childcount $row] == 0} {
        set dir [$tbl rowattrib $row pathName]
        putContents $dir $tbl $row
    }

    if {[$tbl childcount $row] != 0} {
        $tbl cellconfigure $row,0 -image openFolderImg
    }
}

#------------------------------------------------------------------------------
# collapseCmd
#
# Updates the image displayed in the first cell of the specified row of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc collapseCmd {tbl row} {
    $tbl cellconfigure $row,0 -image clsdFolderImg
}

. . .

displayContents ""
</pre>
  </blockquote>

  <p>The last line of the script invokes the procedure
  <code>displayContents</code> with an empty string as argument, i.e., displays
  the volumes mounted on the system.</p>

  <h3 id="ex_styles">Improving the Look &amp; Feel of a tablelist Widget</h3>

  <p>The script <code>styles.tcl</code> in the <code>demos</code> directory
  demonstrates some ways of making tablelist widgets smarter and improving the
  readability of their items.&nbsp; It creates 8 tablelist widgets, shown in
  the following figure:</p>

  <blockquote>
    <img src="styles.png" alt="Styles" width="698" height="493">
  </blockquote>

  <p>Here is the relevant code segment:</p>

  <blockquote>
    <pre>
#
# Create, configure, and populate 8 tablelist widgets
#
frame .f
for {set n 0} { $n &lt; 8} {incr n} {
    set tbl .f.tbl$n
    tablelist::tablelist $tbl \
        -columntitles {"Label 0" "Label 1" "Label 2" "Label 3"} \
        -background white -height 4 -width 40 -stretch all
    if {[$tbl cget -selectborderwidth] == 0} {
        $tbl configure -spacing 1
    }

    switch $n {
        1 {
            $tbl configure -showseparators yes
        }
        2 {
            $tbl configure -stripebackground #f0f0f0
        }
        3 {
            $tbl configure -stripebackground #f0f0f0 -showseparators yes
        }
        4 {
            $tbl columnconfigure 1 -background LightYellow
            $tbl columnconfigure 3 -background LightCyan
        }
        5 {
            $tbl configure -showseparators yes
            $tbl columnconfigure 1 -background LightYellow
            $tbl columnconfigure 3 -background LightCyan
        }
        6 {
            $tbl configure -stripebackground #f0f0f0
            $tbl columnconfigure 1 -background LightYellow \
                -stripebackground #f0f0d2
            $tbl columnconfigure 3 -background LightCyan \
                -stripebackground #d2f0f0
        }
        7 {
            $tbl configure -stripebackground #f0f0f0 -showseparators yes
            $tbl columnconfigure 1 -background LightYellow \
                -stripebackground #f0f0d2
            $tbl columnconfigure 3 -background LightCyan \
                -stripebackground #d2f0f0
        }
    }

    foreach row {0 1 2 3} {
        $tbl insert end \
             [list "Cell $row,0" "Cell $row,1" "Cell $row,2" "Cell $row,3"]
    }
}
</pre>
  </blockquote>

  <p>The only configuration option used here but not discussed in the first
  three examples (although already encountered in the <a href=
  "#ex_dirViewer">previous one</a>) is <code><a href=
  "tablelistWidget.html#showseparators">-showseparators</a></code>.&nbsp; The
  visual effect it produces looks nice both by itself and combined with
  horizontal or vertical stripes, created by using the <code><a href=
  "tablelistWidget.html#stripebackground">-stripebackground</a></code> option
  and the <code><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></code> subcommand,
  respectively.</p>

  <h3 id="ex_editing">Advanced Interactive tablelist Cell Editing</h3>

  <p>The scripts <code>tileWidgets.tcl</code>, <code>bwidget.tcl</code>,
  <code>iwidgets.tcl</code>, and <code>miscWidgets.tcl</code> in the
  <code>demos</code> directory create a tablelist widget displaying some
  parameters of 16 serial lines, and demonstrate how to use various widgets
  from the Tk core and from the packages tile, BWidget, Iwidgets, combobox (by
  Bryan Oakley), ctext, and Mentry (or Mentry_tile) for interactive cell
  editing.&nbsp; The following figure shows the tablelist widget, together with
  a BWidget ComboBox used to edit the content of one of its cells:</p>

  <blockquote>
    <img src="bwidget.png" alt="Serial Line Configuration" width="841" height=
    "387">
  </blockquote>

  <p>Here is the relevant code segment from the script <code>bwidget.tcl</code>
  (the scripts <code>tileWidgets.tcl</code>, <code>iwidgets.tcl</code>, and
  <code>miscWidgets.tcl</code> are similar).&nbsp; A few parts of the code are
  shown in <span>red</span> color &ndash; we will return to this towards the
  end of the section.</p>

  <blockquote>
    <pre>
package require Tk 8.4                          ;# because of "-compound"
package require tablelist 6.0
package require BWidget

wm title . "Serial Line Configuration"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]
option add *Tablelist*Entry.background white

#
# Register some widgets from the BWidget package for interactive cell editing
#
tablelist::addBWidgetEntry
tablelist::addBWidgetSpinBox
tablelist::addBWidgetComboBox

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

#
# Create a tablelist widget with editable columns (except the first one)
#
set tbl .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 \
    -height 0 -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -sortmode integer
$tbl columnconfigure 1 <span>-name available -editable yes -editwindow checkbutton</span> \
    -formatcommand emptyStr
$tbl columnconfigure 2 -name lineName  -editable yes -editwindow Entry \
    -sortmode dictionary
$tbl columnconfigure 3 -name baudRate  -editable yes -editwindow ComboBox \
    -sortmode integer
$tbl columnconfigure 4 -name dataBits  -editable yes -editwindow SpinBox
$tbl columnconfigure 5 -name parity    -editable yes -editwindow ComboBox
$tbl columnconfigure 6 -name stopBits  -editable yes -editwindow ComboBox
$tbl columnconfigure 7 -name handshake -editable yes -editwindow ComboBox
$tbl columnconfigure 8 -name actDate   -editable yes -editwindow Entry \
    -formatcommand formatDate -sortmode integer
$tbl columnconfigure 9 -name actTime   -editable yes -editwindow Entry \
    -formatcommand formatTime -sortmode integer
$tbl columnconfigure 10 -name color    -editable yes -editwindow 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; set the activation
# date &amp; time to 10 minutes past the current clock value
#
set clock [expr {[clock seconds] + 600}]
for {set i 0; set n 1} {$i &lt; 16} {set i $n; incr n} {
    $tbl insert end [list $n [expr {$i &lt; 8}] "Line $n" 9600 8 None 1 XON/XOFF \
        $clock $clock [lindex $colorNames $i]]

    <span>set availImg [expr {($i &lt; 8) ? "checkedImg" : "uncheckedImg"}]
    $tbl cellconfigure end,available -image $availImg</span>
    $tbl cellconfigure end,color -image img[lindex $colorValues $i]
}

set btn [button .btn -text "Close" -command exit]

#
# Manage the widgets
#
pack $btn -side bottom -pady 10
pack $tbl -side top -expand yes -fill both
</pre>
  </blockquote>

  <p>We invoke the <code><a href=
  "tablelistBWidget.html#Entry">tablelist::addBWidgetEntry</a></code>,
  <code><a href=
  "tablelistBWidget.html#SpinBox">tablelist::addBWidgetSpinBox</a></code>, and
  <code><a href=
  "tablelistBWidget.html#ComboBox">tablelist::addBWidgetComboBox</a></code>
  commands to register the Entry, SpinBox, and ComboBox widgets from the
  BWidget package for interactive cell editing.&nbsp; These commands return the
  values <code>"Entry"</code>, <code>"SpinBox"</code>, and
  <code>"ComboBox"</code>, respectively, which we then use in the
  <code><a href="tablelistWidget.html#col_editwindow">-editwindow</a></code>
  column configuration option to set the edit window for the columns no. 2,
  ..., 10.&nbsp; In columns no. 1 and 10 we use the Tk core checkbutton and
  menubutton widgets, which are automatically registered for interactive cell
  editing.</p>

  <p>Notice the use of the <code><a href=
  "tablelistWidget.html#col_name">-name</a></code> column configuration option,
  which allows us to access the columns by their names instead of by numerical
  column indices.&nbsp; This is important, because the file
  <code>option.tcl</code>, which is <code>source</code>d into the main script,
  contains the line</p>

  <blockquote>
    <pre>
option add *Tablelist.movableColumns    yes
</pre>
  </blockquote>

  <p>The <code>editStartCmd</code> and <code>editEndCmd</code> procedures shown
  below use the <code><a href=
  "tablelistWidget.html#columncget">columncget</a></code> subcommand to
  retrieve the name of the column from the numerical column index.</p>

  <p>By the way, two further option database settings contained in the file
  <code>option.tcl</code> are:</p>

  <blockquote>
    <pre>
option add *Tablelist.labelCommand      tablelist::sortByColumn
option add *Tablelist.labelCommand2     tablelist::addToSortColumns
</pre>
  </blockquote>

  <p>The <code><a href=
  "tablelistColSort.html#sortByColumn">tablelist::sortByColumn</a></code> and
  <code><a href=
  "tablelistColSort.html#addToSortColumns">tablelist::addToSortColumns</a></code>
  commands specified in these settings enable the user to sort the items by one
  or more columns, with the aid of the left mouse button and of the
  <code>Shift</code> key.</p>

  <p>The <code>editStartCmd</code> procedure, specified as the value of the
  <code><a href=
  "tablelistWidget.html#editstartcommand">-editstartcommand</a></code>
  configuration option, needs the path name of the edit window, in order to be
  able to configure the widget in various ways.&nbsp; This is a common
  situation, and Tablelist provides the <code><a href=
  "tablelistWidget.html#editwinpath">editwinpath</a></code> subcommand for this
  purpose:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# 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] &lt;= 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] &lt;= 6 &amp;&amp; [regexp {^[0-9]*$} %S]}}
        }

        dataBits {
            #
            # Configure the SpinBox
            #
            $w configure -range {5 8 1} -editable no
        }

        parity {
            #
            # Populate the ComboBox and make it non-editable
            #
            $w configure -values {None Even Odd Mark Space} -editable no
        }

        . . .

        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
}
</pre>
  </blockquote>

  <p>The <code>editEndCmd</code> procedure, specified as the value of the
  <code><a href=
  "tablelistWidget.html#editendcommand">-editendcommand</a></code>
  configuration option, is responsible for a final validation of the edit
  window's text.&nbsp; Another purpose of this command is to convert the text
  contained in the edit window to the cell's new <i>internal</i> content, which
  is necessary because the internal value of the activation date and time is a
  clock value in seconds:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# 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] {
        <span>available {
            #
            # Update the image contained in the cell
            #
            set img [expr {$text ? "checkedImg" : "uncheckedImg"}]
            $tbl cellconfigure $row,$col -image $img
        }</span>

        baudRate {
            #
            # Check whether the baud rate is an integer in the range 50..921600
            #
            if {![regexp {^[0-9]+$} $text] || $text &lt; 50 || $text &gt; 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 &lt;= [clock seconds]} {
                bell
                tk_messageBox -title "Error" -icon error -message \
                    "The activation date &amp; time must be in the future"
                $tbl rejectinput
            } else {
                $tbl cellconfigure $row,actTime -text $actClock
                return $actClock
            }
        }

        . . .

        color {
            #
            # Update the image contained in the cell
            #
            $tbl cellconfigure $row,$col -image img$::colors($text)
        }
    }

    return $text
}
</pre>
  </blockquote>

  <p>Instead of making the <code>"Available"</code> column editable via a
  <i>temporary</i> checkbutton and displaying the images
  <code>"checkedImg"</code> and <code>"uncheckedImg"</code> in its cells, we
  can use the <code><a href=
  "tablelistWidget.html#embedcheckbuttons">embedcheckbuttons</a></code>
  subcommand to populate the column with <i>persistently</i> embedded
  checkbuttons.&nbsp; The necessary changes are as follows:</p>

  <ul>
    <li class="tm">Remove those parts of the code above that are shown in
    <span>red</span> color.</li>

    <li class="tm">
      Invoke

      <blockquote>
        <pre>
$tbl embedcheckbuttons 1
</pre>
      </blockquote>

      after populating the tablelist widget.
    </li>
  </ul>

  <p>As mentioned above, the scripts <code>tileWidgets.tcl</code>,
  <code>iwidgets.tcl</code>, and <code>miscWidgets.tcl</code> are similar to
  <code>bwidget.tcl</code>.&nbsp; The first one makes use of the tile entry,
  spinbox, combobox, checkbutton, and menubutton widgets.&nbsp; The second one
  uses (besides the Tk core checkbutton and menubutton) the entryfield,
  spinint, combobox, dateentry, and timeentry widgets from the Iwidgets package
  and the validation facilities specific to that library.&nbsp; The third
  script makes use of the entry, spinbox, checkbutton, and menubutton widgets
  from the Tk core, Bryan Oakley's combobox, and of the mentry widgets of type
  <code>"Date"</code> and <code>"Time"</code>, and it performs the entry
  validation with the aid of the Wcb package (which is required anyway for the
  Mentry library).</p>

  <h3 id="ex_windows">A tablelist Widget Containing Embedded Windows</h3>

  <p>The script <code>embeddedWindows.tcl</code> in the <code>demos</code>
  directory creates a tablelist widget whose items correspond to the Tk library
  scripts.&nbsp; The size of each file (in bytes) is not only displayed as a
  number, but is also illustrated with the aid of a frame with red background,
  created as a child of an embedded frame with ivory background.&nbsp; The
  files can be viewed by clicking on the corresponding embedded button
  widgets.</p>

  <p>The following screenshot shows the tablelist widget with the mouse cursor
  over the first header label, causing this label to appear in
  <code>active</code> state:</p>

  <blockquote>
    <img src="embeddedWindows.png" alt="Embedded Windows" width="432" height=
    "303">
  </blockquote>

  <p>First, we create and populate the tablelist widget:</p>

  <blockquote>
    <pre>
package require tablelist 6.0

wm title . "Tk Library Scripts"

#
# Add some entries to the Tk option database
#
set dir [file dirname [info script]]
source [file join $dir option.tcl]

#
# Create the font TkFixedFont if not yet present
#
catch {font create TkFixedFont -family Courier -size -12}

#
# Create an image to be displayed in buttons embedded in a tablelist widget
#
image create photo openImg -file [file join $dir open.gif]

#
# Create a vertically scrolled tablelist widget with 5
# dynamic-width columns and interactive sort capability
#
set tf .tf
frame $tf -class ScrollArea
set tbl $tf.tbl
set vsb $tf.vsb
tablelist::tablelist $tbl \
    -columns {0 "File Name" left
              0 "Bar Chart" center
              0 "File Size" right
              0 "View"      center
              0 "Seen"      center} \
    -setgrid no -yscrollcommand [list $vsb set] -width 0
if {[$tbl cget -selectborderwidth] == 0} {
    $tbl configure -spacing 1
}
$tbl columnconfigure 0 -name fileName
$tbl columnconfigure 1 -formatcommand emptyStr -sortmode integer
$tbl columnconfigure 2 -name fileSize -sortmode integer
$tbl columnconfigure 4 -name seen
scrollbar $vsb -orient vertical -command [list $tbl yview]

proc emptyStr val { return "" }

#
# Create a bold font
#
set tblFont [$tbl cget -font]
set size [font actual $tblFont -size]
if {$size == 0} {                                       ;# e.g., on Ubuntu
    set size -12
}
eval font create BoldFont [font actual $tblFont] -size $size -weight bold

#
# Populate the tablelist widget
#
cd $tk_library
set totalSize 0
set maxSize 0
foreach fileName [lsort [glob *.tcl]] {
    set fileSize [file size $fileName]
    $tbl insert end [list $fileName $fileSize $fileSize "" no]

    incr totalSize $fileSize
    if {$fileSize &gt; $maxSize} {
        set maxSize $fileSize
    }
}
$tbl header insert 0 [list "[$tbl size] *.tcl files" "" $totalSize "" ""]
$tbl header rowconfigure 0 -foreground blue
</pre>
  </blockquote>

  <p>We insert the size of each file not only into the column with the
  title&nbsp; <code>"File Size"</code>,&nbsp; but also into the column&nbsp;
  <code>"Bar Chart"</code>.&nbsp; Since we configured this column with&nbsp;
  <code>-formatcommand emptyStr</code>,&nbsp; the text will remain hidden in
  it.&nbsp; It will, however, be needed when sorting the items by that
  column.</p>

  <p>After populating the tablelist's body, we create a header item displaying
  the total number and size of the library files, by invoking the&nbsp;
  <code><a href="tablelistWidget.html#hdr_insert">header
  insert</a></code>&nbsp; subcommand, and change its foreground color with the
  aid of the&nbsp; <code><a href="tablelistWidget.html#hdr_rowconfigure">header
  rowconfigure</a></code>&nbsp; subcommand.</p>

  <p>To be able to create the embedded windows, we have first to implement the
  creation scripts for them, as specified in the description of the
  <code><a href="tablelistWidget.html#cell_window">-window</a></code> cell
  configuration option.&nbsp; Here is the script that creates a frame to be
  embedded into the column displaying the bar chart:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# createFrame
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget tbl, as well as a child frame representing the size of the
# file whose name is diplayed in the first column of the cell's row.
#------------------------------------------------------------------------------
proc createFrame {tbl row col w} {
    #
    # Create the frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w -width 102 -height 14 -background ivory -borderwidth 1 \
             -relief solid
    bindtags $w [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Create the child frame and replace the binding tag "Frame"
    # with "TablelistBody" in the list of its binding tags
    #
    frame $w.f -height 12 -background red -borderwidth 1 -relief raised
    bindtags $w.f [lreplace [bindtags $w] 1 1 TablelistBody]

    #
    # Manage the child frame
    #
    set fileSize [$tbl cellcget $row,fileSize -text]
    place $w.f -relwidth [expr {double($fileSize) / $::maxSize}]
}
</pre>
  </blockquote>

  <p>Since the frame will be embedded into the tablelist's body, we want to
  have the same handling of the mouse events in the frame and in its child
  frame as in the rest of the tablelist's body.&nbsp; To this end we replace
  the binding tag <code>Frame</code> (which has no own bindings anyway) with
  <code><a href="tablelistWidget.html#body_bindings">TablelistBody</a></code>,
  thus making sure that the default binding scripts associated with that tag
  will be valid for the parent frame and its child, too.</p>

  <p>We <code>place</code> the red child frame within its parent using the
  <code>-relwidth</code> option, to make sure that its width will remain
  proportional to the size of the corresponding file when resizing the parent
  frame (which will happen when resizing its column, as seen below).</p>

  <p>The creation script for the buttons used for viewing the Tk library files
  is quite simple:</p>

  <blockquote>
    <pre>
#------------------------------------------------------------------------------
# createButton
#
# Creates a button widget w to be embedded into the specified cell of the
# tablelist widget tbl.
#------------------------------------------------------------------------------
proc createButton {tbl row col w} {
    set key [$tbl getkeys $row]
    button $w -image openImg -highlightthickness 0 -takefocus 0 \
              -command [list viewFile $tbl $key]
}

#------------------------------------------------------------------------------
# viewFile
#
# Displays the content of the file whose name is contained in the row with the
# given key of the tablelist widget tbl.
#------------------------------------------------------------------------------
proc viewFile {tbl key} {
    set top .top$key
    if {[winfo exists $top]} {
        raise $top
        return ""
    }

    toplevel $top
    set fileName [$tbl cellcget k$key,fileName -text]
    wm title $top "File \"$fileName\""

    #
    # Create a vertically scrolled text widget as a grandchild of the toplevel
    #
    set tf $top.tf
    frame $tf -class ScrollArea
    set txt $tf.txt
    set vsb $tf.vsb
    text $txt -background white -font TkFixedFont -setgrid yes \
              -yscrollcommand [list $vsb set]
    catch {$txt configure -tabstyle wordprocessor}      ;# for Tk 8.5 and above
    scrollbar $vsb -orient vertical -command [list $txt yview]

    #
    # Insert the file's content into the text widget
    #
    set chan [open $fileName]
    $txt insert end [read $chan]
    close $chan

    . . .

    #
    # Mark the file as seen
    #
    $tbl rowconfigure k$key -font BoldFont
    $tbl cellconfigure k$key,seen -text yes
}
</pre>
  </blockquote>

  <p>Each file will be displayed in a text widget contained in a top-level
  whose name is <code>.top$key</code>, where <code>$key</code> is obtained with
  the aid of the <code><a href=
  "tablelistWidget.html#getkeys">getkeys</a></code> subcommand.&nbsp; By using
  the key instead of the row number, we will have a unique name for the
  top-level, even if the order of the items changes due to interactive sorting
  by a column.&nbsp; (Remember that the embedded windows will be destroyed and
  automatically recreated when sorting the items or moving the columns.)</p>

  <p>Having implemented the creation scripts for the frames and buttons, we can
  now use the <code><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></code> subcommand to
  effectively create these widgets as embedded windows.&nbsp; Notice the
  <code><a href=
  "tablelistWidget.html#cell_stretchwindow">-stretchwindow</a></code> option
  used for the embedded frames, to make sure that their width will be adapted
  to that of the containing column when the latter is being resized
  interactively.</p>

  <blockquote>
    <pre>
#
# Create embedded windows in the columns no. 1 and 3
#
set rowCount [$tbl size]
for {set row 0} {$row &lt; $rowCount} {incr row} {
    $tbl cellconfigure $row,1 -window createFrame -stretchwindow yes
    $tbl cellconfigure $row,3 -window createButton
}
</pre>
  </blockquote>

  <h3 id="ex_tile">Tile-Based Demo Scripts</h3>

  <p>The Tablelist distribution contains also tile-based counterparts of the
  demo scripts discussed above.&nbsp; As described in the <a href=
  "#ov_tile">More on Tablelist_tile</a> section of this tutorial, it is quite
  easy to port an application using the Tablelist package to one based on
  Tablelist_tile.&nbsp; For example, let's see how to transform the demo script
  <code><a href="#ex_editing">bwidget.tcl</a></code> into a tile-based one,
  called <code>bwidget_tile.tcl</code>.&nbsp; The changes are shown below in
  <span>red</span> color:</p>

  <p>First, we replace the starting lines</p>

  <blockquote>
    <pre>
package require Tk 8.3                          ;# because of entry validation
package require tablelist 6.0
</pre>
  </blockquote>

  <p>with</p>

  <blockquote>
    <pre>
package require tablelist<span>_tile</span> 6.0
</pre>
  </blockquote>

  <p>and the command</p>

  <blockquote>
    <pre>
source [file join $dir option.tcl]
</pre>
  </blockquote>

  <p>with</p>

  <blockquote>
    <pre>
source [file join $dir option<span>_tile</span>.tcl]
</pre>
  </blockquote>

  <p>To ensure that the overall appearance of the GUI will conform to the
  currently used theme, we create a theme-specific container for our
  widgets:</p>

  <blockquote>
    <pre>
<span>#
# Improve the window's appearance by using a tile
# frame as a container for the other widgets
#
set f [ttk::frame .f]</span>
</pre>
  </blockquote>

  <p>This implies that we have to replace the statement</p>

  <blockquote>
    <pre>
set tbl .tbl
</pre>
  </blockquote>

  <p>defining the path name of our tablelist widget with</p>

  <blockquote>
    <pre>
set tbl <span>$f</span>.tbl
</pre>
  </blockquote>

  <p>Similarly, instead of a Tk button created by the command</p>

  <blockquote>
    <pre>
set btn [button .btn -text "Close" -command exit]
</pre>
  </blockquote>

  <p>we use a tile button that is a child of the above tile frame:</p>

  <blockquote>
    <pre>
set btn [<span>ttk::</span>button <span>$f</span>.btn -text "Close" -command exit]
</pre>
  </blockquote>

  <p>We manage this frame in the usual manner:</p>

  <blockquote>
    <pre>
<span>pack $f -expand yes -fill both</span>
</pre>
  </blockquote>

  <p>The script <code>option_tile.tcl</code> is nearly identical to
  <code>option.tcl</code>.&nbsp; Its tile-specific part uses the values written
  by the command <code><a href=
  "tablelistThemes.html#setThemeDefaults">tablelist::setThemeDefaults</a></code>
  into the array <code>tablelist::themeDefaults</code>, to make sure that the
  selection will have the same theme-specific look in all the widgets created
  by the application:</p>

  <blockquote>
    <pre>
<span>tablelist::setThemeDefaults
if {[tablelist::getCurrentTheme] eq "aqua"} {
    option add *Listbox.selectBackground \
               $tablelist::themeDefaults(-selectbackground)
    option add *Listbox.selectForeground \
               $tablelist::themeDefaults(-selectforeground)
} else {
    option add *selectBackground  $tablelist::themeDefaults(-selectbackground)
    option add *selectForeground  $tablelist::themeDefaults(-selectforeground)
}
option add *selectBorderWidth     $tablelist::themeDefaults(-selectborderwidth)</span>
</pre>
  </blockquote>

  <p>The demo script <code>tileWidgets.tcl</code> uses not only the
  Tablelist_tile package for creating a tablelist widget with a modern
  theme-specific look &amp; feel, but also the tile entry, spinbox, combobox,
  checkbutton, and menubutoon widgets for interactive cell editing.&nbsp; The
  resulting window has a nice theme-specific appearance:</p>

  <blockquote>
    <img src="tileWidgets.png" alt="Serial Line Configuration" width="839"
    height="382">
  </blockquote>

  <p>The tile-based version of the demo script <code><a href=
  "#ex_windows">embeddedWindows.tcl</a></code> contains a bit more changes, but
  most of them are not Tablelist-specific.&nbsp; Please take a look at the file
  <code>embeddedWindows_tile.tcl</code> in the <code>demos</code> directory for
  the details.&nbsp; Here is a screenshot of the resulting window:</p>

  <blockquote>
    <img src="embeddedWindows_tile.png" alt="Embedded Windows" width="432"
    height="299">
  </blockquote>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistBWidget.html.





































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the BWidget Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, BWidget">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the BWidget Package</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#Entry">The <code><b>tablelist::addBWidgetEntry</b></code>
    Command</a></li>

    <li><a href="#SpinBox">The <code><b>tablelist::addBWidgetSpinBox</b></code>
    Command</a></li>

    <li><a href="#ComboBox">The
    <code><b>tablelist::addBWidgetComboBox</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The BWidget package is a library extension for Tcl/Tk versions 8.1.1 or
  higher, written in pure Tcl/Tk code.&nbsp; Its download location is</p>

  <blockquote>
    <address>
      <a href=
      "http://sourceforge.net/projects/tcllib/files">http://sourceforge.net/projects/tcllib/files</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the Entry,
  SpinBox, and ComboBox widgets from the BWidget package.&nbsp; The steps
  needed for using one of these widgets for editing the cells of a given column
  are as follows:</p>

  <ol>
    <li>Register the desired widget for interactive cell editing by invoking
    one of the commands described in this reference page.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="Entry">The <code><b>tablelist::addBWidgetEntry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addBWidgetEntry</code> &ndash; Register the Entry
    widget from the BWidget package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addBWidgetEntry</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the Entry widget from the BWidget package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the Entry widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>Entry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, BWidget, Entry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="SpinBox">The <code><b>tablelist::addBWidgetSpinBox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addBWidgetSpinBox</code> &ndash; Register the SpinBox
    widget from the BWidget package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addBWidgetSpinBox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the SpinBox widget from the BWidget package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the SpinBox widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>SpinBox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded SpinBox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the SpinBox non-editable or define
    validations for it, as well as for setting its (range of) values and its
    <code><b>-wrap</b></code> option.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, BWidget, SpinBox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="ComboBox">The <code><b>tablelist::addBWidgetComboBox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addBWidgetComboBox</code> &ndash; Register the
    ComboBox widget from the BWidget package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addBWidgetComboBox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the ComboBox widget from the BWidget package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the ComboBox widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ComboBox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded ComboBox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the ComboBox non-editable or define
    validations for it, as well as for populating its listbox component (with
    the aid of the ComboBox widget's <code><b>-values</b></code> option).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, BWidget, ComboBox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistBinding.html.































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Commands Related to Binding Scripts</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, binding script">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Commands Related to Binding Scripts</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#convEventFields">The
    <code><b>tablelist::convEventFields</b></code> Command</a></li>

    <li><a href="#getTablelistPath">The
    <code><b>tablelist::getTablelistPath</b></code> Command</a></li>

    <li><a href="#getTablelistColumn">The
    <code><b>tablelist::getTablelistColumn</b></code> Command</a></li>

    <li><a href="#delaySashPosUpdates">The
    <code><b>tablelist::delaySashPosUpdates</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The first three commands described in this reference page are designed to
  be used in binding scripts associated with the binding tags whose names are
  returned by the <code><b><a href=
  "tablelistWidget.html#bodytag">bodytag</a></b></code> and <code><b><a href=
  "tablelistWidget.html#labeltag">labeltag</a></b></code> subcommands of the
  Tcl command associated with a tablelist widget.&nbsp; The first two of these
  commands are also used in the default binding scripts associated with the
  binding tag <code><b>TablelistBody</b></code>.&nbsp; For details and examples
  see the sections <a href="tablelistWidget.html#body_bindings">DEFAULT AND
  INDIVIDUAL BINDINGS FOR THE TABLELIST BODY</a> and <a href=
  "tablelistWidget.html#label_bindings">DEFAULT AND INDIVIDUAL BINDINGS FOR THE
  HEADER LABELS</a>.</p>

  <p>The last command is related to the default binding scripts for Tk core
  panedwindow and ttk::panedwindow widgets.&nbsp; It can be used to control the
  frequency of the sash position updates, which might be necessary to eliminate
  some artifacts caused by dragging a sash if one or more of the panes contains
  a tablelist widget with embedded images.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="convEventFields">The <code><b>tablelist::convEventFields</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::convEventFields</code> &ndash; Convert event fields
    relative to a descendant of a tablelist widget</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::convEventFields</b> <i>descendantPathName</i> <i>x</i> <i>y</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command gets the path name of a tablelist widget and the x and y
    coordinates relative to the latter from the path name
    <code><i>descendantPathName</i></code> of one of its descendants and from
    the x and y coordinates <code><i>x</i></code>, <code><i>y</i></code>
    relative to this descendant.&nbsp; The command returns these values as the
    components of a list consisting of three elements.</dd>

    <dd class="tm">
      In a binding script, the descendant widget corresponds to the event field
      <code><b>%W</b></code>, which can be the tablelist's body, one of the
      separator frames, a label widget displaying an embedded image, or (a
      descendant of) an embedded window.&nbsp; It can also be a header label or
      an additional widget placed by Tablelist into a header label for
      displaying a header image or a sort arrow.&nbsp; Likewise, the arguments
      <code><i>x</i></code> and <code><i>y</i></code> correspond to the event
      fields <code><b>%x</b></code> and <code><b>%y</b></code>.&nbsp; The three
      elements of the list returned by the command are usually assigned to the
      help variables <code><b>tablelist::W</b></code>,
      <code><b>tablelist::x</b></code>, and <code><b>tablelist::y</b></code>,
      by using the statement

      <blockquote>
        <pre>
foreach {tablelist::W tablelist::x tablelist::y} \
    [tablelist::convEventFields %W %x %y] {}
</pre>
      </blockquote>
    </dd>

    <dt><b>KEYWORDS</b></dt>

    <dd>tablelist, event fields, binding script</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getTablelistPath">The <code><b>tablelist::getTablelistPath</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getTablelistPath</code> &ndash; Get the path name of a
    tablelist widget from the path name of one of its descendants</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getTablelistPath</b> <i>descendantPathName</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command gets the path name of a tablelist widget from the path
    name <code><i>descendantPathName</i></code> of one of its descendants.</dd>

    <dd class="tm">In a binding script, the descendant widget corresponds to
    the event field <code><b>%W</b></code>, which can be the tablelist's body,
    one of the separator frames, a label widget displaying an embedded image,
    or (a descendant of) an embedded window.&nbsp; It can also be a header
    label or an additional widget placed by Tablelist into a header label for
    displaying a header image or a sort arrow.&nbsp; The return value is often
    assigned to the help variable <code><b>tablelist::W</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, path name, binding script</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getTablelistColumn">The
  <code><b>tablelist::getTablelistColumn</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getTablelistColumn</code> &ndash; Get the column
    number from the path name of a tablelist header label</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getTablelistColumn</b> <i>headerLabelPathName</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command gets the column number from the path name
    <code><i>headerLabelPathName</i></code> of a tablelist header label or of
    an additional widget placed by Tablelist into a header label for displaying
    a header image or a sort arrow.</dd>

    <dd class="tm">In a binding script, the command argument corresponds to the
    event field <code><b>%W</b></code>.&nbsp; The return value is often
    assigned to the help variable <code><b>tablelist::col</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, path name, binding script</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="delaySashPosUpdates">The
  <code><b>tablelist::delaySashPosUpdates</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::delaySashPosUpdates</code> &ndash; Set a delay for the
    panedwindow sash position updates</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::delaySashPosUpdates</b> <i>panedwindowPathName</i> <i>ms</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command sets a delay for the updates of the sash position caused
    by dragging a sash of the panedwindow widget specified by the first
    argument, which must be the path name of a Tk core panedwindow or
    ttk::panedwindow widget.&nbsp; <code><i>ms</i></code> must be an integer
    giving the delay in milliseconds.&nbsp; If this number is non-negative then
    the sash position updates via&nbsp <code><b>sash place ...</b></code>&nbsp;
    (for a Tk core panedwindow widget) or&nbsp; <code><b>sashpos
    ...</b></code>&nbsp; (for a ttk::panedwindow widget) will be scheduled for
    execution <code><i>ms</i></code> milliseconds later, in such a way that,
    until the time for an already scheduled update expires, new drag events
    won't schedule new update operations (only their data will be
    remembered).&nbsp; This will reduce the frequency of the sash position
    updates caused by dragging a sash of the specified widget, depending on the
    value of <code><i>ms</i></code>.&nbsp; If this number is negative then any
    dragging of a sash of the specified widget will immediately trigger an
    update of the sash position, as implemented in the default binding scripts
    for Tk core panedwindow and ttk::panedwindow widgets.</dd>

    <dd class="tm">This command can be used to control the frequency of the
    sash position updates for a given panedwindow widget, which might be
    necessary to eliminate some artifacts caused by dragging a sash if one or
    more of the panes contains a tablelist widget with embedded images.&nbsp;
    The value of <code><i>ms</i></code> (typically a number between 10 and 100)
    is application- and platform-specific (on Windows and Mac OS X Aqua you
    will need a higher value than on X11).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>panedwindow, tablelist, path name, binding script</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistColSort.html.



































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Commands for Interactive Sorting by One or More Columns</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, sort, column, widget">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Commands for Interactive Sorting by One or More Columns</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#sortByColumn">The <code><b>tablelist::sortByColumn</b></code>
    Command</a></li>

    <li><a href="#addToSortColumns">The
    <code><b>tablelist::addToSortColumns</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The commands described in this reference page enable the user to sort the
  items of a tablelist widget based on one or more of its columns, with the aid
  of the left mouse button.</p>

  <p>If the <code><b><a href=
  "#sortByColumn">tablelist::sortByColumn</a></b></code> command was specified
  as the value of the <code><b><a href=
  "tablelistWidget.html#labelcommand">-labelcommand</a></b></code>
  configuration option, then by pressing mouse button 1 over one of the header
  labels and later releasing it over the same label, the items will be sorted
  based on the elements of the corresponding column.</p>

  <p>If the <code><b><a href=
  "#addToSortColumns">tablelist::addToSortColumns</a></b></code> command was
  specified as the value of the <code><b><a href=
  "tablelistWidget.html#labelcommand2">-labelcommand2</a></b></code>
  configuration option, then by pressing mouse button 1 together with the
  <code>Shift</code> key over one of the header labels and later releasing it
  over the same label, the corresponding column will be appended to the list of
  sort columns, or (if it was already contained in that list) the corresponding
  sort order will be toggled; in both cases, the items will be sorted based on
  the updated lists of sort columns and sort orders.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="sortByColumn">The <code><b>tablelist::sortByColumn</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::sortByColumn</code> &ndash; Sort the items of a
    tablelist widget based on one of its columns</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::sortByColumn</b> <i>pathName</i> <i>columnIndex</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command sorts the items of the <a href=
    "tablelistWidget.html">tablelist</a> widget <code><i>pathName</i></code>
    based on the elements of the column specified by
    <code><i>columnIndex</i></code>.&nbsp; This is done by invoking the
    <code><b><a href=
    "tablelistWidget.html#sortbycolumn">sortbycolumn</a></b></code> subcommand
    of the Tcl command associated with the given tablelist widget.&nbsp; If the
    items were last sorted in increasing order, based on the same column given
    by <code><i>columnIndex</i></code>, and no subsequent invocation of the
    <code><b><a href=
    "tablelistWidget.html#resetsortinfo">resetsortinfo</a></b></code>
    subcommand was made, then the last argument passed to
    <code><b>sortbycolumn</b></code> will be <code><b>-decreasing</b></code>,
    otherwise <code><b>-increasing</b></code>.</dd>

    <dd class="tm">After sorting the items, the virtual event
    <code><b>&lt;&lt;TablelistColumnSorted&gt;&gt;</b></code> is
    generated.&nbsp; For Tk versions 8.5 or higher, this virtual event is
    generated with its <code><b>-data</b></code> option set to a list
    consisting of the numerical column index and the sort order
    (<code><b>decreasing</b></code> or <code><b>increasing</b></code>).&nbsp;
    The command returns the sort order, as <code><b>decreasing</b></code> or
    <code><b>increasing</b></code>.</dd>

    <dd class="tm">If the specified column's <code><b><a href=
    "tablelistWidget.html#col_showlinenumbers">-showlinenumbers</a></b></code>
    option has been set to true, then the actions described above are not
    performed and the return value is an empty string.</dd>

    <dd class="tm"><code><b>tablelist::sortByColumn</b></code> is usually
    specified as the value of the <code><b><a href=
    "tablelistWidget.html#labelcommand">-labelcommand</a></b></code>
    configuration option for a tablelist widget.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, sort, column, widget</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="addToSortColumns">The <code><b>tablelist::addToSortColumns</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addToSortColumns</code> &ndash; Add a column index to
    the list of sort columns and perform the multi-column sorting</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addToSortColumns</b> <i>pathName</i> <i>columnIndex</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command adds the column index specified by
    <code><i>columnIndex</i></code> to the list of sort columns of the <a href=
    "tablelistWidget.html">tablelist</a> widget <code><i>pathName</i></code>
    and sorts the items based on the elements of the columns indicated by the
    modified list.&nbsp; This is done by invoking the <code><b><a href=
    "tablelistWidget.html#sortbycolumnlist">sortbycolumnlist</a></b></code>
    subcommand of the Tcl command associated with the given tablelist
    widget.&nbsp; The two arguments passed to
    <code><b>sortbycolumnlist</b></code> are built as follows: (a) if the given
    column index is already contained in the widget's list of sort columns
    (returned by the <code><b><a href=
    "tablelistWidget.html#sortcolumnlist">sortcolumnlist</a></b></code>
    subcommand) then this list is left unchanged and the sort order list
    (returned by the <code><b><a href=
    "tablelistWidget.html#sortorderlist">sortorderlist</a></b></code>
    subcommand) is updated by toggling its corresponding element from
    <code><b>increasing</b></code> to <code><b>decreasing</b></code> and
    vice-versa; (b) otherwise the column index is appended to the list of sort
    columns and the value <code><b>increasing</b></code> is appended to the
    list of sort orders.</dd>

    <dd class="tm">After sorting the items by passing the two updated lists to
    the <code><b>sortbycolumnlist</b></code> subcommand, the virtual event
    <code><b>&lt;&lt;TablelistColumnsSorted&gt;&gt;</b></code> (note the plural
    form!) is generated.&nbsp; For Tk versions 8.5 or higher, this virtual
    event is generated with its <code><b>-data</b></code> option set to a list
    consisting of the two above-mentioned updated lists passed to
    <code><b>sortbycolumnlist</b></code> as arguments.&nbsp; The command
    returns the new sort order corresponding to the given column, as
    <code><b>decreasing</b></code> or <code><b>increasing</b></code>.</dd>

    <dd class="tm">If the specified column's <code><b><a href=
    "tablelistWidget.html#col_showlinenumbers">-showlinenumbers</a></b></code>
    option has been set to true, then the actions described above are not
    performed and the return value is an empty string.</dd>

    <dd class="tm"><code><b>tablelist::addToSortColumns</b></code> is usually
    specified as the value of the <code><b><a href=
    "tablelistWidget.html#labelcommand2">-labelcommand2</a></b></code>
    configuration option for a tablelist widget.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, sort, column list, widget</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistCombobox.html.



















































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the combobox Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, combobox">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the combobox Package</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#combobox">The
    <code><b>tablelist::addOakleyCombobox</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>Bryan Oakley's combobox package is a library extension for Tcl/Tk versions
  8.0 or higher, written in pure Tcl/Tk code.&nbsp; Its download location
  is</p>

  <blockquote>
    <address>
      <a href=
      "http://www1.clearlight.com/~oakley/tcl/combobox">http://www1.clearlight.com/~oakley/tcl/combobox</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the combobox
  widget implemented in the package mentioned above.&nbsp; The steps needed for
  using this widget for editing the cells of a given column are as follows:</p>

  <ol>
    <li>Register the combobox widget for interactive cell editing by invoking
    the <code><b><a href=
    "#combobox">tablelist::addOakleyCombobox</a></b></code> command described
    below.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="combobox">The <code><b>tablelist::addOakleyCombobox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addOakleyCombobox</code> &ndash; Register Bryan
    Oakley's combobox widget for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addOakleyCombobox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers Bryan Oakley's combobox widget for interactive
    cell editing in tablelist widgets.&nbsp; The optional argument specifies
    the name to be used for the combobox widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>combobox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded combobox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the combobox non-editable or define
    validations for its entry child (whose path name can be obtained by
    invoking the tablelist widget's <code><b><a href=
    "tablelistWidget.html#entrypath">entrypath</a></b></code> subcommand, or by
    appending <code><b>.entry</b></code> to the path name of the combobox
    widget, or, if using combobox version 2.3 or later, with the aid of the
    combobox widget's&nbsp; <code><b>subwidget entry</b></code>&nbsp;
    subcommand), as well as for populating its listbox component (by using the
    combobox widget's&nbsp; <code><b>list insert</b></code>&nbsp;
    subcommand).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, combobox</dd>
  </dl>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistCtext.html.













































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the ctext Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, ctext">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the ctext Package</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#ctext">The <code><b>tablelist::addCtext</b></code>
    Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>George Peter Staplin's ctext package is a library extension for Tcl/Tk
  versions 8.0 or higher, written in pure Tcl/Tk code.&nbsp; It is part of
  tklib, which has the address</p>

  <blockquote>
    <address>
      <a href="http://core.tcl.tk/tklib">http://core.tcl.tk/tklib</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the ctext
  widget implemented in the package mentioned above.&nbsp; The steps needed for
  using this widget for editing the cells of a given column are as follows:</p>

  <ol>
    <li>Register the ctext widget for interactive cell editing by invoking the
    <code><b><a href="#ctext">tablelist::addCtext</a></b></code> command
    described below.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="ctext">The <code><b>tablelist::addCtext</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addCtext</code> &ndash; Register the ctext widget for
    interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addCtext</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the ctext widget for interactive cell editing in
    tablelist widgets.&nbsp; The optional argument specifies the name to be
    used for the ctext widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ctext</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded ctext widget used for interactive
    cell editing will be created with its <code><b>-padx</b></code> and
    <code><b>-pady</b></code> options set to <code>2</code>, its
    <code><b>-wrap</b></code> option set to <code><b>none</b></code>, and its
    initial height set to the number of lines contained in it.&nbsp; There is,
    however, an exception from this rule:&nbsp; If the <code><b><a href=
    "tablelistWidget.html#col_wrap">-wrap</a></b></code> option of the cell's
    column was set to true and Tk version 8.5 or higher is being used, then the
    ctext widget's <code><b>-wrap</b></code> option will be set to
    <code><b>word</b></code> and its initial height will equal the number of
    <i>display</i> lines (taking into account the line wraps) contained in
    it.&nbsp; You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to override the initial settings according
    to your needs.</dd>

    <dd class="tm">If the ctext widget's <code><b>-wrap</b></code> option was
    set to <code><b>word</b></code> or <code><b>char</b></code> (either by
    Tablelist or from within the above-mentioned script) and Tk version 8.5 or
    higher is being used, then, whenever its width changes (e.g., due to
    interactive column resizing), its height will be set automatically to the
    number of display lines contained in it.&nbsp; (The number of display lines
    is retrieved with the aid of the&nbsp; <code><b>count
    -displaylines</b></code>&nbsp; ctext widget subcommand, introduced in Tk
    8.5.)</dd>

    <dd class="tm">If the widget callback package Wcb was loaded into the
    interpreter (via&nbsp; <code><b>package require Wcb</b></code>&nbsp;
    or&nbsp; <code><b>package require wcb</b></code>)&nbsp; then the ctext
    widget's height will be updated automatically whenever text is inserted
    into or deleted from it, which makes the editing much more
    user-friendly.&nbsp; This is achieved by using an appropriately defined
    after-<code><b>insert</b></code> and after-<code><b>delete</b></code>
    callback for the edit window.&nbsp; You can use the script corresponding to
    the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define further callbacks for the ctext
    widget.&nbsp; (The above-mentioned callback is created via
    <code><b>wcb::cbappend</b></code>, <i>after</i> returning from that
    script.)</dd>

    <dd class="tm">The <code>Tab</code> key is reserved for navigation between
    the editable cells, but the user can insert a tabulator character into the
    ctext widget by pressing <code>Control-i</code>.</dd>

    <dd class="tm">Unlike in the case of the other widgets used for interactive
    cell editing (except the Tk core text widget), the <code>Return</code> and
    <code>KP_Enter</code> keys insert a newline character into the ctext
    widget.&nbsp; <code>Control-j</code> can also be used for inserting a
    newline.&nbsp; <code>Control-Return</code> and
    <code>Control-KP_Enter</code> terminate the editing and destroy the edit
    window.</dd>

    <dd class="tm"><code>Control-Home</code> and <code>Control-End</code> have
    their well-known text widget-specific bindings, just like
    <code>Meta-&lt;</code> and <code>Meta-&gt;</code> if
    <code><b>tk_strictMotif</b></code> is false.&nbsp; Again, this is different
    from the behavior of the other widgets used for interactive cell editing
    (except the Tk core text widget).&nbsp; For jumping into the first/last
    editable cell, the user can press
    <code>Alt-Home</code>/<code>Alt-End</code> or
    <code>Meta-Home</code>/<code>Meta-End</code>
    (<code>Command-Home</code>/<code>Command-End</code> on Mac OS Classic and
    Mac OS X Aqua).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, ctext</dd>
  </dl>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistIwidgets.html.





































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the Iwidgets Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, Iwidgets">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the Iwidgets Package</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#entryfield">The
    <code><b>tablelist::addIncrEntryfield</b></code> Command</a></li>

    <li><a href="#dateTime">The
    <code><b>tablelist::addIncrDateTimeWidget</b></code> Command</a></li>

    <li><a href="#spinner">The <code><b>tablelist::addIncrSpinner</b></code>
    Command</a></li>

    <li><a href="#spinint">The <code><b>tablelist::addIncrSpinint</b></code>
    Command</a></li>

    <li><a href="#combobox">The <code><b>tablelist::addIncrCombobox</b></code>
    Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The Iwidgets package (also known as [incr Widgets]) is a library extension
  for Tcl/Tk versions 8.0 or higher, written in pure Tcl/Tk code.&nbsp; It
  requires the compiled packages Itcl and Itk (also known as [incr Tcl] and
  [incr Tk], respectively).&nbsp; The download location of these three library
  packages is</p>

  <blockquote>
    <address>
      <a href=
      "http://sourceforge.net/projects/incrtcl/files">http://sourceforge.net/projects/incrtcl/files</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the
  entryfield, datefield, dateentry, timefield, timeentry, spinner, spinint, and
  combobox widgets from the Iwidgets package.&nbsp; The steps needed for using
  one of these widgets for editing the cells of a given column are as
  follows:</p>

  <ol>
    <li>Register the desired widget for interactive cell editing by invoking
    one of the commands described in this reference page.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="entryfield">The <code><b>tablelist::addIncrEntryfield</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrEntryfield</code> &ndash; Register the
    entryfield widget from the Iwidgets package for interactive cell
    editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrEntryfield</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the entryfield widget from the Iwidgets package
    for interactive cell editing in tablelist widgets.&nbsp; The optional
    argument specifies the name to be used for the entryfield widget as the
    value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>entryfield</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, entryfield</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="dateTime">The <code><b>tablelist::addIncrDateTimeWidget</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrDateTimeWidget</code> &ndash; Register the
    datefield, dateentry, timefield, or timeentry widget from the Iwidgets
    package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrDateTimeWidget</b> <b>datefield</b>|<b>dateentry</b>|<b>timefield</b>|<b>timeentry</b> ?<b>-seconds</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the datefield, dateentry, timefield, or
    timeentry widget from the Iwidgets package for interactive cell editing in
    tablelist widgets.&nbsp; If the <code><b>-seconds</b></code> argument is
    present then the <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the content of the embedded window used for interactive cell
    editing as an integer clock value (in seconds), otherwise as a
    string.&nbsp; Use this option for tablelist widgets whose internal list
    contains date or time information in seconds (displayed with the aid of
    commands given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The second optional argument specifies
    the name to be used for the datefield, dateentry, timefield, or timeentry
    widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>datefield</b></code>, <code><b>dateentry</b></code>,
    <code><b>timefield</b></code>, or <code><b>timeentry</b></code>, as given
    by the first argument.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">When editing a cell with the aid of the temporary embedded
    datefield, dateentry, timefield, or timeentry widget associated with the
    above <code><i>name</i></code>, you can use the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any of the widget's options, like
    <code><b>-gmt</b></code>, <code><b>-iq</b></code>, <code><b>-int</b></code>
    ("international" date format, supported by datefield and dateentry
    widgets), or <code><b>-format</b></code> (for timefield and timeentry
    widgets, with the values <code><b>civilian</b></code> and
    <code><b>military</b></code>).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, datefield, dateentry, timefield,
    timeentry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinner">The <code><b>tablelist::addIncrSpinner</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrSpinner</code> &ndash; Register the spinner
    widget from the Iwidgets package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrSpinner</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the spinner widget from the Iwidgets package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the spinner widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>spinner</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">When editing a cell with the aid of the temporary embedded
    spinner widget associated with the above <code><i>name</i></code>, you can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define validations for the widget or set
    any of its other options, like <code><b>-decrement</b></code> and
    <code><b>-increment</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, spinner</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinint">The <code><b>tablelist::addIncrSpinint</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrSpinint</code> &ndash; Register the spinint
    widget from the Iwidgets package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrSpinint</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the spinint widget from the Iwidgets package for
    interactive cell editing in tablelist widgets.&nbsp; The optional argument
    specifies the name to be used for the spinint widget as the value of the
    <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>spinint</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">When editing a cell with the aid of the temporary embedded
    spinint widget associated with the above <code><i>name</i></code>, you can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define validations for the widget or set
    any of its other options, like <code><b>-range</b></code>,
    <code><b>-step</b></code>, and <code><b>-wrap</b></code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, spinint</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="combobox">The <code><b>tablelist::addIncrCombobox</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIncrCombobox</code> &ndash; Register the combobox
    widget from the Iwidgets package for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIncrCombobox</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the dropdown-style combobox widget from the
    Iwidgets package for interactive cell editing in tablelist widgets.&nbsp;
    The optional argument specifies the name to be used for the combobox widget
    as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>combobox</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">The temporary embedded combobox widget associated with the
    above <code><i>name</i></code> will be created with its
    <code><b>-editable</b></code> option set to <code>1</code>.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to make the combobox non-editable or define
    validations for it, as well as for populating its listbox component (by
    using the combobox widget's&nbsp; <code><b>insert list</b></code>&nbsp;
    subcommand).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Iwidgets, combobox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistMentry.html.



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using the Mentry Package</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, Mentry">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using the Mentry Package</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#Date">The <code><b>tablelist::addDateMentry</b></code>
    Command</a></li>

    <li><a href="#Time">The <code><b>tablelist::addTimeMentry</b></code>
    Command</a></li>

    <li><a href="#DateTime">The
    <code><b>tablelist::addDateTimeMentry</b></code> Command</a></li>

    <li><a href="#FixedPoint">The
    <code><b>tablelist::addFixedPointMentry</b></code> Command</a></li>

    <li><a href="#IPAddr">The <code><b>tablelist::addIPAddrMentry</b></code>
    Command</a></li>

    <li><a href="#IPv6Addr">The
    <code><b>tablelist::addIPv6AddrMentry</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The multi-entry package Mentry is a library extension for Tcl/Tk versions
  8.0 or higher, written in pure Tcl/Tk code.&nbsp; Its download location
  is</p>

  <blockquote>
    <address>
      <a href="http://www.nemethi.de">http://www.nemethi.de</a>
    </address>
  </blockquote>

  <p>Starting with version 3.0, the Mentry distribution provides not only the
  package Mentry, but also its tile-based equivalent Mentry_tile, which enables
  the theme-specific appearance of mentry widgets; this package requires Tcl/Tk
  8.4 or higher and tile 0.6 or higher.</p>

  <p>Tablelist supports interactive cell editing with the aid of the mentry
  widgets of type <code>"Date"</code>, <code>"Time"</code>,
  <code>"DateTime</code>, <code>"FixedPoint"</code>, <code>"IPAddr"</code>, and
  <code>"IPv6Addr"</code>.&nbsp; The steps needed for using one of these
  widgets for editing the cells of a given column are as follows:</p>

  <ol>
    <li>Register the desired widget for interactive cell editing by invoking
    one of the commands described in this reference page.</li>

    <li class="tm">Use the tablelist widget's <code><b><a href=
    "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
    subcommand to set the given column's <code><b><a href=
    "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
    and its <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
    the value returned by the command mentioned above.&nbsp; (These options are
    supported at cell level, too, with the aid of the <code><b><a href=
    "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
    subcommand.)</li>
  </ol>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="Date">The <code><b>tablelist::addDateMentry</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addDateMentry</code> &ndash; Register the mentry
    widget of type <code>"Date"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addDateMentry</b> <i>format separator</i> ?<b>-gmt</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::dateMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>format</i></code> and
    <code><i>separator</i></code> arguments have the same meanings as in the
    <code><b>mentry::dateMentry</b></code> command.&nbsp; If the
    <code><b>-gmt</b></code> argument is present then both the internal clock
    value and its external date representation in the mentry widget will be
    viewed as Greenwich Mean Time, otherwise as local time.&nbsp; The second
    optional argument specifies the name to be used for the mentry widget as
    the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>dateMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain as
    internal cell values date information in seconds (displayed with the aid of
    a command given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the content of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getClockVal</b></code>
    command.&nbsp; The value returned by this command (a clock value in seconds
    or one of the error strings <code>"EMPTY"</code>, <code>"BAD"</code>,
    <code>"BAD_DATE"</code>, or <code>"BAD_YEAR"</code>) will be passed to the
    script corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is one of the above error strings then the script should reject
    the mentry's content by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, date</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="Time">The <code><b>tablelist::addTimeMentry</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addTimeMentry</code> &ndash; Register the mentry
    widget of type <code>"Time"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addTimeMentry</b> <i>format separator</i> ?<b>-gmt</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::timeMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>format</i></code> and
    <code><i>separator</i></code> arguments have the same meanings as in the
    <code><b>mentry::timeMentry</b></code> command.&nbsp; If the
    <code><b>-gmt</b></code> argument is present then both the internal clock
    value and its external time representation in the mentry widget will be
    viewed as Greenwich Mean Time, otherwise as local time.&nbsp; The second
    optional argument specifies the name to be used for the mentry widget as
    the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>timeMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain as
    internal cell values time information in seconds (displayed with the aid of
    a command given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the content of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getClockVal</b></code>
    command.&nbsp; The value returned by this command (a clock value in seconds
    or one of the error strings <code>"EMPTY"</code> or <code>"BAD"</code>)
    will be passed to the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is one of the above error strings then the script should reject
    the mentry's content by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, time</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="DateTime">The <code><b>tablelist::addDateTimeMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addDateTimeMentry</code> &ndash; Register the mentry
    widget of type <code>"DateTime"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addDateTimeMentry</b> <i>format dateSeparator timeSeparator</i> ?<b>-gmt</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::dateTimeMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>format</i></code>,
    <code><i>dateSeparator</i></code>, and <code><i>timeSeparator</i></code>
    arguments have the same meanings as in the
    <code><b>mentry::dateTimeMentry</b></code> command.&nbsp; If the
    <code><b>-gmt</b></code> argument is present then both the internal clock
    value and its external date &amp; time representation in the mentry widget
    will be viewed as Greenwich Mean Time, otherwise as local time.&nbsp; The
    second optional argument specifies the name to be used for the mentry
    widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>dateTimeMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain as
    internal cell values date &amp; time information in seconds (displayed with
    the aid of a command given by the <code><b><a href=
    "tablelistWidget.html#col_formatcommand">-formatcommand</a></b></code>
    column configuration option).&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the content of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getClockVal</b></code>
    command.&nbsp; The value returned by this command (a clock value in seconds
    or one of the error strings <code>"EMPTY"</code>, <code>"BAD"</code>,
    <code>"BAD_DATE"</code>, or <code>"BAD_YEAR"</code>) will be passed to the
    script corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is one of the above error strings then the script should reject
    the mentry's content by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, date, time</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="FixedPoint">The <code><b>tablelist::addFixedPointMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addFixedPointMentry</code> &ndash; Register the mentry
    widget of type <code>"FixedPoint"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addFixedPointMentry</b> <i>count1 count2</i> ?<b>-comma</b>? ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::fixedPointMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The <code><i>count1</i></code>, <code><i>count2</i></code>,
    and <code><i>-comma</i></code> arguments have the same meanings as in the
    <code><b>mentry::fixedPointMentry</b></code> command.&nbsp; The second
    optional argument specifies the name to be used for the mentry widget as
    the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>fixedPointMentry_</b><i>count1</i><b>.</b><i>count2</i></code>
    (e.g., <code><b>fixedPointMentry_6.2</b></code>) or
    <code><b>fixedPointMentry_</b><i>count1</i><b>,</b><i>count2</i></code>
    (e.g., <code><b>fixedPointMentry_6,2</b></code>), depending on the presence
    of the optional <code><b>-comma</b></code> argument.&nbsp; The command
    returns its <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain
    real numbers as internal cell values.&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the content of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getReal</b></code> command.&nbsp;
    The value returned by this command (a real number or the error string
    <code>"EMPTY"</code>) will be passed to the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is the above error string then the script should reject the
    mentry's content by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, real number</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="IPAddr">The <code><b>tablelist::addIPAddrMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIPAddrMentry</code> &ndash; Register the mentry
    widget of type <code>"IPAddr"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIPAddrMentry</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::ipAddrMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The optional argument specifies the name to be used for the
    mentry widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ipAddrMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain IP
    addresses as internal cell values.&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the content of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getIPAddr</b></code>
    command.&nbsp; The value returned by this command (an IP address or the
    error string <code>"EMPTY"</code>) will be passed to the script
    corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is the above error string then the script should reject the
    mentry's content by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, IP address</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="IPv6Addr">The <code><b>tablelist::addIPv6AddrMentry</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::addIPv6AddrMentry</code> &ndash; Register the mentry
    widget of type <code>"IPv6Addr"</code> for interactive cell editing</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::addIPv6AddrMentry</b> ?<i>name</i>?
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command registers the widget created by the
    <code><b>mentry::ipv6AddrMentry</b></code> command from the Mentry (or
    Mentry_tile) package for interactive cell editing in tablelist
    widgets.&nbsp; The optional argument specifies the name to be used for the
    mentry widget as the value of the <code><b><a href=
    "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> column or
    cell configuration option.&nbsp; It may be any string that is different
    from the <a href="tablelistTkCore.html">Tk core</a> and <a href=
    "tablelistTile.html">tile</a> edit window names.&nbsp; The default is
    <code><b>ipv6AddrMentry</b></code>.&nbsp; The command returns its
    <code><i>name</i></code> argument.</dd>

    <dd class="tm">A tablelist column having the above <code><i>name</i></code>
    as the value of its <code><b>-editwindow</b></code> option must contain
    IPv6 addresses as internal cell values.&nbsp; The <code><b><a href=
    "tablelistWidget.html#finishediting">finishediting</a></b></code>
    subcommand of the Tcl command associated with the tablelist widget will
    retrieve the content of the embedded window used for interactive cell
    editing by invoking the <code><b>mentry::getIPv6Addr</b></code>
    command.&nbsp; The value returned by this command (an IPv6 address or the
    error string <code>"EMPTY"</code>) will be passed to the script
    corresponding to the <code><b><a href=
    "tablelistWidget.html#editendcommand">-editendcommand</a></b></code>
    tablelist configuration option (if any), as its last argument.&nbsp; If
    this value is the above error string then the script should reject the
    mentry's content by invoking the <code><b><a href=
    "tablelistWidget.html#rejectinput">rejectinput</a></b></code>
    subcommand.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, Mentry, IPv6 address</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistThemes.html.



























































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Commands Related to Tile Themes</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, theme, tile">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Commands Related to Tile Themes</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#setTheme">The <code><b>tablelist::setTheme</b></code>
    Command</a></li>

    <li><a href="#getCurrentTheme">The
    <code><b>tablelist::getCurrentTheme</b></code> Command</a></li>

    <li><a href="#getThemes">The <code><b>tablelist::getThemes</b></code>
    Command</a></li>

    <li><a href="#setThemeDefaults">The
    <code><b>tablelist::setThemeDefaults</b></code> Command</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The commands described in this reference page should only be invoked when
  using the package Tablelist_tile.&nbsp; They enable you to set and query the
  current theme, to retrieve a list of the available themes, and to make sure
  that your widgets will have a theme-specific appearance.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="setTheme">The <code><b>tablelist::setTheme</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::setTheme</code> &ndash; Set the current theme</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::setTheme</b> <i>theme</i>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command sets the current theme to <code><i>theme</i></code>,
    loading it if necessary.&nbsp; It is simply an alias for
    <code><b>ttk::setTheme</b></code> or <code><b>tile::setTheme</b></code>,
    depending on the tile version loaded into the interpreter.&nbsp; (The
    <code><b>tile::setTheme</b></code> command was renamed to
    <code><b>ttk::setTheme</b></code> in tile version 0.8.)</dd>

    <dd class="tm">Being just an alias for a tile library procedure, the
    <code><b>tablelist::setTheme</b></code> command does exactly the same as
    the original one: It loads the package implementing the given theme if
    needed, sets the theme to the specified one, and saves the latter in the
    variable <code><b>ttk::currentTheme</b></code> or
    <code><b>tile::currentTheme</b></code>, depending on the current tile
    version.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getCurrentTheme">The <code><b>tablelist::getCurrentTheme</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getCurrentTheme</code> &ndash; Get the current
    theme</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getCurrentTheme</b>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command returns the value of the variable
    <code><b>ttk::currentTheme</b></code> or
    <code><b>tile::currentTheme</b></code>, depending on the tile version
    loaded into the interpreter.&nbsp; (The namespace containing the variable
    <code><b>currentTheme</b></code> was changed in tile version 0.8 from
    <code><b>tile</b></code> to <code><b>ttk</b></code>.)</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="getThemes">The <code><b>tablelist::getThemes</b></code> Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::getThemes</code> &ndash; Get the themes registered in
    the package database</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::getThemes</b>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command returns a list of the themes registered in the package
    database.&nbsp; It is simply an alias for <code><b>ttk::themes</b></code>
    or <code><b>tile::availableThemes</b></code>, depending on the tile version
    loaded into the interpreter.&nbsp; (The
    <code><b>tile::availableThemes</b></code> command was renamed to
    <code><b>ttk::themes</b></code> in tile version 0.8.)</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="setThemeDefaults"><code><b>tablelist::setThemeDefaults</b></code>
  Command</h2>

  <dl>
    <dt><b>NAME</b></dt>

    <dd><code>tablelist::setThemeDefaults</code> &ndash; Set theme-specific
    default values of some tablelist configuration options</dd>

    <dt class="tm"><b>SYNOPSIS</b></dt>

    <dd>
      <pre>
<b>tablelist::setThemeDefaults</b>
</pre>
    </dd>

    <dt><b>DESCRIPTION</b></dt>

    <dd>This command populates the array
    <code><b>tablelist::themeDefaults</b></code> with theme-specific default
    values of a series of Tablelist configuration options.&nbsp; The array
    names are the command-line names of the options, and the corresponding
    array values are the default values of these configuration options for the
    currently set tile theme.</dd>

    <dd class="tm">The options whose names and values are written into the
    array <code><b>tablelist::themeDefaults</b></code> are:
    <code><b>-background</b></code>, <code><b>-foreground</b></code>,
    <code><b>-disabledforeground</b></code>,
    <code><b>-stripebackground</b></code>,
    <code><b>-selectbackground</b></code>,
    <code><b>-selectforeground</b></code>,
    <code><b>-selectborderwidth</b></code>, <code><b>-font</b></code>,
    <code><b>-labelforeground</b></code>, <code><b>-labelfont</b></code>,
    <code><b>-labelborderwidth</b></code>, <code><b>-labelpady</b></code>,
    <code><b>-arrowcolor</b></code>, <code><b>-arrowdisabledcolor</b></code>,
    <code><b>-arrowstyle</b></code>, and <code><b>-treestyle</b></code>.&nbsp;
    In addition, the command sets some other array elements to theme-specific
    default values of the background and foreground colors of the column labels
    in <code><b>normal</b></code>, <code><b>disabled</b></code>,
    <code><b>active</b></code>, and <code><b>pressed</b></code> states.&nbsp;
    (Tablelist needs the label colors for handling sort arrows and images with
    transparent background in the column labels.)</dd>

    <dd class="tm">The <code><b>tablelist::setThemeDefaults</b></code> command
    is invoked by Tablelist_tile automatically whenever a tablelist widget is
    createad or the <code><b>&lt;&lt;ThemeChanged&gt;&gt;</b></code> virtual
    event is received by a tablelist widget.&nbsp; In the latter case, the
    widget is reconfigured, using the new default values of those options that
    were not set explicitly to values different from the corresponding
    defaults.</dd>

    <dd class="tm">Besides being used by the Tablelist_tile code, this command
    can also be invoked in Tcl scripts, still before creating any tile-based
    tablelist widget.&nbsp; By calling it explicitly and using the values
    written by it into the array <code><b>tablelist::themeDefaults</b></code>,
    you can make sure that classical Tk widgets, e.g., listbox and text, will
    have a theme-specific appearance, just like the tile widgets.&nbsp; For
    example, you can add some common configuration options to the option
    database as follows:</dd>

    <dd>
      <blockquote>
        <pre>
tablelist::setThemeDefaults
if {$tile::currentTheme eq "aqua"} {
    option add *Listbox.selectBackground \
               $tablelist::themeDefaults(-selectbackground)
    option add *Listbox.selectForeground \
               $tablelist::themeDefaults(-selectforeground)
} else {
    option add *selectBackground  $tablelist::themeDefaults(-selectbackground)
    option add *selectForeground  $tablelist::themeDefaults(-selectforeground)
}
option add *selectBorderWidth     $tablelist::themeDefaults(-selectborderwidth)
</pre>
      </blockquote>
    </dd>

    <dt><b>KEYWORDS</b></dt>

    <dd>tablelist, theme, tile</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistTile.html.















































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using Tile Widgets</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, tile">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using Tile Widgets</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#entry">Interactive Cell Editing Using the tile entry
    Widget</a></li>

    <li><a href="#spinbox">Interactive Cell Editing Using the tile spinbox
    Widget</a></li>

    <li><a href="#combobox">Interactive Cell Editing Using the tile combobox
    Widget</a></li>

    <li><a href="#checkbutton">Interactive Cell Editing Using the tile
    checkbutton Widget</a></li>

    <li><a href="#menubutton">Interactive Cell Editing Using the tile
    menubutton Widget</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>The tile theme engine is a compiled library extension for Tcl/Tk versions
  8.4 or higher.&nbsp; Beginning with Tk 8.5a6, tile is integrated into the Tk
  core.&nbsp; For earlier Tk versions it can be downloaded from the address</p>

  <blockquote>
    <address>
      <a href=
      "http://sourceforge.net/projects/tktable/files/tile/">http://sourceforge.net/projects/tktable//files/tile</a>
    </address>
  </blockquote>

  <p>Tablelist supports interactive cell editing with the aid of the tile
  entry, spinbox, combobox, checkbutton, and menubutton widgets, accessed as
  <code><b>ttk::entry</b></code>, <code><b>ttk::spinbox</b></code>,
  <code><b>ttk::combobox</b></code>, <code><b>ttk::checkbutton</b></code>, and
  <code><b>ttk::menubutton</b></code>, respectively.&nbsp; The fully-qualified
  names <code><b>::ttk::entry</b></code>, <code><b>::ttk::spinbox</b></code>,
  <code><b>::ttk::combobox</b></code>, <code><b>::ttk::checkbutton</b></code>,
  and <code><b>::ttk::menubutton</b></code> are also supported.&nbsp; The
  version of the tile package must be 0.6 or higher (the tile spinbox requires
  even tile 0.8.3 or later, or, alternatively, Tk 8.6 or later).&nbsp; These
  widgets are automatically registered for cell editing, hence the only action
  needed for using one of them for editing the cells of a given column is as
  follows:</p>

  <p>Use the tablelist widget's <code><b><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
  subcommand to set the given column's <code><b><a href=
  "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
  and its <code><b><a href=
  "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
  <code><b>ttk::entry</b></code>, <code><b>ttk::spinbox</b></code>,
  <code><b>ttk::combobox</b></code>, <code><b>ttk::checkbutton</b></code>, or
  <code><b>ttk::menubutton</b></code> (or to the corresponding fully-qualified
  name), respectively.&nbsp; (These options are supported at cell level, too,
  with the aid of the <code><b><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
  subcommand.)</p>

  <p>One known limitation of earlier tile versions was that the&nbsp;
  <code><b>(ttk::)style theme use</b></code>&nbsp; command could only be used
  to set the current theme, but not to retrieve it.&nbsp; For this reason,
  Tablelist makes use of the variable <code><b>ttk::currentTheme</b></code> or
  <code><b>tile::currentTheme</b></code> (depending on the tile version), which
  is set by the <code><b>ttk::setTheme</b></code> or
  <code><b>tile::setTheme</b></code> procedure.&nbsp; From this it follows that
  the tile widgets used for interactive cell editing will only be managed as
  expected if the platform-specific default theme is either left unchanged or
  replaced with another theme by invoking the procedure
  <code><b>ttk::setTheme</b></code> or <code><b>tile::setTheme</b></code>,
  depending on the current tile version.&nbsp; (See also the <code><b><a href=
  "tablelistThemes.html#setTheme">tablelist::setTheme</a></b></code>
  command.)</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="entry">Interactive Cell Editing Using the tile entry Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile entry widget used for interactive cell
    editing will be created with an explicitly set value for its
    <code><b>-style</b></code> option.&nbsp; Apart from its theme-specific
    appearance, it behaves just like its Tk core counterpart.</dd>

    <dd class="tm">If an application uses the tile entry widget for interactive
    cell editing and also the Wcb package (even if not for that widget), then
    the version of Wcb must be 3.1 or higher (because earlier Wcb releases
    didn't support any tile widgets).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, entry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinbox">Interactive Cell Editing Using the tile spinbox Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile spinbox widget used for interactive cell
    editing will be created with an explicitly set value for its
    <code><b>-style</b></code> option and with its <code><b>-state</b></code>
    option set to <code><b>normal</b></code>, which makes the widget
    editable.&nbsp; You can use the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set the state of the spinbox to
    <code><b>readonly</b></code> or define validations for it, as well as for
    setting its (range of) values and its <code><b>-wrap</b></code>
    option.&nbsp; Apart from its theme-specific appearance, it behaves just
    like its Tk core counterpart.</dd>

    <dd class="tm">If an application uses the tile spinbox widget for
    interactive cell editing and also the Wcb package (even if not for that
    widget), then the version of Wcb must be 3.2 or higher (because the support
    for the new tile spinbox widget was added to Wcb in its version 3.2).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, spinbox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="combobox">Interactive Cell Editing Using the tile combobox
  Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile combobox widget used for interactive cell
    editing will be created with an explicitly set value for its
    <code><b>-style</b></code> option and with its <code><b>-state</b></code>
    option set to <code><b>normal</b></code>, which makes the widget
    editable.&nbsp; You can use the script corresponding to the
    <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set the state of the combobox to
    <code><b>readonly</b></code> or define validations for it, as well as for
    populating its listbox component (with the aid of the combobox widget's
    <code><b>-values</b></code> option).</dd>

    <dd class="tm">If an application uses the tile combobox widget for
    interactive cell editing and also the Wcb package (even if not for that
    widget), then the version of Wcb must be 3.1 or higher (because earlier Wcb
    releases didn't support any tile widgets).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, combobox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="checkbutton">Interactive Cell Editing Using the tile checkbutton
  Widget.</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile checkbutton widget used for interactive
    cell editing will be created with explicitly set values for its
    <code><b>-style</b></code> and <code><b>-variable</b></code> options.&nbsp;
    You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other configuration options, like
    <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code>, according
    to the <i>internal</i> values of the cells.&nbsp; Since the default values
    of the <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code> tile
    checkbutton options are <code>0</code> and <code>1</code>, you don't need
    to change these options if the cells have the same internal values
    <code>0</code> and <code>1</code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, checkbutton</dd>
  </dl>
  <hr>

  <h2 id="menubutton">Interactive Cell Editing Using the tile menubutton
  Widget.</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded tile menubutton widget used for interactive cell
    editing will be created with explicitly set values for its
    <code><b>-style</b></code> and <code><b>-textvariable</b></code>
    options.&nbsp; In addition, a menu with its <code><b>-tearoff</b></code>
    option set to <code>0</code> and an appropriate script as the value of its
    <code><b>-postcommand</b></code> option is created and set as the value of
    the menubutton's <code><b>-menu</b></code> option.&nbsp; In an X11
    environment, the menu's appearance is adapted to that of the tablelist
    widget by setting its <code><b>-background</b></code>,
    <code><b>-foreground</b></code>, <code><b>-activebackground</b></code>,
    <code><b>-activeforeground</b></code>, and
    <code><b>-activeborderwidth</b></code> options to appropriate values.&nbsp;
    You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other options of the menubutton
    and/or its associated menu.&nbsp; You will, however, need this script in
    the first place for populating the menu, preferably with radiobutton
    entries.&nbsp; For every radiobutton entry added to the menu, the Tablelist
    implementation will make sure that its value (which can be specified by
    setting the entry's <code><b>-value</b></code> or
    <code><b>-label</b></code> option) will be displayed in the menubutton as
    its text when the entry is selected.&nbsp; (Tablelist achieves this by
    setting the menu entry's <code><b>-variable</b></code> option to the value
    of the menubutton's <code><b>-textvariable</b></code> option.)&nbsp; For
    menu entries of types other than radiobutton (e.g., for command entries) it
    is the responsibility of the application to make sure that the selected
    entry's text will be shown in the menubutton (for example, with the aid of
    the menu entry's <code><b>-command</b></code> option).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, tile, menubutton</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistTkCore.html.

































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<html>
<head>
  <title>Interactive Tablelist Cell Editing Using Tk Core Widgets</title>

  <meta name="Author" content="Csaba Nemethi">
  <meta name="Keywords" content="tablelist, editing, Tk core">

  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>

<body bgcolor="#FFFFFF">
  <div align="center">
    <h1>Interactive Tablelist Cell Editing Using Tk Core Widgets</h1>

    <h2>For Tablelist Version 6.0</h2>

    <h3>by</h3>

    <h2>Csaba Nemethi</h2>

    <address>
      <a href="mailto:csaba.nemethi@t-online.de">csaba.nemethi@t-online.de</a>
    </address>
  </div>
  <hr>

  <h2 id="contents">Contents</h2>

  <ul>
    <li><a href="#overview">Overview</a></li>

    <li><a href="#entry">Interactive Cell Editing Using the entry
    Widget</a></li>

    <li><a href="#text">Interactive Cell Editing Using the text Widget</a></li>

    <li><a href="#spinbox">Interactive Cell Editing Using the spinbox
    Widget</a></li>

    <li><a href="#checkbutton">Interactive Cell Editing Using the checkbutton
    Widget</a></li>

    <li><a href="#menubutton">Interactive Cell Editing Using the menubutton
    Widget</a></li>
  </ul>

  <div align="center">
    <p><a href="index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="overview">Overview</h2>

  <p>Tablelist supports interactive cell editing with the aid of the Tk core
  entry, text, spinbox, checkbutton, and menubutton widgets.&nbsp; These
  widgets are automatically registered for cell editing, hence the only action
  needed for using one of them for editing the cells of a given column is as
  follows:</p>

  <p>Use the tablelist widget's <code><b><a href=
  "tablelistWidget.html#columnconfigure">columnconfigure</a></b></code>
  subcommand to set the given column's <code><b><a href=
  "tablelistWidget.html#col_editable">-editable</a></b></code> option to true
  and its <code><b><a href=
  "tablelistWidget.html#col_editwindow">-editwindow</a></b></code> option to
  <code><b>entry</b></code>, <code><b>text</b></code>,
  <code><b>spinbox</b></code>, <code><b>checkbutton</b></code>, or
  <code><b>menubutton</b></code>, respectively.&nbsp; (These options are
  supported at cell level, too, with the aid of the <code><b><a href=
  "tablelistWidget.html#cellconfigure">cellconfigure</a></b></code>
  subcommand.)&nbsp; Since the default value of the
  <code><b>-editwindow</b></code> column configuration option is
  <code><b>entry</b></code>, it is not necessary to set it explicitly if the
  editing should take place with the aid of an embedded entry widget.</p>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="entry">Interactive Cell Editing Using the entry Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>As mentioned above, the interactive cell editing in a tablelist widget
    takes place per default with the aid of an embedded entry widget.&nbsp;
    Refer to the <a href="tablelistWidget.html#cell_editing">INTERACTIVE CELL
    EDITING</a> section of the reference page describing the
    <code><b>tablelist::tablelist</b></code> command for details on the editing
    process.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, entry</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="text">Interactive Cell Editing Using the text Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded text widget used for interactive cell editing
    will be created with its <code><b>-padx</b></code> and
    <code><b>-pady</b></code> options set to <code>2</code>, its
    <code><b>-wrap</b></code> option set to <code><b>none</b></code>, and its
    initial height set to the number of lines contained in it.&nbsp; There is,
    however, an exception from this rule:&nbsp; If the <code><b><a href=
    "tablelistWidget.html#col_wrap">-wrap</a></b></code> option of the cell's
    column was set to true and Tk version 8.5 or higher is being used, then the
    text widget's <code><b>-wrap</b></code> option will be set to
    <code><b>word</b></code> and its initial height will equal the number of
    <i>display</i> lines (taking into account the line wraps) contained in
    it.&nbsp; You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to override the initial settings according
    to your needs.</dd>

    <dd class="tm">If the text widget's <code><b>-wrap</b></code> option was
    set to <code><b>word</b></code> or <code><b>char</b></code> (either by
    Tablelist or from within the above-mentioned script) and Tk version 8.5 or
    higher is being used, then, whenever its width changes (e.g., due to
    interactive column resizing), its height will be set automatically to the
    number of display lines contained in it.&nbsp; (The number of display lines
    is retrieved with the aid of the&nbsp; <code><b>count
    -displaylines</b></code>&nbsp; text widget subcommand, introduced in Tk
    8.5.)</dd>

    <dd class="tm">If the widget callback package Wcb was loaded into the
    interpreter (via&nbsp; <code><b>package require Wcb</b></code>&nbsp;
    or&nbsp; <code><b>package require wcb</b></code>)&nbsp; then the text
    widget's height will be updated automatically whenever text is inserted
    into or deleted from it, which makes the editing much more
    user-friendly.&nbsp; This is achieved by using an appropriately defined
    after-<code><b>insert</b></code> and after-<code><b>delete</b></code>
    callback for the edit window.&nbsp; You can use the script corresponding to
    the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to define further callbacks for the text
    widget.&nbsp; (The above-mentioned callback is created via
    <code><b>wcb::cbappend</b></code>, <i>after</i> returning from that
    script.)</dd>

    <dd class="tm">The <code>Tab</code> key is reserved for navigation between
    the editable cells, but the user can insert a tabulator character into the
    text widget by pressing <code>Control-i</code>.</dd>

    <dd class="tm">Unlike in the case of the other widgets used for interactive
    cell editing, the <code>Return</code> and <code>KP_Enter</code> keys insert
    a newline character into the text widget.&nbsp; <code>Control-j</code> can
    also be used for inserting a newline.&nbsp; <code>Control-Return</code> and
    <code>Control-KP_Enter</code> terminate the editing and destroy the edit
    window.</dd>

    <dd class="tm"><code>Control-Home</code> and <code>Control-End</code> have
    their well-known text widget-specific bindings, just like
    <code>Meta-&lt;</code> and <code>Meta-&gt;</code> if
    <code><b>tk_strictMotif</b></code> is false.&nbsp; Again, this is different
    from the behavior of the other widgets used for interactive cell
    editing.&nbsp; For jumping into the first/last editable cell, the user can
    press <code>Alt-Home</code>/<code>Alt-End</code> or
    <code>Meta-Home</code>/<code>Meta-End</code>
    (<code>Command-Home</code>/<code>Command-End</code> on Mac OS Classic and
    Mac OS X Aqua).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, text</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="spinbox">Interactive Cell Editing Using the spinbox Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded spinbox widget used for interactive cell editing
    will be created with its <code><b>-state</b></code> option set to
    <code><b>normal</b></code>, which makes the widget editable.&nbsp; You can
    use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set the state of the spinbox to
    <code><b>readonly</b></code> or define validations for it, as well as for
    setting its (range of) values and its <code><b>-wrap</b></code>
    option.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, spinbox</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
  <hr>

  <h2 id="checkbutton">Interactive Cell Editing Using the checkbutton
  Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>On Windows, Mac OS Classic, and Mac OS X Aqua the temporary embedded
    checkbutton widget used for interactive cell editing will be created with
    explicitly set values for its <code><b>-borderwidth</b></code>,
    <code><b>-font</b></code>, <code><b>-padx</b></code>,
    <code><b>-pady</b></code>, and <code><b>-variable</b></code> options.&nbsp;
    In an X11 environment it will be created with explicitly set values for its
    <code><b>-borderwidth</b></code>, <code><b>-indicatoron</b></code>,
    <code><b>-image</b></code>, <code><b>-selectimage</b></code>,
    <code><b>-selectcolor</b></code>, and <code><b>-variable</b></code>
    options.&nbsp; You can use the script corresponding to the
    <code><b><a href="tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other options, like
    <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code>, according
    to the <i>internal</i> values of the cells.&nbsp; Since the default values
    of the <code><b>-offvalue</b></code> and <code><b>-onvalue</b></code>
    checkbutton options are <code>0</code> and <code>1</code>, you don't need
    to change these options if the cells have the same internal values
    <code>0</code> and <code>1</code>.</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, checkbutton</dd>
  </dl>
  <hr>

  <h2 id="menubutton">Interactive Cell Editing Using the menubutton Widget</h2>

  <dl>
    <dt><b>DESCRIPTION</b></dt>

    <dd>The temporary embedded menubutton widget used for interactive cell
    editing will be created with explicitly set values for its
    <code><b>-anchor</b></code>, <code><b>-indicatoron</b></code>,
    <code><b>-justify</b></code>, <code><b>-padx</b></code>,
    <code><b>-pady</b></code>, <code><b>-relief</b></code>, and
    <code><b>-textvariable</b></code> options.&nbsp; In addition, a menu with
    its <code><b>-tearoff</b></code> option set to <code>0</code> and an
    appropriate script as the value of its <code><b>-postcommand</b></code>
    option is created and set as the value of the menubutton's
    <code><b>-menu</b></code> option.&nbsp; In an X11 environment, the menu's
    appearance is adapted to that of the tablelist widget by setting its
    <code><b>-background</b></code>, <code><b>-foreground</b></code>,
    <code><b>-activebackground</b></code>,
    <code><b>-activeforeground</b></code>, and
    <code><b>-activeborderwidth</b></code> options to appropriate values.&nbsp;
    You can use the script corresponding to the <code><b><a href=
    "tablelistWidget.html#editstartcommand">-editstartcommand</a></b></code>
    tablelist configuration option to set any other options of the menubutton
    and/or its associated menu.&nbsp; You will, however, need this script in
    the first place for populating the menu, preferably with radiobutton
    entries.&nbsp; For every radiobutton entry added to the menu, the Tablelist
    implementation will make sure that its value (which can be specified by
    setting the entry's <code><b>-value</b></code> or
    <code><b>-label</b></code> option) will be displayed in the menubutton as
    its text when the entry is selected.&nbsp; (Tablelist achieves this by
    setting the menu entry's <code><b>-variable</b></code> option to the value
    of the menubutton's <code><b>-textvariable</b></code> option.)&nbsp; For
    menu entries of types other than radiobutton (e.g., for command entries) it
    is the responsibility of the application to make sure that the selected
    entry's text will be shown in the menubutton (for example, with the aid of
    the menu entry's <code><b>-command</b></code> option).</dd>

    <dt class="tm"><b>KEYWORDS</b></dt>

    <dd>tablelist, editing, menubutton</dd>
  </dl>

  <div align="center">
    <p><a href="#contents">Contents</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href=
    "index.html">Start page</a></p>
  </div>
</body>
</html>

Added libs/tablelist6.0/doc/tablelistWidget.html.

more than 10,000 changes

Added libs/tablelist6.0/doc/tileWidgets.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/ubuntu.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/ubuntu2.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/ubuntu3.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/ubuntuMate.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/vistaAero.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/vistaClassic.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/win10.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/win7Aero.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/win7Classic.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/winnative.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/winxpBlue.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/winxpOlive.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/winxpSilver.png.

cannot compute difference between binary files

Added libs/tablelist6.0/doc/yuyo.png.

cannot compute difference between binary files

Added libs/tablelist6.0/pkgIndex.tcl.

























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Tablelist and Tablelist_tile package index file.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Regular packages:
#
package ifneeded tablelist         6.0 \
	[list source [file join $dir tablelist.tcl]]
package ifneeded tablelist_tile    6.0 \
	[list source [file join $dir tablelist_tile.tcl]]

#
# Aliases:
#
package ifneeded Tablelist         6.0 \
	[list package require -exact tablelist	    6.0]
package ifneeded Tablelist_tile    6.0 \
	[list package require -exact tablelist_tile 6.0]

#
# Code common to all packages:
#
package ifneeded tablelist::common 6.0 \
        "namespace eval ::tablelist { proc DIR {} {return [list $dir]} } ;\
	 source [list [file join $dir tablelistPublic.tcl]]"

Added libs/tablelist6.0/scripts/mwutil.tcl.





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
#==============================================================================
# Contains utility procedures for mega-widgets.
#
# Structure of the module:
#   - Namespace initialization
#   - Public utility procedures
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tcl 8
package require Tk  8

#
# Namespace initialization
# ========================
#

namespace eval mwutil {
    #
    # Public variables:
    #
    variable version	2.9
    variable library	[file dirname [info script]]

    #
    # Public procedures:
    #
    namespace export	wrongNumArgs getAncestorByClass convEventFields \
			defineKeyNav processTraversal focusNext focusPrev \
			configureWidget fullConfigOpt fullOpt enumOpts \
			configureSubCmd attribSubCmd hasattribSubCmd \
			unsetattribSubCmd getScrollInfo

    #
    # Make modified versions of the procedures tk_focusNext and
    # tk_focusPrev, to be invoked in the processTraversal command
    #
    proc makeFocusProcs {} {
	#
	# Enforce the evaluation of the Tk library file "focus.tcl"
	#
	tk_focusNext .

	#
	# Build the procedures focusNext and focusPrev
	#
	foreach direction {Next Prev} {
	    set procBody [info body tk_focus$direction]
	    regsub -all {winfo children} $procBody {getChildren $class} procBody
	    proc focus$direction {w class} $procBody
	}
    }
    makeFocusProcs 

    #
    # Invoked in the procedures focusNext and focusPrev defined above:
    #
    proc getChildren {class w} {
	if {[string compare [winfo class $w] $class] == 0} {
	    return {}
	} else {
	    return [winfo children $w]
	}
    }
}

#
# Public utility procedures
# =========================
#

#------------------------------------------------------------------------------
# mwutil::wrongNumArgs
#
# Generates a "wrong # args" error message.
#------------------------------------------------------------------------------
proc mwutil::wrongNumArgs args {
    set optList {}
    foreach arg $args {
	lappend optList \"$arg\"
    }
    return -code error "wrong # args: should be [enumOpts $optList]"
}

#------------------------------------------------------------------------------
# mwutil::getAncestorByClass
#
# Gets the path name of the widget of the specified class from the path name w
# of one of its descendants.  It is assumed that all of the ancestors of w
# exist (but w itself needn't exist).
#------------------------------------------------------------------------------
proc mwutil::getAncestorByClass {w class} {
    regexp {^(\..+)\..+$} $w dummy win
    while {[string compare [winfo class $win] $class] != 0} {
	set win [winfo parent $win]
    }

    return $win
}

#------------------------------------------------------------------------------
# mwutil::convEventFields
#
# Gets the path name of the widget of the specified class and the x and y
# coordinates relative to the latter from the path name w of one of its
# descendants and from the x and y coordinates relative to the latter.
#------------------------------------------------------------------------------
proc mwutil::convEventFields {w x y class} {
    set win [getAncestorByClass $w $class]
    set _x  [expr {$x + [winfo rootx $w] - [winfo rootx $win]}]
    set _y  [expr {$y + [winfo rooty $w] - [winfo rooty $win]}]

    return [list $win $_x $_y]
}

#------------------------------------------------------------------------------
# mwutil::defineKeyNav
#
# For a given mega-widget class, the procedure defines the binding tag
# ${class}KeyNav as a partial replacement for "all", by substituting the
# scripts bound to the events <Tab>, <Shift-Tab>, and <<PrevWindow>> with new
# ones which propagate these events to the mega-widget of the given class
# containing the widget to which the event was reported.  (The event
# <Shift-Tab> was replaced with <<PrevWindow>> in Tk 8.3.0.)  This tag is
# designed to be inserted before "all" in the list of binding tags of a
# descendant of a mega-widget of the specified class.
#------------------------------------------------------------------------------
proc mwutil::defineKeyNav class {
    foreach event {<Tab> <Shift-Tab> <<PrevWindow>>} {
	bind ${class}KeyNav $event \
	     [list mwutil::processTraversal %W $class $event]
    }

    bind Entry   <<TraverseIn>> { %W selection range 0 end; %W icursor end }
    bind Spinbox <<TraverseIn>> { %W selection range 0 end; %W icursor end }
}

#------------------------------------------------------------------------------
# mwutil::processTraversal
#
# Processes the given traversal event for the mega-widget of the specified
# class containing the widget w if that mega-widget is not the only widget
# receiving the focus during keyboard traversal within its top-level widget.
#------------------------------------------------------------------------------
proc mwutil::processTraversal {w class event} {
    set win [getAncestorByClass $w $class]

    if {[string compare $event "<Tab>"] == 0} {
	set target [focusNext $win $class]
    } else {
	set target [focusPrev $win $class]
    }

    if {[string compare $target $win] != 0} {
	set focus [focus]
	if {[string length $focus] != 0} {
	    event generate $focus <<TraverseOut>>
	}

	focus $target
	event generate $target <<TraverseIn>>
    }

    return -code break ""
}

#------------------------------------------------------------------------------
# mwutil::configureWidget
#
# Configures the widget win by processing the command-line arguments specified
# in optValPairs and, if the value of initialize is true, also those database
# options that don't match any command-line arguments.
#------------------------------------------------------------------------------
proc mwutil::configureWidget {win configSpecsName configCmd cgetCmd \
			      optValPairs initialize} {
    upvar $configSpecsName configSpecs

    #
    # Process the command-line arguments
    #
    set cmdLineOpts {}
    set savedVals {}
    set failed 0
    set count [llength $optValPairs]
    foreach {opt val} $optValPairs {
	if {[catch {fullConfigOpt $opt configSpecs} result] != 0} {
	    set failed 1
	    break
	}
	if {$count == 1} {
	    set result "value for \"$opt\" missing"
	    set failed 1
	    break
	}
	set opt $result
	lappend cmdLineOpts $opt
	lappend savedVals [eval $cgetCmd [list $win $opt]]
	if {[catch {eval $configCmd [list $win $opt $val]} result] != 0} {
	    set failed 1
	    break
	}
	incr count -2
    }

    if {$failed} {
	#
	# Restore the saved values
	#
	foreach opt $cmdLineOpts val $savedVals {
	    eval $configCmd [list $win $opt $val]
	}

	return -code error $result
    }

    if {$initialize} {
	#
	# Process those configuration options that were not
	# given as command-line arguments; use the corresponding
	# values from the option database if available
	#
	foreach opt [lsort [array names configSpecs]] {
	    if {[llength $configSpecs($opt)] == 1 ||
		[lsearch -exact $cmdLineOpts $opt] >= 0} {
		continue
	    }
	    set dbName [lindex $configSpecs($opt) 0]
	    set dbClass [lindex $configSpecs($opt) 1]
	    set dbValue [option get $win $dbName $dbClass]
	    if {[string length $dbValue] == 0} {
		set default [lindex $configSpecs($opt) 3]
		eval $configCmd [list $win $opt $default]
	    } else {
		if {[catch {
		    eval $configCmd [list $win $opt $dbValue]
		} result] != 0} {
		    return -code error $result
		}
	    }
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# mwutil::fullConfigOpt
#
# Returns the full configuration option corresponding to the possibly
# abbreviated option opt.
#------------------------------------------------------------------------------
proc mwutil::fullConfigOpt {opt configSpecsName} {
    upvar $configSpecsName configSpecs

    if {[info exists configSpecs($opt)]} {
	if {[llength $configSpecs($opt)] == 1} {
	    return $configSpecs($opt)
	} else {
	    return $opt
	}
    }

    set optList [lsort [array names configSpecs]]
    set count 0
    foreach elem $optList {
	if {[string first $opt $elem] == 0} {
	    incr count
	    if {$count == 1} {
		set option $elem
	    } else {
		break
	    }
	}
    }

    if {$count == 1} {
	if {[llength $configSpecs($option)] == 1} {
	    return $configSpecs($option)
	} else {
	    return $option
	}
    } elseif {$count == 0} {
	### return -code error "unknown option \"$opt\""
	return -code error \
	       "bad option \"$opt\": must be [enumOpts $optList]"
    } else {
	### return -code error "unknown option \"$opt\""
	return -code error \
	       "ambiguous option \"$opt\": must be [enumOpts $optList]"
    }
}

#------------------------------------------------------------------------------
# mwutil::fullOpt
#
# Returns the full option corresponding to the possibly abbreviated option opt.
#------------------------------------------------------------------------------
proc mwutil::fullOpt {kind opt optList} {
    if {[lsearch -exact $optList $opt] >= 0} {
	return $opt
    }

    set count 0
    foreach elem $optList {
	if {[string first $opt $elem] == 0} {
	    incr count
	    if {$count == 1} {
		set option $elem
	    } else {
		break
	    }
	}
    }

    if {$count == 1} {
	return $option
    } elseif {$count == 0} {
	return -code error \
	       "bad $kind \"$opt\": must be [enumOpts $optList]"
    } else {
	return -code error \
	       "ambiguous $kind \"$opt\": must be [enumOpts $optList]"
    }
}

#------------------------------------------------------------------------------
# mwutil::enumOpts
#
# Returns a string consisting of the elements of the given list, separated by
# commas and spaces.
#------------------------------------------------------------------------------
proc mwutil::enumOpts optList {
    set optCount [llength $optList]
    set n 1
    foreach opt $optList {
	if {$n == 1} {
	    set str $opt
	} elseif {$n < $optCount} {
	    append str ", $opt"
	} else {
	    if {$optCount > 2} {
		append str ","
	    }
	    append str " or $opt"
	}

	incr n
    }

    return $str
}

#------------------------------------------------------------------------------
# mwutil::configureSubCmd
#
# This procedure is invoked to process configuration subcommands.
#------------------------------------------------------------------------------
proc mwutil::configureSubCmd {win configSpecsName configCmd cgetCmd argList} {
    upvar $configSpecsName configSpecs

    set argCount [llength $argList]
    if {$argCount > 1} {
	#
	# Set the specified configuration options to the given values
	#
	return [configureWidget $win configSpecs $configCmd $cgetCmd $argList 0]
    } elseif {$argCount == 1} {
	#
	# Return the description of the specified configuration option
	#
	set opt [fullConfigOpt [lindex $argList 0] configSpecs]
	set dbName [lindex $configSpecs($opt) 0]
	set dbClass [lindex $configSpecs($opt) 1]
	set default [lindex $configSpecs($opt) 3]
	return [list $opt $dbName $dbClass $default \
		[eval $cgetCmd [list $win $opt]]]
    } else {
	#
	# Return a list describing all available configuration options
	#
	foreach opt [lsort [array names configSpecs]] {
	    if {[llength $configSpecs($opt)] == 1} {
		set alias $configSpecs($opt)
		if {$::tk_version >= 8.1} {
		    lappend result [list $opt $alias]
		} else {
		    set dbName [lindex $configSpecs($alias) 0]
		    lappend result [list $opt $dbName]
		}
	    } else {
		set dbName [lindex $configSpecs($opt) 0]
		set dbClass [lindex $configSpecs($opt) 1]
		set default [lindex $configSpecs($opt) 3]
		lappend result [list $opt $dbName $dbClass $default \
				[eval $cgetCmd [list $win $opt]]]
	    }
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# mwutil::attribSubCmd
#
# This procedure is invoked to process *attrib subcommands.
#------------------------------------------------------------------------------
proc mwutil::attribSubCmd {win prefix argList} {
    set classNs [string tolower [winfo class $win]]
    upvar ::${classNs}::ns${win}::attribs attribs

    set argCount [llength $argList]
    if {$argCount > 1} {
	#
	# Set the specified attributes to the given values
	#
	if {$argCount % 2 != 0} {
	    return -code error "value for \"[lindex $argList end]\" missing"
	}
	foreach {attr val} $argList {
	    set attribs($prefix-$attr) $val
	}
	return ""
    } elseif {$argCount == 1} {
	#
	# Return the value of the specified attribute
	#
	set attr [lindex $argList 0]
	set name $prefix-$attr
	if {[info exists attribs($name)]} {
	    return $attribs($name)
	} else {
	    return ""
	}
    } else {
	#
	# Return the current list of attribute names and values
	#
	set len [string length "$prefix-"]
	set result {}
	foreach name [lsort [array names attribs "$prefix-*"]] {
	    set attr [string range $name $len end]
	    lappend result [list $attr $attribs($name)]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# mwutil::hasattribSubCmd
#
# This procedure is invoked to process has*attrib subcommands.
#------------------------------------------------------------------------------
proc mwutil::hasattribSubCmd {win prefix attr} {
    set classNs [string tolower [winfo class $win]]
    upvar ::${classNs}::ns${win}::attribs attribs

    return [info exists attribs($prefix-$attr)]
}

#------------------------------------------------------------------------------
# mwutil::unsetattribSubCmd
#
# This procedure is invoked to process unset*attrib subcommands.
#------------------------------------------------------------------------------
proc mwutil::unsetattribSubCmd {win prefix attr} {
    set classNs [string tolower [winfo class $win]]
    upvar ::${classNs}::ns${win}::attribs attribs

    set name $prefix-$attr
    if {[info exists attribs($name)]} {
	unset attribs($name)
    }

    return ""
}

#------------------------------------------------------------------------------
# mwutil::getScrollInfo
#
# Parses a list of arguments of the form "moveto <fraction>" or "scroll
# <number> units|pages" and returns the corresponding list consisting of two or
# three properly formatted elements.
#------------------------------------------------------------------------------
proc mwutil::getScrollInfo argList {
    set argCount [llength $argList]
    set opt [lindex $argList 0]

    if {[string first $opt "moveto"] == 0} {
	if {$argCount != 2} {
	    wrongNumArgs "moveto fraction"
	}

	set fraction [lindex $argList 1]
	format "%f" $fraction ;# floating-point number check with error message
	return [list moveto $fraction]
    } elseif {[string first $opt "scroll"] == 0} {
	if {$argCount != 3} {
	    wrongNumArgs "scroll number units|pages"
	}

	set number [format "%d" [lindex $argList 1]]
	set what [lindex $argList 2]
	if {[string first $what "units"] == 0} {
	    return [list scroll $number units]
	} elseif {[string first $what "pages"] == 0} {
	    return [list scroll $number pages]
	} else {
	    return -code error "bad argument \"$what\": must be units or pages"
	}
    } else {
	return -code error "unknown option \"$opt\": must be moveto or scroll"
    }
}

Added libs/tablelist6.0/scripts/pencil.cur.

cannot compute difference between binary files

Added libs/tablelist6.0/scripts/repair.tcl.









































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#!/usr/bin/env wish

#==============================================================================
# Creates new versions of the files "tablelistWidget.tcl", "tablelistBind.tcl",
# "tablelistConfig.tcl", "tablelistEdit.tcl", "tablelistMove.tcl",
# "tablelistSort.tcl", and "tablelistUtil.tcl" by defining the procedure
# "arrElemExists" and replacing all invocations of "[info exists
# <array>(<name>)]" with "[arrElemExists <array> <name>]".  This works around a
# bug in Tcl versions 8.2, 8.3.0 - 8.3.2, and 8.4a1 (fixed in Tcl 8.3.3 and
# 8.4a2), which causes excessive memory use when calling "info exists" on
# non-existent array elements.
#
# Copyright (c) 2001-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

set procDef {
    #
    # The following procedure returns 1 if arrName($name) exists and
    # 0 otherwise.  It is a (partial) replacement for [info exists
    # arrName($name)], which -- due to a bug in Tcl versions 8.2,
    # 8.3.0 - 8.3.2, and 8.4a1 (fixed in Tcl 8.3.3 and 8.4a2) --
    # causes excessive memory use if arrName($name) doesn't exist.
    # The first version of the procedure assumes that the second
    # argument doesn't contain glob-style special characters.
    #
    if {[regexp {^8\.(2\.[0-3]|3\.[0-2]|4a1)$} $tk_patchLevel]} {
	proc arrElemExists {arrName name} {
	    upvar $arrName arr
	    return [llength [array names arr $name]]
	}
    } else {
	proc arrElemExists {arrName name} {
	    upvar $arrName arr
	    return [info exists arr($name)]		;# this is much faster
	}
    }
}

file copy tablelistWidget.tcl tablelistWidget.tcl.BAK

set fi [open tablelistWidget.tcl.BAK r]
set fo [open tablelistWidget.tcl     w]

for {set n 1} {[gets $fi line] >= 0} {incr n} {
    if {$n == 19} {
	puts -nonewline $fo $line
	puts $fo $procDef
    } else {
	regsub -all {\[info exists (tablelist::[^\(]+)\(([^\]]+)\)\]} $line \
		    {[tablelist::arrElemExists \1 \2]} line
	regsub -all {\[info exists ([^\(]+)\(([^\]]+)\)\]} $line \
		    {[arrElemExists \1 \2]} line
	puts $fo $line
    }
}

close $fi
close $fo

puts "\nMade backup copy \"tablelistWidget.tcl.BAK\"."
puts "Created new version of the file \"tablelistWidget.tcl\"."

foreach file {tablelistBind.tcl tablelistConfig.tcl tablelistEdit.tcl
	      tablelistMove.tcl tablelistSort.tcl tablelistThemes.tcl
	      tablelistUtil.tcl} {
    file copy $file $file.BAK

    set fi [open $file.BAK r]
    set fo [open $file     w]

    while {[gets $fi line] >= 0} {
	regsub -all {\[info exists (tablelist::[^\(]+)\(([^\]]+)\)\]} $line \
		    {[tablelist::arrElemExists \1 \2]} line
	regsub -all {\[info exists ([^\(]+)\(([^\]]+)\)\]} $line \
		    {[arrElemExists \1 \2]} line
	puts $fo $line
    }

    close $fi
    close $fo

    puts "\nMade backup copy \"$file.BAK\"."
    puts "Created new version of the file \"$file\"."
}

Added libs/tablelist6.0/scripts/tablelistBind.tcl.





















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
#==============================================================================
# Contains public and private procedures used in tablelist bindings.
#
# Structure of the module:
#   - Public helper procedures
#   - Binding tag Tablelist
#   - Binding tag TablelistWindow
#   - Binding tag TablelistBody
#   - Binding tag TablelistHeader
#   - Binding tags TablelistLabel, TablelistSubLabel, and TablelistArrow
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Public helper procedures
# ========================
#

#------------------------------------------------------------------------------
# tablelist::getTablelistColumn
#
# Gets the column number from the path name w of a (sub)label or sort arrow of
# a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::getTablelistColumn w {
    if {[regexp {^(\..+)\.hdr\.t\.f\.l([0-9]+)(-[it]l)?$} $w dummy win col] ||
	[regexp {^(\..+)\.hdr\.t\.f\.c([0-9]+)$} $w dummy win col]} {
	return $col
    } else {
	return -1
    }
}

#------------------------------------------------------------------------------
# tablelist::getTablelistPath
#
# Gets the path name of the tablelist widget from the path name w of one of its
# descendants.  It is assumed that all of the ancestors of w exist (but w
# itself needn't exist).
#------------------------------------------------------------------------------
proc tablelist::getTablelistPath w {
    return [mwutil::getAncestorByClass $w Tablelist]
}

#------------------------------------------------------------------------------
# tablelist::convEventFields
#
# Gets the path name of the tablelist widget and the x and y coordinates
# relative to the latter from the path name w of one of its descendants and
# from the x and y coordinates relative to the latter.
#------------------------------------------------------------------------------
proc tablelist::convEventFields {w x y} {
    return [mwutil::convEventFields $w $x $y Tablelist]
}

#------------------------------------------------------------------------------
# tablelist::delaySashPosUpdates
#
# Overrides the Tk or Ttk library procedure ::tk::panedwindow::DragSash or
# ::ttk::panedwindow::Drag with a version in which the "sash place ..." or
# "sashpos ..." invocations for the (ttk::)panedwindow widget w are delayed by
# ms milliseconds.
#------------------------------------------------------------------------------
proc tablelist::delaySashPosUpdates {w ms} {
    #
    # Check the first argument
    #
    if {![winfo exists $w]} {
	return -code error "bad window path name \"$w\""
    }
    set class [winfo class $w]
    switch $class {
	Panedwindow {
	    if {[llength [info commands ::tk::panedwindow::DragSash]] == 0} {
		return -code error "window \"$w\" is not a panedwindow widget"
	    }
	}

	TPanedwindow {
	    if {[llength [info commands ::ttk::panedwindow::Drag]] != 0} {
		set namesp ::ttk::panedwindow
	    } else {
		return -code error \
		       "window \"$w\" is not a ttk::panedwindow widget"
	    }
	}

	TPaned {
	    if {[llength [info commands ::ttk::paned::Drag]] != 0} {
		set namesp ::ttk::paned
	    } elseif {[llength [info commands ::tile::paned::Drag]] != 0} {
		set namesp ::tile::paned
	    } else {
		return -code error "window \"$w\" is not a ttk::paned widget"
	    }
	}

	default {
	    return -code error \
		   "window \"$w\" is not a (ttk::)panewindow widget"
	}
    }

    #
    # Check the second argument
    #
    if {[catch {format "%d" $ms} result] != 0} { ;# integer check with error msg
	return -code error $result
    }
    set ms $result
    if {$ms < 0} {
	#
	# Forget the sash position update delay for the given widget
	#
	if {[info exists ::tablelist::sashPosUpdateDelays($w)]} {
	    unset ::tablelist::sashPosUpdateDelays($w)
	}
	return ""
    }

    #
    # Remember the sash position update delay for the given widget
    #
    set ::tablelist::sashPosUpdateDelays($w) $ms

    bind $w <Destroy> {+
	#
	# Forget the sash position update delay for the given widget
	#
	if {[info exists ::tablelist::sashPosUpdateDelays(%W)]} {
	    unset ::tablelist::sashPosUpdateDelays(%W)
	}
    }

    #
    # Override the Tk or Ttk library procedure
    # ::tk::panedwindow::DragSash or ${namesp}::Drag
    #
    if {[string compare [winfo class $w] "Panedwindow"] == 0} {
	proc ::tk::panedwindow::DragSash {w x y proxy} {
	    variable ::tk::Priv
	    if {![info exists Priv(sash)]} { return }

	    if {[$w cget -opaqueresize]} {
		set proxy 0
	    }

	    if {$proxy} {
		$w proxy place [expr {$x + $Priv(dx)}] [expr {$y + $Priv(dy)}]
	    } elseif {[info exists ::tablelist::sashPosUpdateDelays($w)]} {
		set Priv(newSashX) [expr {$x + $Priv(dx)}]
		set Priv(newSashY) [expr {$y + $Priv(dy)}]

		if {![info exists Priv(sashPosId)]} {
		    set Priv(sashPosId) \
			[after $::tablelist::sashPosUpdateDelays($w) \
			 [list ::tk::panedwindow::UpdateSashPos $w $Priv(sash)]]
		}
	    } else {
		$w sash place $Priv(sash) \
			[expr {$x + $Priv(dx)}] [expr {$y + $Priv(dy)}]
	    }
	}

	proc ::tk::panedwindow::UpdateSashPos {w index} {
	    variable ::tk::Priv
	    unset Priv(sashPosId)

	    if {[winfo exists $w]} {
		$w sash place $index $Priv(newSashX) $Priv(newSashY)
	    }
	}

    } else {
	proc ${namesp}::Drag {w x y} [format {
	    variable State
	    if {!$State(pressed)} { return }

	    switch -- [$w cget -orient] {
		horizontal	{ set delta [expr {$x - $State(pressX)}] }
		vertical	{ set delta [expr {$y - $State(pressY)}] }
	    }

	    if {[info exists ::tablelist::sashPosUpdateDelays($w)]} {
		set State(newSashPos) [expr {$State(sashPos) + $delta}]

		if {![info exists State(sashPosId)]} {
		    set State(sashPosId) \
			[after $::tablelist::sashPosUpdateDelays($w) \
			 [list %s::UpdateSashPos $w $State(sash)]]
		}
	    } else {
		$w sashpos $State(sash) [expr {$State(sashPos) + $delta}]
	    }
	} $namesp]

	proc ${namesp}::UpdateSashPos {w index} {
	    variable State
	    unset State(sashPosId)

	    if {[winfo exists $w]} {
		$w sashpos $index $State(newSashPos)
	    }
	}
    }
}

#
# Binding tag Tablelist
# =====================
#

#------------------------------------------------------------------------------
# tablelist::addActiveTag
#
# This procedure is invoked when the tablelist widget win gains the keyboard
# focus.  It moves the "active" tag to the line or cell that displays the
# active item or element of the widget in its body text child.
#------------------------------------------------------------------------------
proc tablelist::addActiveTag win {
    upvar ::tablelist::ns${win}::data data
    set data(ownsFocus) 1

    #
    # Conditionally move the "active" tag to the line
    # or cell that displays the active item or element
    #
    if {![info exists data(dispId)]} {
	moveActiveTag $win
    }
}

#------------------------------------------------------------------------------
# tablelist::removeActiveTag
#
# This procedure is invoked when the tablelist widget win loses the keyboard
# focus.  It removes the "active" tag from the body text child of the widget.
#------------------------------------------------------------------------------
proc tablelist::removeActiveTag win {
    upvar ::tablelist::ns${win}::data data
    set data(ownsFocus) 0

    $data(body) tag remove curRow 1.0 end
    $data(body) tag remove active 1.0 end
}

#------------------------------------------------------------------------------
# tablelist::cleanup
#
# This procedure is invoked when the tablelist widget win is destroyed.  It
# executes some cleanup operations.
#------------------------------------------------------------------------------
proc tablelist::cleanup win {
    #
    # Cancel the execution of all delayed (hdr_)handleMotion, updateKeyToRowMap,
    # adjustSeps, makeStripes, showLineNumbers, stretchColumns,
    # (hdr_)updateColors, updateScrlColOffset, updateHScrlbar, updateVScrlbar,
    # updateView, synchronize, displayItems, horizMoveTo, vertMoveTo, autoScan,
    # horizAutoScan, forceRedraw, reconfigWindows, redisplay, redisplayCol, and
    # destroyWidgets commands
    #
    upvar ::tablelist::ns${win}::data data
    foreach id {motionId hdr_motionId mapId sepsId stripesId lineNumsId
		stretchId colorsId hdr_colorsId offsetId hScrlbarId vScrlbarId
		viewId syncId dispId moveToId afterId redrawId reconfigId} {
	if {[info exists data($id)]} {
	    after cancel $data($id)
	}
    }
    foreach name [array names data *redispId] {
	after cancel $data($name)
    }
    foreach destroyId $data(destroyIdList) {
	after cancel $destroyId
    }

    #
    # If there is a list variable associated with the
    # widget then remove the trace set on this variable
    #
    upvar #0 $data(-listvariable) var
    if {$data(hasListVar) && [info exists var]} {
	trace vdelete var wu $data(listVarTraceCmd)
    }

    #
    # Destroy any existing bindings for the tags data(bodyTag),
    # data(headerTag), data(labelTag), and data(editwinTag)
    #
    foreach tag [list $data(bodyTag) $data(headerTag) \
		      $data(labelTag) $data(editwinTag)] {
	foreach event [bind $tag] {
	    bind $tag $event ""
	}
    }

    #
    # Delete the bitmaps displaying the sort ranks
    # and the images used to display the sort arrows
    #
    for {set rank 1} {$rank < 10} {incr rank} {
	image delete sortRank$rank$win
    }
    set imgNames [image names]
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set w $data(hdrTxtFrmCanv)$col
	foreach shape {triangleUp darkLineUp lightLineUp
		       triangleDn darkLineDn lightLineDn} {
	    if {[lsearch -exact $imgNames $shape$w] >= 0} {
		image delete $shape$w
	    }
	}
    }

    destroy $data(corner)

    namespace delete ::tablelist::ns$win
    catch {rename ::$win ""}
}

#------------------------------------------------------------------------------
# tablelist::updateCanvases
#
# This procedure handles the events <Activate> and <Deactivate> by configuring
# the canvases displaying sort arrows.
#------------------------------------------------------------------------------
proc tablelist::updateCanvases win {
    upvar ::tablelist::ns${win}::data data
    foreach col $data(arrowColList) {
	configCanvas $win $col
	raiseArrow $win $col
    }
}

#------------------------------------------------------------------------------
# tablelist::updateConfigSpecs
#
# This procedure handles the virtual event <<ThemeChanged>> by updating the
# theme-specific default values of some tablelist configuration options.
#------------------------------------------------------------------------------
proc tablelist::updateConfigSpecs win {
    #
    # This might be an "after idle" callback; check whether the window exists
    #
    if {[destroyed $win]} {
	return ""
    }

    set currentTheme [getCurrentTheme]
    upvar ::tablelist::ns${win}::data data
    if {[string compare $currentTheme $data(currentTheme)] == 0} {
	if {[string compare $currentTheme "tileqt"] == 0} {
	    set widgetStyle [tileqt_currentThemeName]
	    if {[info exists ::env(KDE_SESSION_VERSION)] &&
		[string length $::env(KDE_SESSION_VERSION)] != 0} {
		set colorScheme [getKdeConfigVal "General" "ColorScheme"]
	    } else {
		set colorScheme [getKdeConfigVal "KDE" "colorScheme"]
	    }
	    if {[string compare $widgetStyle $data(widgetStyle)] == 0 &&
		[string compare $colorScheme $data(colorScheme)] == 0} {
		return ""
	    }
	} else {
	    return ""
	}
    }

    variable usingTile
    if {$usingTile} {
	#
	# Populate the array tmp with values corresponding to the old theme
	# and the array themeDefaults with values corresponding to the new one
	#
	array set tmp $data(themeDefaults)
	setThemeDefaults 

	#
	# Set those configuration options whose values equal the old
	# theme-specific defaults to the new theme-specific ones
	#
	variable themeDefaults
	foreach opt {-background -foreground -disabledforeground
		     -stripebackground -selectbackground -selectforeground
		     -selectborderwidth -font -labelforeground -labelfont
		     -labelborderwidth -labelpady -treestyle} {
	    if {[string compare $data($opt) $tmp($opt)] == 0} {
		doConfig $win $opt $themeDefaults($opt)
	    }
	}
	if {[string compare $data(-arrowcolor) $tmp(-arrowcolor)] == 0 &&
	    [string compare $data(-arrowstyle) $tmp(-arrowstyle)] == 0} {
	    foreach opt {-arrowcolor -arrowdisabledcolor -arrowstyle} {
		doConfig $win $opt $themeDefaults($opt)
	    }
	}
	foreach opt {-background -foreground} {
	    doConfig $win $opt $data($opt)     ;# sets the bg color of the seps
	}
	updateCanvases $win
    }

    #
    # Destroy and recreate the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editRow $data(editRow)
	saveEditData $win
	destroy $data(bodyFrm)
	doEditCell $win $editRow $editCol 1
    }

    #
    # Destroy and recreate the embedded windows
    #
    for {set row 0} {$row < $data(hdr_itemCount)} {incr row} {
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    set key [lindex $data(hdr_keyList) $row]
	    if {[info exists data($key,$col-window)]} {
		set val $data($key,$col-window)
		doCellConfig h$row $col $win -window ""
		doCellConfig h$row $col $win -window $val
	    }
	}
    }
    if {$data(winCount) != 0} {
	for {set row 0} {$row < $data(itemCount)} {incr row} {
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set key [lindex $data(keyList) $row]
		if {[info exists data($key,$col-window)]} {
		    set val $data($key,$col-window)
		    doCellConfig $row $col $win -window ""
		    doCellConfig $row $col $win -window $val
		}
	    }
	}
    }

    set data(currentTheme) $currentTheme
    if {[string compare $currentTheme "tileqt"] == 0} {
	set data(widgetStyle) [tileqt_currentThemeName]
	if {[info exists ::env(KDE_SESSION_VERSION)] &&
	    [string length $::env(KDE_SESSION_VERSION)] != 0} {
	    set data(colorScheme) [getKdeConfigVal "General" "ColorScheme"]
	} else {
	    set data(colorScheme) [getKdeConfigVal "KDE" "colorScheme"]
	}
    } else {
	set data(widgetStyle) ""
	set data(colorScheme) ""
    }
    if {$usingTile} {
	set data(themeDefaults) [array get themeDefaults]
    }
}

#
# Binding tag TablelistWindow
# ===========================
#

#------------------------------------------------------------------------------
# tablelist::cleanupWindow
#
# This procedure is invoked when a window embedded into a tablelist widget is
# destroyed.  It invokes the cleanup script associated with the cell containing
# the window, if any.
#------------------------------------------------------------------------------
proc tablelist::cleanupWindow aux {
    regexp {^(.+)\.(hdr\.t|body)\.frm_(h?k[0-9]+),([0-9]+)$} $aux \
	   dummy win textWidget key col
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::checkStates checkStates

    if {[info exists data($key,$col-windowdestroy)]} {
	set row [keyToRow $win $key]
	uplevel #0 $data($key,$col-windowdestroy) [list $win $row $col $aux.w]
    }

    if {[info exists checkStates($key,$col)]} {
	unset checkStates($key,$col)
    }
}

#
# Binding tag TablelistBody
# =========================
#

#------------------------------------------------------------------------------
# tablelist::defineTablelistBody
#
# Defines the bindings for the binding tag TablelistBody.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistBody {} {
    variable priv
    array set priv {
	x			""
	y			""
	afterId			""
	prevRow			""
	prevCol			""
	prevActExpCollCtrlCell	""
	selection		{}
	selClearPending		0
	selChangePending	0
	justClicked		0
	justReleased		0
	clickedInEditWin	0
	clickedExpCollCtrl	0
    }

    foreach event {<Enter> <Motion> <Leave>} {
	bind TablelistBody $event [format {
	    tablelist::handleMotionDelayed %%W %%x %%y %%X %%Y %%m %s
	} $event]
    }
    bind TablelistBody <Button-1> {
	if {[winfo exists %W]} {
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}
	    if {$tablelist::y < [winfo y [$tablelist::W bodypath]]} {
		continue
	    }

	    set tablelist::priv(x) $tablelist::x
	    set tablelist::priv(y) $tablelist::y
	    set tablelist::priv(row) [$tablelist::W nearest       $tablelist::y]
	    set tablelist::priv(col) [$tablelist::W nearestcolumn $tablelist::x]
	    set tablelist::priv(justClicked) 1
	    after 300 [list set tablelist::priv(justClicked) 0]
	    set tablelist::priv(clickedInEditWin) 0
	    if {[$tablelist::W cget -setfocus] &&
		[string compare [$tablelist::W cget -state] "normal"] == 0} {
		focus [$tablelist::W bodypath]
	    }
	    if {[tablelist::wasExpCollCtrlClicked %W %x %y]} {
		set tablelist::priv(clickedExpCollCtrl) 1
		if {[string length [$tablelist::W editwinpath]] != 0} {
		    tablelist::doFinishEditing $tablelist::W
		}
	    } else {
		tablelist::condEditContainingCell $tablelist::W \
		    $tablelist::x $tablelist::y
		set tablelist::priv(row) \
		    [$tablelist::W nearest       $tablelist::y]
		set tablelist::priv(col) \
		    [$tablelist::W nearestcolumn $tablelist::x]
		tablelist::condBeginMove $tablelist::W $tablelist::priv(row)
		tablelist::beginSelect $tablelist::W \
		    $tablelist::priv(row) $tablelist::priv(col) 1
	    }
	}
    }
    bind TablelistBody <Double-Button-1> {
	if {[winfo exists %W]} {
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}
	    if {$tablelist::y < [winfo y [$tablelist::W bodypath]]} {
		continue
	    }

	    if {[$tablelist::W cget -editselectedonly]} {
		tablelist::condEditContainingCell $tablelist::W \
		    $tablelist::x $tablelist::y
	    }
	}
    }
    bind TablelistBody <B1-Motion> {
	if {$tablelist::priv(justClicked)} {
	    continue
	}

	foreach {tablelist::W tablelist::x tablelist::y} \
	    [tablelist::convEventFields %W %x %y] {}

	if {[string length $tablelist::priv(x)] == 0 ||
	    [string length $tablelist::priv(y)] == 0} {
	    set tablelist::priv(x) $tablelist::x
	    set tablelist::priv(y) $tablelist::y
	}
	set tablelist::priv(prevX) $tablelist::priv(x)
	set tablelist::priv(prevY) $tablelist::priv(y)
	set tablelist::priv(x) $tablelist::x
	set tablelist::priv(y) $tablelist::y
	tablelist::condAutoScan $tablelist::W
	if {!$tablelist::priv(clickedExpCollCtrl)} {
	    tablelist::motion $tablelist::W \
		[$tablelist::W nearest       $tablelist::y] \
		[$tablelist::W nearestcolumn $tablelist::x] 1
	    tablelist::condShowTarget $tablelist::W $tablelist::y
	}
    }
    bind TablelistBody <ButtonRelease-1> {
	if {[winfo exists %W]} {
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}
	    if {$tablelist::y < [winfo y [$tablelist::W bodypath]] &&
		[string length $tablelist::priv(afterId)] == 0} { ;# no autoscan
		continue
	    }

	    set tablelist::priv(x) ""
	    set tablelist::priv(y) ""
	    after cancel $tablelist::priv(afterId)
	    set tablelist::priv(afterId) ""
	    set tablelist::priv(justReleased) 1
	    after 100 [list set tablelist::priv(justReleased) 0]
	    set tablelist::priv(releasedInEditWin) 0
	    if {!$tablelist::priv(clickedExpCollCtrl)} {
		if {$tablelist::priv(justClicked)} {
		    tablelist::moveOrActivate $tablelist::W \
			$tablelist::priv(row) $tablelist::priv(col) 1
		} else {
		    tablelist::moveOrActivate $tablelist::W \
			[$tablelist::W nearest       $tablelist::y] \
			[$tablelist::W nearestcolumn $tablelist::x] \
			[expr {$tablelist::x >= 0 &&
			       $tablelist::x < [winfo width $tablelist::W] &&
			       $tablelist::y >= [winfo y $tablelist::W.body] &&
			       $tablelist::y < [winfo height $tablelist::W]}]
		}
	    }
	    set tablelist::priv(clickedExpCollCtrl) 0
	    after 100 [list tablelist::condEvalInvokeCmd $tablelist::W]
	}
    }
    bind TablelistBody <Shift-Button-1> {
	foreach {tablelist::W tablelist::x tablelist::y} \
	    [tablelist::convEventFields %W %x %y] {}
	if {$tablelist::y < [winfo y [$tablelist::W bodypath]]} {
	    continue
	}

	tablelist::beginExtend $tablelist::W \
	    [$tablelist::W nearest       $tablelist::y] \
	    [$tablelist::W nearestcolumn $tablelist::x]
    }
    bind TablelistBody <Control-Button-1> {
	foreach {tablelist::W tablelist::x tablelist::y} \
	    [tablelist::convEventFields %W %x %y] {}
	if {$tablelist::y < [winfo y [$tablelist::W bodypath]]} {
	    continue
	}

	tablelist::beginToggle $tablelist::W \
	    [$tablelist::W nearest       $tablelist::y] \
	    [$tablelist::W nearestcolumn $tablelist::x]
    }

    bind TablelistBody <Return> {
	tablelist::condEditActiveCell [tablelist::getTablelistPath %W]
    }
    bind TablelistBody <KP_Enter> {
	tablelist::condEditActiveCell [tablelist::getTablelistPath %W]
    }
    bind TablelistBody <Tab> {
	tablelist::nextPrevCell [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody <Shift-Tab> {
	tablelist::nextPrevCell [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody <<PrevWindow>> {
	tablelist::nextPrevCell [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody <plus> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] plus
    }
    bind TablelistBody <minus> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] minus
    }
    bind TablelistBody <KP_Add> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] plus
    }
    bind TablelistBody <KP_Subtract> {
	tablelist::plusMinus [tablelist::getTablelistPath %W] minus
    }

    foreach {virtual event} {
	PrevLine <Up>		 NextLine <Down>
	PrevChar <Left>		 NextChar <Right>
	LineStart <Home>	 LineEnd <End>
	PrevWord <Control-Left>	 NextWord <Control-Right>

	SelectPrevLine <Shift-Up>     SelectNextLine <Shift-Down>
	SelectPrevChar <Shift-Left>   SelectNextChar <Shift-Right>
	SelectLineStart <Shift-Home>  SelectLineEnd <Shift-End>
	SelectAll <Control-slash>     SelectNone <Control-backslash>} {
	if {[llength [event info <<$virtual>>]] == 0} {
	    set eventArr($virtual) $event
	} else {
	    set eventArr($virtual) <<$virtual>>
	}
    }

    bind TablelistBody $eventArr(PrevLine) {
	tablelist::upDown [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(NextLine) {
	tablelist::upDown [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(PrevChar) {
	tablelist::leftRight [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(NextChar) {
	tablelist::leftRight [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody <Prior> {
	tablelist::priorNext [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody <Next> {
	tablelist::priorNext [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(LineStart) {
	tablelist::homeEnd [tablelist::getTablelistPath %W] Home
    }
    bind TablelistBody $eventArr(LineEnd) {
	tablelist::homeEnd [tablelist::getTablelistPath %W] End
    }
    bind TablelistBody <Control-Home> {
	tablelist::firstLast [tablelist::getTablelistPath %W] first
    }
    bind TablelistBody <Control-End> {
	tablelist::firstLast [tablelist::getTablelistPath %W] last
    }
    bind TablelistBody $eventArr(SelectPrevLine) {
	tablelist::extendUpDown [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(SelectNextLine) {
	tablelist::extendUpDown [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(SelectPrevChar) {
	tablelist::extendLeftRight [tablelist::getTablelistPath %W] -1
    }
    bind TablelistBody $eventArr(SelectNextChar) {
	tablelist::extendLeftRight [tablelist::getTablelistPath %W] 1
    }
    bind TablelistBody $eventArr(SelectLineStart) {
	tablelist::extendToHomeEnd [tablelist::getTablelistPath %W] Home
    }
    bind TablelistBody $eventArr(SelectLineEnd) {
	tablelist::extendToHomeEnd [tablelist::getTablelistPath %W] End
    }
    bind TablelistBody <Shift-Control-Home> {
	tablelist::extendToFirstLast [tablelist::getTablelistPath %W] first
    }
    bind TablelistBody <Shift-Control-End> {
	tablelist::extendToFirstLast [tablelist::getTablelistPath %W] last
    }
    foreach event {<space> <Select>} {
	bind TablelistBody $event {
	    set tablelist::W [tablelist::getTablelistPath %W]

	    tablelist::beginSelect $tablelist::W \
		[$tablelist::W index active] [$tablelist::W columnindex active]
	}
    }
    foreach event {<Shift-Control-space> <Shift-Select>} {
	bind TablelistBody $event {
	    set tablelist::W [tablelist::getTablelistPath %W]

	    tablelist::beginExtend $tablelist::W \
		[$tablelist::W index active] [$tablelist::W columnindex active]
	}
    }
    foreach event {<Control-space> <Control-Select>} {
	bind TablelistBody $event {
	    if {!$tablelist::strictTk} {
		set tablelist::W [tablelist::getTablelistPath %W]

		tablelist::beginToggle $tablelist::W \
		    [$tablelist::W index active] \
		    [$tablelist::W columnindex active]
	    }
	}
    }
    bind TablelistBody <Escape> {
	tablelist::cancelSelection [tablelist::getTablelistPath %W]
    }
    bind TablelistBody $eventArr(SelectAll) {
	tablelist::selectAll [tablelist::getTablelistPath %W]
    }
    bind TablelistBody $eventArr(SelectNone) {
	set tablelist::W [tablelist::getTablelistPath %W]

	if {[string compare [$tablelist::W cget -selectmode] "browse"] != 0} {
	    $tablelist::W selection clear 0 end
	    event generate $tablelist::W <<TablelistSelect>>
	}
    }
    foreach pattern {Tab Shift-Tab ISO_Left_Tab hpBackTab} {
	catch {
	    foreach modifier {Control Meta} {
		bind TablelistBody <$modifier-$pattern> [format {
		    mwutil::processTraversal %%W Tablelist <%s>
		} $pattern]
	    }
	}
    }

    variable winSys
    catch {
	if {[string compare $winSys "classic"] == 0 ||
	    [string compare $winSys "aqua"] == 0} {
	    bind TablelistBody <MouseWheel> {
		[tablelist::getTablelistPath %W] yview scroll [expr {-%D}] units
		break
	    }
	    bind TablelistBody <Shift-MouseWheel> {
		[tablelist::getTablelistPath %W] xview scroll [expr {-%D}] units
		break
	    }
	    bind TablelistBody <Option-MouseWheel> {
		[tablelist::getTablelistPath %W] yview scroll \
		    [expr {-10 * %D}] units
		break
	    }
	    bind TablelistBody <Shift-Option-MouseWheel> {
		[tablelist::getTablelistPath %W] xview scroll \
		    [expr {-10 * %D}] units
		break
	    }
	} else {
	    bind TablelistBody <MouseWheel> {
		[tablelist::getTablelistPath %W] yview scroll \
		    [expr {-(%D / 120) * 4}] units
		break
	    }
	    bind TablelistBody <Shift-MouseWheel> {
		[tablelist::getTablelistPath %W] xview scroll \
		    [expr {-(%D / 120) * 4}] units
		break
	    }

	    foreach event {<Control-Key-a> <Control-Lock-Key-A>} {
		bind TablelistBody $event {
		    tablelist::selectAll [tablelist::getTablelistPath %W]
		}
	    }
	    foreach event {<Shift-Control-Key-A> <Shift-Control-Lock-Key-a>} {
		bind TablelistBody $event {
		    set tablelist::W [tablelist::getTablelistPath %W]

		    if {[string compare [$tablelist::W cget -selectmode] \
			 "browse"] != 0} {
			$tablelist::W selection clear 0 end
			event generate $tablelist::W <<TablelistSelect>>
		    }
		}
	    }
	}
    }

    if {[string compare $winSys "x11"] == 0} {
	bind TablelistBody <Button-4> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] yview scroll -5 units
		break
	    }
	}
	bind TablelistBody <Button-5> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] yview scroll 5 units
		break
	    }
	}
	bind TablelistBody <Shift-Button-4> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] xview scroll -5 units
		break
	    }
	}
	bind TablelistBody <Shift-Button-5> {
	    if {!$tk_strictMotif} {
		[tablelist::getTablelistPath %W] xview scroll 5 units
		break
	    }
	}
    }

    foreach event {<Control-Left> <<PrevWord>> <Control-Right> <<NextWord>>
		   <Control-Prior> <Control-Next> <<Copy>>
		   <Button-2> <B2-Motion>} {
	set script [strMap {
	    "%W" "$tablelist::W"  "%x" "$tablelist::x"  "%y" "$tablelist::y"
	} [bind Listbox $event]]

	if {[string length $script] != 0} {
	    bind TablelistBody $event [format {
		if {[winfo exists %%W]} {
		    foreach {tablelist::W tablelist::x tablelist::y} \
			[tablelist::convEventFields %%W %%x %%y] {}
		    %s
		}
	    } $script]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::invokeMotionHandler
#
# Invokes the procedure handleMotionDelayed for the body of the tablelist
# widget win and the current pointer coordinates.
#------------------------------------------------------------------------------
proc tablelist::invokeMotionHandler win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set X [winfo pointerx $w]
    set Y [winfo pointery $w]
    if {$X >= 0 && $Y >= 0} {	;# the mouse pointer is on the same screen as w
	set x [expr {$X - [winfo rootx $w]}]
	set y [expr {$Y - [winfo rooty $w]}]
    } else {
	set x -1
	set y -1
    }

    handleMotionDelayed $w $x $y $X $Y "" <Motion>
}

#------------------------------------------------------------------------------
# tablelist::handleMotionDelayed
#
# This procedure is invoked when the mouse pointer enters or leaves the body of
# a tablelist widget or is moving within it.  It schedules the execution of the
# handleMotion procedure 100 ms later.
#------------------------------------------------------------------------------
proc tablelist::handleMotionDelayed {w x y X Y mode event} {
    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data
    if {[regexp {^vsep([0-9]+)?$} [winfo name $w]]} {
	return ""
    }

    set data(motionData) [list $w $x $y $X $Y $event]
    if {![info exists data(motionId)]} {
	set data(motionId) [after 100 [list tablelist::handleMotion $win]]
    }

    if {[string compare $event "<Enter>"] == 0 &&
	[string compare $mode "NotifyNormal"] == 0} {
	set data(justEntered) 1
    }
}

#------------------------------------------------------------------------------
# tablelist::handleMotion
#
# Invokes the procedures showOrHideTooltip, updateExpCollCtrl, and updateCursor.
#------------------------------------------------------------------------------
proc tablelist::handleMotion win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(motionId)]} {
	after cancel $data(motionId)
	unset data(motionId)
    }

    set data(justEntered) 0

    foreach {w x y X Y event} $data(motionData) {}
    if {![winfo exists $w]} {
	invokeMotionHandler $win
	return ""
    }

    #
    # Get the containing cell from the coordinates relative to the tablelist
    #
    foreach {win _x _y} [convEventFields $w $x $y] {}
    set row [containingRow $win $_y]
    set col [containingCol $win $_x]

    showOrHideTooltip $win $row $col $X $Y
    if {[destroyed $win]} {
	return ""
    }
    updateExpCollCtrl $win $w $row $col $x

    #
    # Make sure updateCursor won't change the cursor of an embedded window
    #
    if {[string match "$data(body).frm_k*" $w] &&
	[string compare [winfo parent $w] $data(body)] == 0 &&
	[string compare $event "<Leave>"] != 0} {
	set row -1
	set col -1
    }

    updateCursor $win $row $col
}

#------------------------------------------------------------------------------
# tablelist::showOrHideTooltip
#
# If the pointer has crossed a cell boundary then the procedure removes the old
# tooltip and displays the one corresponding to the new cell.
#------------------------------------------------------------------------------
proc tablelist::showOrHideTooltip {win row col X Y} {
    upvar ::tablelist::ns${win}::data data
    if {[string length $data(-tooltipaddcommand)] == 0 ||
	[string length $data(-tooltipdelcommand)] == 0 ||
	[string compare $row,$col $data(prevCell)] == 0} {
	return ""
    }

    #
    # Remove the old tooltip, if any.  Then, if we are within a
    # cell, display the new tooltip corresponding to that cell.
    #
    event generate $win <Leave>
    catch {uplevel #0 $data(-tooltipdelcommand) [list $win]}
    if {[destroyed $win]} {
	return ""
    }
    set data(prevCell) $row,$col
    if {$row >= 0 && $col >= 0} {
	set focus [focus -displayof $win]
	if {[string length $focus] == 0 || [string first $win $focus] != 0 ||
	    [string compare [winfo toplevel $focus] \
	     [winfo toplevel $win]] == 0} {
	    uplevel #0 $data(-tooltipaddcommand) [list $win $row $col]
	    if {[destroyed $win]} {
		return ""
	    }
	    event generate $win <Enter> -rootx $X -rooty $Y
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateExpCollCtrl
#
# Activates or deactivates the expand/collapse control under the mouse pointer.
#------------------------------------------------------------------------------
proc tablelist::updateExpCollCtrl {win w row col x} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set indentLabel $data(body).ind_$key,$col

    #
    # Check whether the x coordinate is inside the expand/collapse control
    #
    set inExpCollCtrl 0
    if {[winfo exists $indentLabel]} {
	if {[string compare $w $data(body)] == 0 &&
	    $x < [winfo x $indentLabel] &&
	    [string compare $data($key-parent) "root"] == 0} {
	    set imgName [$indentLabel cget -image]
	    if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
			 $imgName dummy treeStyle mode depth]} {
		#
		# The mouse position is in the tablelist body, to the left
		# of an expand/collapse control of a top-level item:  Handle
		# this like a position inside the expand/collapse control
		#
		set inExpCollCtrl 1
	    }
	} elseif {[string compare $w $indentLabel] == 0} {
	    set imgName [$w cget -image]
	    if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
			 $imgName dummy treeStyle mode depth]} {
		#
		# The mouse position is in an expand/collapse
		# image (which ends with the expand/collapse
		# control):  Check whether it is inside the control
		#
		set baseWidth [image width tablelist_${treeStyle}_collapsedImg]
		if {$x >= [winfo width $w] - $baseWidth - 5} {
		    set inExpCollCtrl 1
		}
	    }
	}
    }

    #
    # Conditionally deactivate the previously activated expand/collapse control
    #
    variable priv
    set prevCellIdx $priv(prevActExpCollCtrlCell)
    if {[string length $prevCellIdx] != 0 &&
	[info exists data($prevCellIdx-indent)] &&
	(!$inExpCollCtrl || [string compare $prevCellIdx $key,$col] != 0) &&
	[winfo exists $data(body).ind_$prevCellIdx]} {
	set data($prevCellIdx-indent) \
	    [strMap {"Act" ""} $data($prevCellIdx-indent)]
	$data(body).ind_$prevCellIdx configure -image $data($prevCellIdx-indent)
	set priv(prevActExpCollCtrlCell) ""
    }

    if {!$inExpCollCtrl || [string compare $prevCellIdx $key,$col] == 0} {
	return ""
    }

    #
    # Activate the expand/collapse control under the mouse pointer
    #
    variable ${treeStyle}_collapsedActImg
    if {[info exists ${treeStyle}_collapsedActImg]} {
	set data($key,$col-indent) [strMap {
	    "SelActImg" "SelActImg" "SelImg" "SelActImg"
	    "ActImg" "ActImg" "Img" "ActImg"
	} $data($key,$col-indent)]
	$indentLabel configure -image $data($key,$col-indent)
	set priv(prevActExpCollCtrlCell) $key,$col
    }
}

#------------------------------------------------------------------------------
# tablelist::updateCursor
#
# Updates the cursor of the body component of the tablelist widget win, over
# the specified cell containing the mouse pointer.
#------------------------------------------------------------------------------
proc tablelist::updateCursor {win row col} {
    upvar ::tablelist::ns${win}::data data
    if {$data(inEditWin)} {
	set cursor $data(-cursor)
    } elseif {$data(-showeditcursor)} {
	if {$data(-editselectedonly) &&
	    ![::$win cellselection includes $row,$col]} {
	    set editable 0
	} else {
	    set editable [expr {$row >= 0 && $col >= 0 &&
			  [isCellEditable $win $row $col]}]
	}

	if {$editable} {
	    if {$row == $data(editRow) && $col == $data(editCol)} {
		set cursor $data(-cursor)
	    } else {
		variable editCursor
		if {![info exists editCursor]} {
		    makeEditCursor 
		}
		set cursor $editCursor
	    }
	} else {
	    set cursor $data(-cursor)
	}

	#
	# Special handling for cell editing with the aid of BWidget
	# ComboBox. Oakley combobox, or Tk menubutton widgets
	#
	if {$data(editRow) >= 0 && $data(editCol) >= 0} {
	    foreach c [winfo children $data(bodyFrmEd)] {
		set class [winfo class $c]
		if {([string compare $class "Toplevel"] == 0 ||
		     [string compare $class "Menu"] == 0) &&
		     [winfo ismapped $c]} {
		    set cursor $data(-cursor)
		    break
		}
	    }
	}
    } else {
	set cursor $data(-cursor)
    }

    if {[string compare [$data(body) cget -cursor] $cursor] != 0} {
	$data(body) configure -cursor $cursor
    }
}

#------------------------------------------------------------------------------
# tablelist::makeEditCursor
#
# Creates the platform-specific edit cursor.
#------------------------------------------------------------------------------
proc tablelist::makeEditCursor {} {
    variable editCursor
    variable winSys

    if {[string compare $winSys "win32"] == 0} {
	variable library
	set cursorName "pencil.cur"
	set cursorFile [file join $library scripts $cursorName]
	if {$::tcl_version >= 8.4} {
	    set cursorFile [file normalize $cursorFile]
	}
	set editCursor [list @$cursorFile]

	#
	# Make sure it will work for starpacks, too
	#
	variable helpLabel
	if {[catch {$helpLabel configure -cursor $editCursor}] != 0} {
	    set tempDir $::env(TEMP)
	    file copy -force $cursorFile $tempDir
	    set editCursor [list @[file join $tempDir $cursorName]]
	}
    } else {
	set editCursor pencil
    }
}

#------------------------------------------------------------------------------
# tablelist::wasExpCollCtrlClicked
#
# This procedure is invoked when mouse button 1 is pressed in the body of a
# tablelist widget or in one of its separators.  It checks whether the mouse
# click occurred inside an expand/collapse control.
#------------------------------------------------------------------------------
proc tablelist::wasExpCollCtrlClicked {w x y} {
    foreach {win _x _y} [convEventFields $w $x $y] {}
    set row [containingRow $win $_y]
    set col [containingCol $win $_x]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set indentLabel $data(body).ind_$key,$col
    if {![winfo exists $indentLabel]} {
	return 0
    }

    #
    # Check whether the x coordinate is inside the expand/collapse control
    #
    set inExpCollCtrl 0
    if {[string compare $w $data(body)] == 0 && $x < [winfo x $indentLabel] &&
	[string compare $data($key-parent) "root"] == 0} {
	set imgName [$indentLabel cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    #
	    # The mouse position is in the tablelist body, to the left
	    # of an expand/collapse control of a top-level item:  Handle
	    # this like a position inside the expand/collapse control
	    #
	    set inExpCollCtrl 1
	}
    } elseif {[string compare $w $indentLabel] == 0} {
	set imgName [$w cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    #
	    # The mouse position is in an expand/collapse
	    # image (which ends with the expand/collapse
	    # control):  Check whether it is inside the control
	    #
	    set baseWidth [image width tablelist_${treeStyle}_collapsedImg]
	    if {$x >= [winfo width $w] - $baseWidth - 5} {
		set inExpCollCtrl 1
	    }
	}
    }

    if {!$inExpCollCtrl} {
	return 0
    }

    #
    # Toggle the state of the expand/collapse control
    #
    if {[string compare $mode "collapsed"] == 0} {
	::$win expand $row -partly
    } else {
	::$win collapse $row -partly
    }

    return 1
}

#------------------------------------------------------------------------------
# tablelist::condEditContainingCell
#
# This procedure is invoked when mouse button 1 is pressed in the body of a
# tablelist widget win or in one of its separators.  If the mouse click
# occurred inside an editable cell and the latter is not already being edited,
# then the procedure starts the interactive editing in that cell.  Otherwise it
# finishes a possibly active cell editing.
#------------------------------------------------------------------------------
proc tablelist::condEditContainingCell {win x y} {
    #
    # Get the containing cell from the coordinates relative to the parent
    #
    set row [containingRow $win $y]
    set col [containingCol $win $x]

    upvar ::tablelist::ns${win}::data data
    if {$data(justEntered) || ($data(-editselectedonly) &&
	![::$win cellselection includes $row,$col])} {
	set editable 0
    } else {
	set editable [expr {$row >= 0 && $col >= 0 &&
		      [isCellEditable $win $row $col]}]
    }

    #
    # The following check is sometimes needed on OS X if
    # editing with the aid of a menubutton is in progress
    #
    variable editCursor
    if {($row != $data(editRow) || $col != $data(editCol)) &&
	$data(-showeditcursor) && [info exists editCursor] &&
	[string compare [$data(body) cget -cursor] $editCursor] != 0} {
	set editable 0
    }

    if {$editable} {
	#
	# Get the coordinates relative to the
	# tablelist body and invoke doEditCell
	#
	set w $data(body)
	incr x -[winfo x $w]
	incr y -[winfo y $w]
	scan [$w index @$x,$y] "%d.%d" line charPos
	doEditCell $win $row $col 0 "" $charPos
    } elseif {$data(editRow) >= 0} {
	#
	# Finish the current editing
	#
	doFinishEditing $win
    }
}

#------------------------------------------------------------------------------
# tablelist::condBeginMove
#
# This procedure is typically invoked on button-1 presses in the body of a
# tablelist widget or in one of its separators.  It begins the process of
# moving the nearest row if the rows are movable and the selection mode is not
# browse or extended.
#------------------------------------------------------------------------------
proc tablelist::condBeginMove {win row} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || !$data(-movablerows) || $data(itemCount) == 0 ||
	[string compare $data(-selectmode) "browse"] == 0 ||
	[string compare $data(-selectmode) "extended"] == 0} {
	return ""
    }

    set data(sourceRow) $row
    set sourceKey [lindex $data(keyList) $row]
    set data(sourceEndRow) [nodeRow $win $sourceKey end]
    set data(sourceDescCount) [descCount $win $sourceKey]

    set data(sourceParentKey) $data($sourceKey-parent)
    set data(sourceParentRow) [keyToRow $win $data(sourceParentKey)]
    set data(sourceParentEndRow) [nodeRow $win $data(sourceParentKey) end]

    set topWin [winfo toplevel $win]
    set data(topEscBinding) [bind $topWin <Escape>]
    bind $topWin <Escape> [list tablelist::cancelMove [strMap {"%" "%%"} $win]]
}

#------------------------------------------------------------------------------
# tablelist::beginSelect
#
# This procedure is typically invoked on button-1 presses in the body of a
# tablelist widget or in one of its separators.  It begins the process of
# making a selection in the widget.  Its exact behavior depends on the
# selection mode currently in effect for the widget.
#------------------------------------------------------------------------------
proc tablelist::beginSelect {win row col {checkIfDragSrc 0}} {
    variable priv
    set priv(selClearPending) 0
    set priv(selChangePending) 0

    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    if {[string compare $data(-selectmode) "multiple"] == 0} {
		if {[::$win selection includes $row]} {
		    if {$checkIfDragSrc && [isDragSrc $win]} {
			set priv(selClearPending) 1
		    } else {
			::$win selection clear $row
		    }
		} else {
		    ::$win selection set $row
		}
	    } else {
		if {[::$win selection includes $row] &&
		    $checkIfDragSrc && [isDragSrc $win]} {
		    set priv(selChangePending) 1
		} else {
		    ::$win selection clear 0 end
		    ::$win selection set $row
		}
		::$win selection anchor $row
		set priv(selection) {}
	    }

	    set priv(prevRow) $row
	}

	cell {
	    if {[string compare $data(-selectmode) "multiple"] == 0} {
		if {[::$win cellselection includes $row,$col]} {
		    if {$checkIfDragSrc && [isDragSrc $win]} {
			set priv(selClearPending) 1
		    } else {
			::$win cellselection clear $row,$col
		    }
		} else {
		    ::$win cellselection set $row,$col
		}
	    } else {
		if {[::$win cellselection includes $row,$col] &&
		    $checkIfDragSrc && [isDragSrc $win]} {
		    set priv(selChangePending) 1
		} else {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set $row,$col
		}
		::$win cellselection anchor $row,$col
		set priv(selection) {}
	    }

	    set priv(prevRow) $row
	    set priv(prevCol) $col
	}
    }

    event generate $win <<TablelistSelect>>
}

#------------------------------------------------------------------------------
# tablelist::condAutoScan
#
# This procedure is invoked when the mouse leaves or enters the scrollable part
# of a tablelist widget's body text child while button 1 is down.  It either
# invokes the autoScan procedure or cancels its executon as an "after" command.
#------------------------------------------------------------------------------
proc tablelist::condAutoScan win {
    variable priv
    set w [::$win bodypath]
    set wX [winfo x $w]
    set wY [winfo y $w]
    set wWidth  [winfo width  $w]
    set wHeight [winfo height $w]
    set x [expr {$priv(x) - $wX}]
    set y [expr {$priv(y) - $wY}]
    set prevX [expr {$priv(prevX) - $wX}]
    set prevY [expr {$priv(prevY) - $wY}]
    set minX [minScrollableX $win]

    if {($y >= $wHeight && $prevY < $wHeight) ||
	($y < 0 && $prevY >= 0) ||
	($x >= $wWidth && $prevX < $wWidth) ||
	($x < $minX && $prevX >= $minX)} {
	if {[string length $priv(afterId)] == 0} {
	    autoScan $win
	}
    } elseif {($y < $wHeight && $prevY >= $wHeight) ||
	      ($y >= 0 && $prevY < 0) ||
	      ($x < $wWidth && $prevX >= $wWidth) ||
	      ($x >= $minX && $prevX < $minX)} {
	after cancel $priv(afterId)
	set priv(afterId) ""
    }
}

#------------------------------------------------------------------------------
# tablelist::autoScan
#
# This procedure is invoked when the mouse leaves the scrollable part of a
# tablelist widget's body text child while button 1 is down.  It scrolls the
# child up, down, left, or right, depending on where the mouse left the
# scrollable part of the tablelist's body, and reschedules itself as an "after"
# command so that the child continues to scroll until the mouse moves back into
# the window or the mouse button is released.
#------------------------------------------------------------------------------
proc tablelist::autoScan win {
    if {[destroyed $win] || [isDragSrc $win] ||
	[string length [::$win editwinpath]] != 0} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(-autoscan)} {
	return ""
    }

    variable priv
    set w [::$win bodypath]
    set x [expr {$priv(x) - [winfo x $w]}]
    set y [expr {$priv(y) - [winfo y $w]}]
    set minX [minScrollableX $win]

    if {$y >= [winfo height $w]} {
	::$win yview scroll 1 units
	set ms 50
    } elseif {$y < 0} {
	::$win yview scroll -1 units
	set ms 50
    } elseif {$x >= [winfo width $w]} {
	if {$data(-titlecolumns) == 0} {
	    ::$win xview scroll 2 units
	    set ms 50
	} else {
	    ::$win xview scroll 1 units
	    set ms 250
	}
    } elseif {$x < $minX} {
	if {$data(-titlecolumns) == 0} {
	    ::$win xview scroll -2 units
	    set ms 50
	} else {
	    ::$win xview scroll -1 units
	    set ms 250
	}
    } else {
	return ""
    }

    motion $win [::$win nearest $priv(y)] [::$win nearestcolumn $priv(x)] 1
    if {[string length $tablelist::priv(x)] != 0 &&
	[string length $tablelist::priv(y)] != 0} {
	set priv(afterId) [after $ms [list tablelist::autoScan $win]]
    }
}

#------------------------------------------------------------------------------
# tablelist::minScrollableX
#
# Returns the least x coordinate within the scrollable part of the body of the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::minScrollableX win {
    upvar ::tablelist::ns${win}::data data
    if {$data(-titlecolumns) == 0} {
	return 0
    } else {
	set sep [::$win separatorpath]
	if {[winfo viewable $sep]} {
	    return [expr {[winfo x $sep] - [winfo x [::$win bodypath]] + 1}]
	} else {
	    return 0
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::motion
#
# This procedure is called to process mouse motion events in the body of a
# tablelist widget or in one of its separators. while button 1 is down.  It may
# move or extend the selection, depending on the widget's selection mode.
#------------------------------------------------------------------------------
proc tablelist::motion {win row col {checkIfDragSrc 0}} {
    if {$checkIfDragSrc && [isDragSrc $win]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    variable priv
    switch $data(-selecttype) {
	row {
	    set prRow $priv(prevRow)
	    if {$row == $prRow} {
		return ""
	    }

	    switch -- $data(-selectmode) {
		browse {
		    ::$win selection clear 0 end
		    ::$win selection set $row
		    set priv(prevRow) $row
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    if {[string length $prRow] == 0} {
			set prRow $row
			::$win selection set $row
		    }

		    if {[::$win selection includes anchor]} {
			::$win selection clear $prRow $row
			::$win selection set anchor $row
		    } else {
			::$win selection clear $prRow $row
			::$win selection clear anchor $row
		    }

		    set ancRow $data(anchorRow)
		    foreach r $priv(selection) {
			if {($r >= $prRow && $r < $row && $r < $ancRow) ||
			    ($r <= $prRow && $r > $row && $r > $ancRow)} {
			    ::$win selection set $r
			}
		    }

		    set priv(prevRow) $row
		    event generate $win <<TablelistSelect>>
		}
	    }
	}

	cell {
	    set prRow $priv(prevRow)
	    set prCol $priv(prevCol)
	    if {$row == $prRow && $col == $prCol} {
		return ""
	    }

	    switch -- $data(-selectmode) {
		browse {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set $row,$col
		    set priv(prevRow) $row
		    set priv(prevCol) $col
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    if {[string length $prRow] == 0 ||
			[string length $prCol] == 0} {
			set prRow $row
			set prcol $col
			::$win cellselection set $row,$col
		    }

		    set ancRow $data(anchorRow)
		    set ancCol $data(anchorCol)
		    if {[::$win cellselection includes anchor]} {
			::$win cellselection clear $prRow,$prCol $row,$ancCol
			::$win cellselection clear $prRow,$prCol $ancRow,$col
			::$win cellselection set anchor $row,$col
		    } else {
			::$win cellselection clear $prRow,$prCol $row,$ancCol
			::$win cellselection clear $prRow,$prCol $ancRow,$col
			::$win cellselection clear anchor $row,$col
		    }

		    foreach {rMin1 cMin1 rMax1 cMax1} \
			[normalizedRect $prRow $prCol $row $ancCol] {}
		    foreach {rMin2 cMin2 rMax2 cMax2} \
			[normalizedRect $prRow $prCol $ancRow $col] {}
		    foreach {rMin3 cMin3 rMax3 cMax3} \
			[normalizedRect $ancRow $ancCol $row $col] {}
		    foreach cellIdx $priv(selection) {
			scan $cellIdx "%d,%d" r c
			if {([cellInRect $r $c $rMin1 $cMin1 $rMax1 $cMax1] ||
			     [cellInRect $r $c $rMin2 $cMin2 $rMax2 $cMax2]) &&
			    ![cellInRect $r $c $rMin3 $cMin3 $rMax3 $cMax3]} {
			    ::$win cellselection set $r,$c
			}
		    }

		    set priv(prevRow) $row
		    set priv(prevCol) $col
		    event generate $win <<TablelistSelect>>
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::condShowTarget
#
# This procedure is called to process mouse motion events in the body of a
# tablelist widget or in one of its separators. while button 1 is down.  It
# visualizes the would-be target position of the clicked row if a move
# operation is in progress.
#------------------------------------------------------------------------------
proc tablelist::condShowTarget {win y} {
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(sourceRow)]} {
	return ""
    }

    set indentImg [doCellCget $data(sourceRow) $data(treeCol) $win -indent]
    set w $data(body)
    incr y -[winfo y $w]
    set textIdx [$w index @0,$y]
    set dlineinfo [$w dlineinfo $textIdx]
    set lineY [lindex $dlineinfo 1]
    set lineHeight [lindex $dlineinfo 3]
    set row [expr {int($textIdx) - 1}]

    if {$::tk_version < 8.3 || [string length $indentImg] == 0} {
	if {$y < $lineY + $lineHeight/2} {
	    set data(targetRow) $row
	    set gapY $lineY
	} else {
	    set y [expr {$lineY + $lineHeight}]
	    set textIdx [$w index @0,$y]
	    set row2 [expr {int($textIdx) - 1}]
	    if {$row2 == $row} {
		set row2 $data(itemCount)
	    }
	    set data(targetRow) $row2
	    set gapY $y
	}
	set data(targetChildIdx) -1
    } else {
	if {$y < $lineY + $lineHeight/4} {
	    set data(targetRow) $row
	    set data(targetChildIdx) -1
	    set gapY $lineY
	} elseif {$y < $lineY + $lineHeight*3/4} {
	    set data(targetRow) $row
	    set data(targetChildIdx) 0
	    set gapY [expr {$lineY + $lineHeight/2}]
	} else {
	    set y [expr {$lineY + $lineHeight}]
	    set textIdx [$w index @0,$y]
	    set row2 [expr {int($textIdx) - 1}]
	    if {$row2 == $row} {
		set row2 $data(itemCount)
	    }
	    set data(targetRow) $row2
	    set data(targetChildIdx) -1
	    set gapY $y
	}
    }

    #
    # Get the key and node index of the potential target parent
    #
    if {$data(targetRow) > $data(lastRow)} {
	if {$data(targetRow) > $data(sourceParentEndRow)} {
	    set targetParentKey root
	    set targetParentNodeIdx root
	} else {
	    set targetParentKey $data(sourceParentKey)
	    set targetParentNodeIdx $data(sourceParentRow)
	}
    } elseif {$data(targetChildIdx) == 0} {
	set targetParentKey [lindex $data(keyList) $data(targetRow)]
	set targetParentNodeIdx $data(targetRow)
    } else {
	set targetParentKey [::$win parentkey $data(targetRow)]
	set targetParentNodeIdx [keyToRow $win $targetParentKey]
	if {$targetParentNodeIdx < 0} {
	    set targetParentNodeIdx root
	}
    }

    if {($data(targetRow) == $data(sourceRow)) ||

	($data(targetRow) == $data(sourceParentRow) &&
	 $data(targetChildIdx) == 0) ||

	($data(targetRow) == $data(sourceEndRow) &&
	 $data(targetChildIdx) < 0) ||

	($data(targetRow) > $data(sourceRow) &&
	 $data(targetRow) <= $data(sourceRow) + $data(sourceDescCount)) ||

	([string compare $data(sourceParentKey) $targetParentKey] != 0 &&
	 ($::tk_version < 8.3 ||
	  ([string length $data(-acceptchildcommand)] != 0 &&
	   ![uplevel #0 $data(-acceptchildcommand) \
	     [list $win $targetParentNodeIdx $data(sourceRow)]]))) ||

	($data(targetChildIdx) < 0 &&
	 [string length $data(-acceptdropcommand)] != 0 &&
	 ![uplevel #0 $data(-acceptdropcommand) \
	   [list $win $data(targetRow) $data(sourceRow)]])} {

	unset data(targetRow)
	unset data(targetChildIdx)
	$w configure -cursor $data(-cursor)
	place forget $data(rowGap)
    } else {
	$w configure -cursor $data(-movecursor)
	if {$data(targetChildIdx) == 0} {
	    place $data(rowGap) -anchor w -y $gapY -height $lineHeight -width 6
	} else {
	    place $data(rowGap) -anchor w -y $gapY -height 4 \
				-width [winfo width $data(hdrTxtFrm)]
	}
	raise $data(rowGap)
    }
}

#------------------------------------------------------------------------------
# tablelist::moveOrActivate
#
# This procedure is invoked whenever mouse button 1 is released in the body of
# a tablelist widget or in one of its separators.  It either moves the
# previously clicked row before or after the one containing the mouse cursor,
# or activates the given nearest item or element (depending on the widget's
# selection type).
#------------------------------------------------------------------------------
proc tablelist::moveOrActivate {win row col inside} {
    variable priv
    upvar ::tablelist::ns${win}::data data
    if {$priv(selClearPending) && $inside} {
	switch $data(-selecttype) {
	    row {
		if {$row == $priv(prevRow)} {
		    ::$win selection clear $priv(prevRow)
		}
	    }
	    cell {
		if {$row == $priv(prevRow) && $col == $priv(prevCol)} {
		    ::$win cellselection clear $priv(prevRow),$priv(prevCol)
		}
	    }
	}

	event generate $win <<TablelistSelect>>
	set priv(selClearPending) 0
    } elseif {$priv(selChangePending) && $inside} {
	switch $data(-selecttype) {
	    row {
		if {$row == $priv(prevRow)} {
		    ::$win selection clear 0 end
		    ::$win selection set $priv(prevRow)
		}
	    }
	    cell {
		if {$row == $priv(prevRow) && $col == $priv(prevCol)} {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set $priv(prevRow),$priv(prevCol)
		}
	    }
	}

	event generate $win <<TablelistSelect>>
	set priv(selChangePending) 0
    }

    #
    # Return if both <Button-1> and <ButtonRelease-1> occurred in the
    # temporary embedded widget used for interactive cell editing
    #
    if {$priv(clickedInEditWin) && $priv(releasedInEditWin)} {
	return ""
    }

    if {[info exists data(sourceRow)]} {
	set sourceRow $data(sourceRow)
	unset data(sourceRow)
	unset data(sourceEndRow)
	unset data(sourceDescCount)
	unset data(sourceParentKey)
	unset data(sourceParentRow)
	unset data(sourceParentEndRow)
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	$data(body) configure -cursor $data(-cursor)
	place forget $data(rowGap)

	if {[info exists data(targetRow)]} {
	    set sourceKey [lindex $data(keyList) $sourceRow]
	    set targetRow $data(targetRow)
	    unset data(targetRow)

	    if {$targetRow > $data(lastRow)} {
		if {[catch {::$win move $sourceRow $targetRow}] == 0} {
		    set targetParentNodeIdx [::$win parentkey $sourceRow]
		} else {
		    ::$win move $sourceRow root end
		    set targetParentNodeIdx root
		}

		set targetChildIdx [::$win childcount $targetParentNodeIdx]
	    } else {
		set targetChildIdx $data(targetChildIdx)
		unset data(targetChildIdx)

		if {$targetChildIdx == 0} {
		    set targetParentNodeIdx [lindex $data(keyList) $targetRow]
		    ::$win expand $targetParentNodeIdx -partly
		    ::$win move $sourceKey $targetParentNodeIdx $targetChildIdx
		} else {
		    set targetParentNodeIdx [::$win parentkey $targetRow]
		    set targetChildIdx [::$win childindex $targetRow]
		    ::$win move $sourceRow $targetParentNodeIdx $targetChildIdx
		}
	    }

	    set userData [list $sourceKey $targetParentNodeIdx $targetChildIdx]
	    genVirtualEvent $win <<TablelistRowMoved>> $userData

	    switch $data(-selecttype) {
		row  { ::$win activate $sourceKey }
		cell { ::$win activatecell $sourceKey,$col }
	    }

	    return ""
	}
    }

    switch $data(-selecttype) {
	row  { ::$win activate $row }
	cell { ::$win activatecell $row,$col }
    }
}

#------------------------------------------------------------------------------
# tablelist::condEvalInvokeCmd
#
# This procedure is invoked when mouse button 1 is released in the body of a
# tablelist widget win or in one of its separators.  If interactive cell
# editing is in progress in a column whose associated edit window has an invoke
# command that hasn't yet been called in the current edit session, then the
# procedure evaluates that command.
#------------------------------------------------------------------------------
proc tablelist::condEvalInvokeCmd win {
    #
    # This is an "after 100" callback; check whether the window exists
    #
    if {[destroyed $win]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(editCol) < 0} {
	return ""
    }

    variable editWin
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    if {[string length $editWin($name-invokeCmd)] == 0 || $data(invoked)} {
	return ""
    }

    #
    # Return if both <Button-1> and <ButtonRelease-1> occurred in the
    # temporary embedded widget used for interactive cell editing
    #
    variable priv
    if {$priv(clickedInEditWin) && $priv(releasedInEditWin)} {
	return ""
    }

    #
    # Check whether the edit window is a checkbutton,
    # and return if it is an editable combobox widget
    #
    set isCheckbtn 0
    set w $data(bodyFrmEd)
    switch [winfo class $w] {
	Checkbutton -
	TCheckbutton {
	    set isCheckbtn 1
	}
	TCombobox {
	    if {[string compare [$w cget -state] "normal"] == 0} {
		return ""
	    }
	}
	ComboBox -
	Combobox {
	    if {[$w cget -editable]} {
		return ""
	    }
	}
    }

    #
    # Evaluate the edit window's invoke command
    #
    eval [strMap {"%W" "$w"} $editWin($name-invokeCmd)]
    set data(invoked) 1

    #
    # If the edit window is a checkbutton and the value of the
    # -instanttoggle option is true then finish the editing
    #
    if {$isCheckbtn && $data(-instanttoggle)} {
	doFinishEditing $win
    }
}

#------------------------------------------------------------------------------
# tablelist::cancelMove
#
# This procedure is invoked to process <Escape> events in the top-level window
# containing the tablelist widget win during a row move operation.  It cancels
# the action in progress.
#------------------------------------------------------------------------------
proc tablelist::cancelMove win {
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(sourceRow)]} {
	return ""
    }

    unset data(sourceRow)
    unset data(sourceEndRow)
    unset data(sourceDescCount)
    unset data(sourceParentKey)
    unset data(sourceParentRow)
    unset data(sourceParentEndRow)
    if {[info exists data(targetRow)]} {
	unset data(targetRow)
    }
    if {[info exists data(targetChildIdx)]} {
	unset data(targetChildIdx)
    }
    bind [winfo toplevel $win] <Escape> $data(topEscBinding)
    $data(body) configure -cursor $data(-cursor)
    place forget $data(rowGap)
}

#------------------------------------------------------------------------------
# tablelist::beginExtend
#
# This procedure is typically invoked on shift-button-1 presses in the body of
# a tablelist widget or in one of its separators.  It begins the process of
# extending a selection in the widget.  Its exact behavior depends on the
# selection mode currently in effect for the widget.
#------------------------------------------------------------------------------
proc tablelist::beginExtend {win row col} {
    if {[string compare [::$win cget -selectmode] "extended"] != 0} {
	return ""
    }

    if {[::$win selection includes anchor]} {
	motion $win $row $col
    } else {
	beginSelect $win $row $col
    }
}

#------------------------------------------------------------------------------
# tablelist::beginToggle
#
# This procedure is typically invoked on control-button-1 presses in the body
# of a tablelist widget or in one of its separators.  It begins the process of
# toggling a selection in the widget.  Its exact behavior depends on the
# selection mode currently in effect for the widget.
#------------------------------------------------------------------------------
proc tablelist::beginToggle {win row col} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    if {[string compare $data(-selectmode) "extended"] == 0} {
		variable priv
		set priv(selection) [::$win curselection]
		set priv(prevRow) $row
		::$win selection anchor $row
		if {[::$win selection includes $row]} {
		    ::$win selection clear $row
		} else {
		    ::$win selection set $row
		}
	    } else {
		variable strictTk
		if {$strictTk} {
		    return ""
		}

		if {[::$win selection includes $row]} {
		    ::$win selection clear $row
		} else {
		    beginSelect $win $row $col
		    return ""
		}
	    }
	}

	cell {
	    if {[string compare $data(-selectmode) "extended"] == 0} {
		variable priv
		set priv(selection) [::$win curcellselection]
		set priv(prevRow) $row
		set priv(prevCol) $col
		::$win cellselection anchor $row,$col
		if {[::$win cellselection includes $row,$col]} {
		    ::$win cellselection clear $row,$col
		} else {
		    ::$win cellselection set $row,$col
		}
	    } else {
		variable strictTk
		if {$strictTk} {
		    return ""
		}

		if {[::$win cellselection includes $row,$col]} {
		    ::$win cellselection clear $row,$col
		} else {
		    beginSelect $win $row $col
		    return ""
		}
	    }
	}
    }

    event generate $win <<TablelistSelect>>
}

#------------------------------------------------------------------------------
# tablelist::condEditActiveCell
#
# This procedure is invoked whenever Return or KP_Enter is pressed in the body
# of a tablelist widget.  If the selection type is cell and the active cell is
# editable then the procedure starts the interactive editing in that cell.
#------------------------------------------------------------------------------
proc tablelist::condEditActiveCell win {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selecttype) "cell"] != 0 ||
	[firstViewableRow $win] < 0 || [firstViewableCol $win] < 0} {
	return ""
    }

    set row $data(activeRow)
    set col $data(activeCol)
    if {[isCellEditable $win $row $col]} {
	doEditCell $win $row $col 0
    }
}

#------------------------------------------------------------------------------
# tablelist::plusMinus
#
# Partially expands or collapses the active row if possible.
#------------------------------------------------------------------------------
proc tablelist::plusMinus {win keysym} {
    upvar ::tablelist::ns${win}::data data
    set row $data(activeRow)
    set col $data(treeCol)
    set key [lindex $data(keyList) $row]
    set op ""

    if {[info exists data($key,$col-indent)]} {
	set indentLabel $data(body).ind_$key,$col
	set imgName [$indentLabel cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    if {[string compare $keysym "plus"] == 0 &&
		[string compare $mode "collapsed"] == 0} {
		set op "expand"
	    } elseif {[string compare $keysym "minus"] == 0 &&
		      [string compare $mode "expanded"] == 0} {
		set op "collapse"
	    }
	}
    }

    if {[string length $op] != 0} {
	#
	# Toggle the state of the expand/collapse control
	#
	::$win $op $row -partly
    }
}

#------------------------------------------------------------------------------
# tablelist::nextPrevCell
#
# Does nothing unless the selection type is cell; in this case it moves the
# location cursor (active element) to the next or previous element, and changes
# the selection if we are in browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::nextPrevCell {win amount} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    # Nothing
	}

	cell {
	    if {$data(editRow) >= 0} {
		return -code break ""
	    }

	    set row $data(activeRow)
	    set col $data(activeCol)
	    set oldRow $row
	    set oldCol $col

	    while 1 {
		incr col $amount
		if {$col < 0} {
		    incr row $amount
		    if {$row < 0} {
			set row $data(lastRow)
		    }
		    set col $data(lastCol)
		} elseif {$col > $data(lastCol)} {
		    incr row $amount
		    if {$row > $data(lastRow)} {
			set row 0
		    }
		    set col 0
		}

		if {$row == $oldRow && $col == $oldCol} {
		    return -code break ""
		} elseif {[isRowViewable $win $row] && !$data($col-hide)} {
		    condChangeSelection $win $row $col
		    return -code break ""
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::upDown
#
# Moves the location cursor (active item or element) up or down by one line,
# and changes the selection if we are in browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::upDown {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {$data(editRow) >= 0} {
	return ""
    }

    switch $data(-selecttype) {
	row {
	    set row $data(activeRow)
	    set col -1
	}

	cell {
	    set row $data(activeRow)
	    set col $data(activeCol)
	}
    }

    while 1 {
	incr row $amount
	if {$row < 0 || $row > $data(lastRow)} {
	    return ""
	} elseif {[isRowViewable $win $row]} {
	    condChangeSelection $win $row $col
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::leftRight
#
# Partially expands or collapses the active row if possible.  Otherwise, if the
# tablelist widget's selection type is "row" then this procedure scrolls the
# widget's view left or right by the width of the character "0".  Otherwise it
# moves the location cursor (active element) left or right by one column, and
# changes the selection if we are in browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::leftRight {win amount} {
    upvar ::tablelist::ns${win}::data data
    set row $data(activeRow)
    set col $data(treeCol)
    set key [lindex $data(keyList) $row]
    set op ""

    if {[info exists data($key,$col-indent)]} {
	set indentLabel $data(body).ind_$key,$col
	set imgName [$indentLabel cget -image]
	if {[regexp {^tablelist_(.+)_(collapsed|expanded).*Img([0-9]+)$} \
		     $imgName dummy treeStyle mode depth]} {
	    if {$amount > 0 && [string compare $mode "collapsed"] == 0} {
		set op "expand"
	    } elseif {$amount < 0 && [string compare $mode "expanded"] == 0} {
		set op "collapse"
	    }
	}
    }

    if {[string length $op] == 0} {
	switch $data(-selecttype) {
	    row {
		::$win xview scroll $amount units
	    }

	    cell {
		if {$data(editRow) >= 0} {
		    return ""
		}

		set col $data(activeCol)
		while 1 {
		    incr col $amount
		    if {$col < 0 || $col > $data(lastCol)} {
			return ""
		    } elseif {!$data($col-hide)} {
			condChangeSelection $win $row $col
			return ""
		    }
		}
	    }
	}
    } else {
	#
	# Toggle the state of the expand/collapse control
	#
	::$win $op $row -partly
    }
}

#------------------------------------------------------------------------------
# tablelist::priorNext
#
# Scrolls the tablelist view up or down by one page.
#------------------------------------------------------------------------------
proc tablelist::priorNext {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {$data(editRow) >= 0} {
	return ""
    }

    ::$win yview scroll $amount pages
    ::$win activate @0,0
    update idletasks
}

#------------------------------------------------------------------------------
# tablelist::homeEnd
#
# If selecttype is row then the procedure scrolls the tablelist widget
# horizontally to its left or right edge.  Otherwise it sets the location
# cursor (active element) to the first/last element of the active row, selects
# that element, and deselects everything else in the widget.
#------------------------------------------------------------------------------
proc tablelist::homeEnd {win keysym} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    switch $keysym {
		Home { ::$win xview moveto 0 }
		End  { ::$win xview moveto 1 }
	    }
	}

	cell {
	    set row $data(activeRow)
	    switch $keysym {
		Home { set col [firstViewableCol $win] }
		End  { set col [ lastViewableCol $win] }
	    }
	    changeSelection $win $row $col
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::firstLast
#
# Sets the location cursor (active item or element) to the first/last item or
# element in the tablelist widget, selects that item or element, and deselects
# everything else in the widget.
#------------------------------------------------------------------------------
proc tablelist::firstLast {win target} {
    switch $target {
	first {
	    set row [firstViewableRow $win]
	    set col [firstViewableCol $win]
	}

	last {
	    set row [lastViewableRow $win]
	    set col [lastViewableCol $win]
	}
    }

    changeSelection $win $row $col
}

#------------------------------------------------------------------------------
# tablelist::extendUpDown
#
# Does nothing unless we are in extended selection mode; in this case it moves
# the location cursor (active item or element) up or down by one line, and
# extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendUpDown {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selectmode) "extended"] != 0} {
	return ""
    }

    switch $data(-selecttype) {
	row {
	    set row $data(activeRow)
	    while 1 {
		incr row $amount
		if {$row < 0 || $row > $data(lastRow)} {
		    return ""
		} elseif {[isRowViewable $win $row]} {
		    ::$win activate $row
		    ::$win see active
		    motion $win $data(activeRow) -1
		    return ""
		}
	    }
	}

	cell {
	    set row $data(activeRow)
	    set col $data(activeCol)
	    while 1 {
		incr row $amount
		if {$row < 0 || $row > $data(lastRow)} {
		    return ""
		} elseif {[isRowViewable $win $row]} {
		    ::$win activatecell $row,$col
		    ::$win seecell active
		    motion $win $data(activeRow) $data(activeCol)
		    return ""
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::extendLeftRight
#
# Does nothing unless we are in extended selection mode and the selection type
# is cell; in this case it moves the location cursor (active element) left or
# right by one column, and extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendLeftRight {win amount} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selectmode) "extended"] != 0} {
	return ""
    }

    switch $data(-selecttype) {
	row {
	    # Nothing
	}

	cell {
	    set row $data(activeRow)
	    set col $data(activeCol)
	    while 1 {
		incr col $amount
		if {$col < 0 || $col > $data(lastCol)} {
		    return ""
		} elseif {!$data($col-hide)} {
		    ::$win activatecell $row,$col
		    ::$win seecell active
		    motion $win $data(activeRow) $data(activeCol)
		    return ""
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::extendToHomeEnd
#
# Does nothing unless the selection mode is multiple or extended and the
# selection type is cell; in this case it moves the location cursor (active
# element) to the first/last element of the active row, and, if we are in
# extended mode, it extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendToHomeEnd {win keysym} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    # Nothing
	}

	cell {
	    set row $data(activeRow)
	    switch $keysym {
		Home { set col [firstViewableCol $win] }
		End  { set col [ lastViewableCol $win] }
	    }

	    switch -- $data(-selectmode) {
		multiple {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		}
		extended {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		    if {[::$win selection includes anchor]} {
			motion $win $row $col
		    }
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::extendToFirstLast
#
# Does nothing unless the selection mode is multiple or extended; in this case
# it moves the location cursor (active item or element) to the first/last item
# or element in the tablelist widget, and, if we are in extended mode, it
# extends the selection to that point.
#------------------------------------------------------------------------------
proc tablelist::extendToFirstLast {win target} {
    switch $target {
	first {
	    set row [firstViewableRow $win]
	    set col [firstViewableCol $win]
	}

	last {
	    set row [lastViewableRow $win]
	    set col [lastViewableCol $win]
	}
    }

    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    switch -- $data(-selectmode) {
		multiple {
		    ::$win activate $row
		    ::$win see $row
		}
		extended {
		    ::$win activate $row
		    ::$win see $row
		    if {[::$win selection includes anchor]} {
			motion $win $row -1
		    }
		}
	    }
	}

	cell {
	    switch -- $data(-selectmode) {
		multiple {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		}
		extended {
		    ::$win activatecell $row,$col
		    ::$win seecell $row,$col
		    if {[::$win selection includes anchor]} {
			motion $win $row $col
		    }
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::cancelSelection
#
# This procedure is invoked to cancel an extended selection in progress.  If
# there is an extended selection in progress, it restores all of the elements
# to their previous selection state.
#------------------------------------------------------------------------------
proc tablelist::cancelSelection win {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $data(-selectmode) "extended"] != 0} {
	return ""
    }

    variable priv
    switch $data(-selecttype) {
	row {
	    if {[string length $priv(prevRow)] == 0} {
		return ""
	    }

	    ::$win selection clear 0 end
	    foreach row $priv(selection) {
		::$win selection set $row
	    }
	    event generate $win <<TablelistSelect>>
	}

	cell {
	    if {[string length $priv(prevRow)] == 0 ||
		[string length $priv(prevCol)] == 0} {
		return ""
	    }

	    ::$win selection clear 0 end
	    foreach cellIdx $priv(selection) {
		::$win cellselection set $cellIdx
	    }
	    event generate $win <<TablelistSelect>>
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::selectAll
#
# This procedure is invoked to handle the "select all" operation.  For single
# and browse mode, it just selects the active item or element.  Otherwise it
# selects everything in the widget.
#------------------------------------------------------------------------------
proc tablelist::selectAll win {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    if {[string compare $data(-selectmode) "single"] == 0 ||
		[string compare $data(-selectmode) "browse"] == 0} {
		::$win selection clear 0 end
		::$win selection set active
	    } else {
		::$win selection set 0 end
	    }
	}

	cell {
	    if {[string compare $data(-selectmode) "single"] == 0 ||
		[string compare $data(-selectmode) "browse"] == 0} {
		::$win cellselection clear 0,0 end
		::$win cellselection set active
	    } else {
		::$win cellselection set 0,0 end
	    }
	}
    }

    event generate $win <<TablelistSelect>>
}

#------------------------------------------------------------------------------
# tablelist::isDragSrc
#
# Checks whether the body component of the tablelist widget win is a BWidget or
# TkDND drag source for mouse button 1.
#------------------------------------------------------------------------------
proc tablelist::isDragSrc win {
    upvar ::tablelist::ns${win}::data data
    set bindTags [bindtags $data(body)]
    return [expr {[info exists data(sourceRow)] || $data(-customdragsource) ||
		  [lsearch -exact $bindTags "BwDrag1"] >= 0 ||
		  [lsearch -exact $bindTags "TkDND_Drag1"] >= 0
    }]
}

#------------------------------------------------------------------------------
# tablelist::normalizedRect
#
# Returns a list of the form {minRow minCol maxRow maxCol}, built from the
# given arguments.
#------------------------------------------------------------------------------
proc tablelist::normalizedRect {row1 col1 row2 col2} {
    if {$row1 <= $row2} {
	set minRow $row1
	set maxRow $row2
    } else {
	set minRow $row2
	set maxRow $row1
    }

    if {$col1 <= $col2} {
	set minCol $col1
	set maxCol $col2
    } else {
	set minCol $col2
	set maxCol $col1
    }

    return [list $minRow $minCol $maxRow $maxCol]
}

#------------------------------------------------------------------------------
# tablelist::cellInRect
#
# Checks whether the cell row,col is contained in the given rectangular range.
#------------------------------------------------------------------------------
proc tablelist::cellInRect {row col minRow minCol maxRow maxCol} {
    return [expr {$row >= $minRow && $row <= $maxRow &&
		  $col >= $minCol && $col <= $maxCol}]
}

#------------------------------------------------------------------------------
# tablelist::firstViewableRow
#
# Returns the index of the first viewable row of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::firstViewableRow win {
    upvar ::tablelist::ns${win}::data data
    for {set row 0} {$row < $data(itemCount)} {incr row} {
	if {[isRowViewable $win $row]} {
	    return $row
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::lastViewableRow
#
# Returns the index of the last viewable row of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::lastViewableRow win {
    upvar ::tablelist::ns${win}::data data
    for {set row $data(lastRow)} {$row >= 0} {incr row -1} {
	if {[isRowViewable $win $row]} {
	    return $row
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::firstViewableCol
#
# Returns the index of the first non-hidden column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::firstViewableCol win {
    upvar ::tablelist::ns${win}::data data
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {!$data($col-hide)} {
	    return $col
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::lastViewableCol
#
# Returns the index of the last non-hidden column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::lastViewableCol win {
    upvar ::tablelist::ns${win}::data data
    for {set col $data(lastCol)} {$col >= 0} {incr col -1} {
	if {!$data($col-hide)} {
	    return $col
	}
    }

    return -1
}

#------------------------------------------------------------------------------
# tablelist::condChangeSelection
#
# Activates the given item or element, and selects it exclusively if we are in
# browse or extended selection mode.
#------------------------------------------------------------------------------
proc tablelist::condChangeSelection {win row col} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    ::$win activate $row
	    ::$win see active

	    switch -- $data(-selectmode) {
		browse {
		    ::$win selection clear 0 end
		    ::$win selection set active
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    ::$win selection clear 0 end
		    ::$win selection set active
		    ::$win selection anchor active
		    variable priv
		    set priv(selection) {}
		    set priv(prevRow) $data(activeRow)
		    event generate $win <<TablelistSelect>>
		}
	    }
	}

	cell {
	    ::$win activatecell $row,$col
	    ::$win seecell active

	    switch -- $data(-selectmode) {
		browse {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set active
		    event generate $win <<TablelistSelect>>
		}
		extended {
		    ::$win cellselection clear 0,0 end
		    ::$win cellselection set active
		    ::$win cellselection anchor active
		    variable priv
		    set priv(selection) {}
		    set priv(prevRow) $data(activeRow)
		    set priv(prevCol) $data(activeCol)
		    event generate $win <<TablelistSelect>>
		}
	    }
	}
    }

    update idletasks
}

#------------------------------------------------------------------------------
# tablelist::changeSelection
#
# Activates the given item or element and selects it exclusively.
#------------------------------------------------------------------------------
proc tablelist::changeSelection {win row col} {
    upvar ::tablelist::ns${win}::data data
    switch $data(-selecttype) {
	row {
	    ::$win activate $row
	    ::$win see active

	    ::$win selection clear 0 end
	    ::$win selection set active
	}

	cell {
	    ::$win activatecell $row,$col
	    ::$win seecell active

	    ::$win cellselection clear 0,0 end
	    ::$win cellselection set active
	}
    }

    event generate $win <<TablelistSelect>>
}

#
# Binding tag TablelistHeader
# ===========================
#

#------------------------------------------------------------------------------
# tablelist::defineTablelistHeader
#
# Defines the bindings for the binding tag TablelistHeader.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistHeader {} {
    foreach event {<Enter> <Motion> <Leave>} {
	bind TablelistHeader $event {
	    tablelist::hdr_handleMotionDelayed %W %x %y %X %Y
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_handleMotionDelayed
#
# This procedure is invoked when the mouse pointer enters or leaves the header
# text widget of a tablelist widget or is moving within it.  It schedules the
# execution of the hdr_handleMotion procedure 100 ms later.
#------------------------------------------------------------------------------
proc tablelist::hdr_handleMotionDelayed {w x y X Y} {
    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data
    if {[regexp {^vsep([0-9]+)?$} [winfo name $w]]} {
	return ""
    }

    set data(hdr_motionData) [list $w $x $y $X $Y]
    if {![info exists data(hdr_motionId)]} {
	set data(hdr_motionId) \
	    [after 100 [list tablelist::hdr_handleMotion $win]]
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_handleMotion
#
# Invokes the procedure hdr_showOrHideTooltip.
#------------------------------------------------------------------------------
proc tablelist::hdr_handleMotion win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(hdr_motionId)]} {
	after cancel $data(hdr_motionId)
	unset data(hdr_motionId)
    }

    #
    # Get the containing header cell from the
    # coordinates relative to the tablelist
    #
    foreach {w x y X Y} $data(hdr_motionData) {}
    foreach {win _x _y} [convEventFields $w $x $y] {}
    set row [hdr_containingRow $win $_y]
    set col [containingCol $win $_x]

    hdr_showOrHideTooltip $win $row $col $X $Y
}

#------------------------------------------------------------------------------
# tablelist::hdr_showOrHideTooltip
#
# If the pointer has crossed a header cell boundary then the procedure removes
# the old tooltip and displays the one corresponding to the new cell.
#------------------------------------------------------------------------------
proc tablelist::hdr_showOrHideTooltip {win row col X Y} {
    upvar ::tablelist::ns${win}::data data
    if {[string length $data(-tooltipaddcommand)] == 0 ||
	[string length $data(-tooltipdelcommand)] == 0 ||
	[string compare $row,$col $data(hdr_prevCell)] == 0} {
	return ""
    }

    #
    # Remove the old tooltip, if any.  Then, if we are within a
    # cell, display the new tooltip corresponding to that cell.
    #
    event generate $win <Leave>
    catch {uplevel #0 $data(-tooltipdelcommand) [list $win]}
    if {[destroyed $win]} {
	return ""
    }
    set data(hdr_prevCell) $row,$col
    if {$row >= 0 && $col >= 0} {
	set focus [focus -displayof $win]
	if {[string length $focus] == 0 || [string first $win $focus] != 0 ||
	    [string compare [winfo toplevel $focus] \
	     [winfo toplevel $win]] == 0} {
	    uplevel #0 $data(-tooltipaddcommand) [list $win h$row $col]
	    if {[destroyed $win]} {
		return ""
	    }
	    event generate $win <Enter> -rootx $X -rooty $Y
	}
    }
}

#
# Binding tags TablelistLabel, TablelistSubLabel, and TablelistArrow
# ==================================================================
#

#------------------------------------------------------------------------------
# tablelist::defineTablelistLabel
#
# Defines the bindings for the binding tag TablelistLabel.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistLabel {} {
    bind TablelistLabel <Enter> {
	tablelist::labelEnter %W %X %Y %x
    }
    bind TablelistLabel <Motion> {
	tablelist::labelEnter %W %X %Y %x
    }
    bind TablelistLabel <Leave> {
	tablelist::labelLeave %W %X %x %y
    }
    bind TablelistLabel <Button-1> {
	tablelist::labelB1Down %W %x 0
    }
    bind TablelistLabel <Shift-Button-1> {
	tablelist::labelB1Down %W %x 1
    }
    bind TablelistLabel <B1-Motion> {
	tablelist::labelB1Motion %W %X %x %y
    }
    bind TablelistLabel <B1-Enter> {
	tablelist::labelB1Enter %W
    }
    bind TablelistLabel <B1-Leave> {
	tablelist::labelB1Leave %W %x %y
    }
    bind TablelistLabel <ButtonRelease-1> {
	tablelist::labelB1Up %W %X
    }
    bind TablelistLabel <<Button3>> {
	tablelist::labelB3Down %W 0
    }
    bind TablelistLabel <<ShiftButton3>> {
	tablelist::labelB3Down %W 1
    }
    bind TablelistLabel <Double-Button-1> {
	tablelist::labelDblB1 %W %x 0
    }
    bind TablelistLabel <Shift-Double-Button-1> {
	tablelist::labelDblB1 %W %x 1
    }
}

#------------------------------------------------------------------------------
# tablelist::defineTablelistSubLabel
#
# Defines the binding tag TablelistSubLabel (for sublabels of tablelist labels)
# to have the same events as TablelistLabel and the binding scripts obtained
# from those of TablelistLabel by replacing the widget %W with the containing
# label as well as the %x and %y fields with the corresponding coordinates
# relative to that label.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistSubLabel {} {
    foreach event [bind TablelistLabel] {
	set script [strMap {
	    "%W" "$tablelist::W"  "%x" "$tablelist::x"  "%y" "$tablelist::y"
	} [bind TablelistLabel $event]]

	bind TablelistSubLabel $event [format {
	    set tablelist::W \
		[string range %%W 0 [expr {[string length %%W] - 4}]]
	    set tablelist::x \
		[expr {%%x + [winfo x %%W] - [winfo x $tablelist::W]}]
	    set tablelist::y \
		[expr {%%y + [winfo y %%W] - [winfo y $tablelist::W]}]
	    %s
	} $script]
    }
}

#------------------------------------------------------------------------------
# tablelist::defineTablelistArrow
#
# Defines the binding tag TablelistArrow (for sort arrows) to have the same
# events as TablelistLabel and the binding scripts obtained from those of
# TablelistLabel by replacing the widget %W with the containing label as well
# as the %x and %y fields with the corresponding coordinates relative to that
# label.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistArrow {} {
    foreach event [bind TablelistLabel] {
	set script [strMap {
	    "%W" "$tablelist::W"  "%x" "$tablelist::x"  "%y" "$tablelist::y"
	} [bind TablelistLabel $event]]

	bind TablelistArrow $event [format {
	    set tablelist::W \
		[winfo parent %%W].l[string range [winfo name %%W] 1 end]
	    set tablelist::x \
		[expr {%%x + [winfo x %%W] - [winfo x $tablelist::W]}]
	    set tablelist::y \
		[expr {%%y + [winfo y %%W] - [winfo y $tablelist::W]}]
	    %s
	} $script]
    }
}

#------------------------------------------------------------------------------
# tablelist::labelEnter
#
# This procedure is invoked when the mouse pointer enters the header label w of
# a tablelist widget, or is moving within that label.  It updates the cursor,
# displays the tooltip, and activates or deactivates the label, depending on
# whether the pointer is on its right border or not.
#------------------------------------------------------------------------------
proc tablelist::labelEnter {w X Y x} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    configLabel $w -cursor $data(-cursor)

    if {[string length $data(-tooltipaddcommand)] != 0 &&
	[string length $data(-tooltipdelcommand)] != 0 &&
	$col != $data(prevCol)} {
	#
	# Display the tooltip corresponding to this label
	#
	event generate $win <Leave>
	catch {uplevel #0 $data(-tooltipdelcommand) [list $win]}
	if {[destroyed $win]} {
	    return ""
	}
	set data(prevCol) $col
	set focus [focus -displayof $win]
	if {[string length $focus] == 0 ||
	    [string first $win $focus] != 0 ||
	    [string compare [winfo toplevel $focus] \
	     [winfo toplevel $win]] == 0} {
	    uplevel #0 $data(-tooltipaddcommand) [list $win -1 $col]
	    if {[destroyed $win]} {
		return ""
	    }
	    event generate $win <Enter> -rootx $X -rooty $Y
	}
    }

    if {$data(isDisabled)} {
	return ""
    }

    if {[inResizeArea $w $x col] &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	configLabel $w -cursor $data(-resizecursor)
	configLabel $w -active 0
    } else {
	configLabel $w -active 1
    }
}

#------------------------------------------------------------------------------
# tablelist::labelLeave
#
# This procedure is invoked when the mouse pointer leaves the header label w of
# a tablelist widget.  It removes the tooltip and deactivates the label.
#------------------------------------------------------------------------------
proc tablelist::labelLeave {w X x y} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    #
    # The following code is needed because the event
    # can also occur in a widget placed into the label
    #
    upvar ::tablelist::ns${win}::data data
    set data(hdr_prevCell) -1,-1
    set hdrX [winfo rootx $data(hdr)]
    if {$X >= $hdrX && $X < $hdrX + [winfo width $data(hdr)] &&
	$x >= 1 && $x < [winfo width $w] - 1 &&
	$y >= 0 && $y < [winfo height $w]} {
	return ""
    }

    if {[string length $data(-tooltipaddcommand)] != 0 &&
	[string length $data(-tooltipdelcommand)] != 0} {
	#
	# Remove the tooltip, if any
	#
	event generate $win <Leave>
	catch {uplevel #0 $data(-tooltipdelcommand) [list $win]}
	if {[destroyed $win]} {
	    return ""
	}
	set data(prevCol) -1
    }

    if {$data(isDisabled)} {
	return ""
    }

    configLabel $w -active 0
}

#------------------------------------------------------------------------------
# tablelist::labelB1Down
#
# This procedure is invoked when mouse button 1 is pressed in the header label
# w of a tablelist widget.  If the pointer is on the right border of the label
# then the procedure records its x-coordinate relative to the label, the width
# of the column, and some other data needed later.  Otherwise it saves the
# label's relief so it can be restored later, and changes the relief to sunken.
#------------------------------------------------------------------------------
proc tablelist::labelB1Down {w x shiftPressed} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) ||
	[info exists data(colBeingResized)]} {	;# resize operation in progress
	return ""
    }

    set data(labelClicked) 1
    set data(X) [expr {[winfo rootx $w] + $x}]
    set data(shiftPressed) $shiftPressed

    if {[inResizeArea $w $x col] &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	set data(colBeingResized) $col
	set data(colResized) 0

	set w $data(body)
	set topTextIdx [$w index @0,0]
	set btmTextIdx [$w index @0,[expr {[winfo height $w] - 1}]]
	$w tag add visibleLines "$topTextIdx linestart" "$btmTextIdx lineend"
	set data(topRow) [expr {int($topTextIdx) - 1}]
	set data(btmRow) [expr {int($btmTextIdx) - 1}]

	set w $data(hdrTxtFrmLbl)$col
	set labelWidth [winfo width $w]
	set data(oldStretchedColWidth) [expr {$labelWidth - 2*$data(charWidth)}]
	set data(oldColDelta) $data($col-delta)
	set data(configColWidth) [lindex $data(-columns) [expr {3*$col}]]

	if {[lsearch -exact $data(arrowColList) $col] >= 0} {
	    set canvasWidth $data(arrowWidth)
	    if {[llength $data(arrowColList)] > 1} {
		incr canvasWidth 6
	    }
	    set data(minColWidth) $canvasWidth
	} elseif {$data($col-wrap)} {
	    set data(minColWidth) $data(charWidth)
	} else {
	    set data(minColWidth) 0
	}
	incr data(minColWidth)

	set data(focus) [focus -displayof $win]
	set topWin [winfo toplevel $win]
	focus $topWin
	set data(topEscBinding) [bind $topWin <Escape>]
	bind $topWin <Escape> \
	     [list tablelist::escape [strMap {"%" "%%"} $win] $col]
    } else {
	set data(inClickedLabel) 1
	set data(relief) [$w cget -relief]

	if {[info exists data($col-labelcommand)] ||
	    [string length $data(-labelcommand)] != 0} {
	    set data(changeRelief) 1
	    configLabel $w -relief sunken -pressed 1
	} else {
	    set data(changeRelief) 0
	}

	if {$data(-movablecolumns)} {
	    set data(focus) [focus -displayof $win]
	    set topWin [winfo toplevel $win]
	    focus $topWin
	    set data(topEscBinding) [bind $topWin <Escape>]
	    bind $topWin <Escape> \
		 [list tablelist::escape [strMap {"%" "%%"} $win] $col]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::labelB1Motion
#
# This procedure is invoked to process mouse motion events in the header label
# w of a tablelist widget while button 1 is down.  If this event occured during
# a column resize operation then the procedure computes the difference between
# the pointer's new x-coordinate relative to that label and the one recorded by
# the last invocation of labelB1Down, and adjusts the width of the
# corresponding column accordingly.  Otherwise a horizontal scrolling is
# performed if needed, and the would-be target position of the clicked label is
# visualized if the columns are movable.
#------------------------------------------------------------------------------
proc tablelist::labelB1Motion {w X x y} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked)} {
	return ""
    }

    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	set width [expr {$data(oldStretchedColWidth) + $X - $data(X)}]
	if {$width >= $data(minColWidth)} {
	    set col $data(colBeingResized)
	    set data(colResized) 1
	    set idx [expr {3*$col}]
	    set data(-columns) [lreplace $data(-columns) $idx $idx -$width]
	    set idx [expr {2*$col}]
	    set data(colList) [lreplace $data(colList) $idx $idx $width]
	    set data($col-lastStaticWidth) $width
	    set data($col-delta) 0
	    redisplayCol $win $col $data(topRow) $data(btmRow)

	    #
	    # Handle the case that the bottom row has become
	    # greater (due to the redisplayCol invocation)
	    #
	    set b $data(body)
	    set btmTextIdx [$b index @0,$data(btmY)]
	    set btmRow [expr {int($btmTextIdx) - 1}]
	    if {$btmRow > $data(lastRow)} {
		set btmRow $data(lastRow)
	    }
	    while {$btmRow > $data(btmRow)} {
		$b tag add visibleLines [expr {$data(btmRow) + 2}].0 \
					"$btmTextIdx lineend"
		incr data(btmRow)
		redisplayCol $win $col $data(btmRow) $btmRow
		set data(btmRow) $btmRow

		set btmTextIdx [$b index @0,$data(btmY)]
		set btmRow [expr {int($btmTextIdx) - 1}]
		if {$btmRow > $data(lastRow)} {
		    set btmRow $data(lastRow)
		}
	    }

	    #
	    # Handle the case that the top row has become
	    # less (due to the redisplayCol invocation)
	    #
	    set topTextIdx [$b index @0,0]
	    set topRow [expr {int($topTextIdx) - 1}]
	    while {$topRow < $data(topRow)} {
		$b tag add visibleLines "$topTextIdx linestart" \
					$data(topRow).end
		incr data(topRow) -1
		redisplayCol $win $col $topRow $data(topRow)
		set data(topRow) $topRow

		set topTextIdx [$b index @0,0]
		set topRow [expr {int($topTextIdx) - 1}]
	    }

	    adjustColumns $win {} 0
	    adjustElidedText $win
	    redisplayVisibleItems $win
	    updateColors $win
	    updateVScrlbarWhenIdle $win
	}
    } else {
	#
	# Scroll the window horizontally if needed
	#
	set hdrX [winfo rootx $data(hdr)]
	if {$data(-titlecolumns) == 0 || ![winfo viewable $data(vsep)]} {
	    set leftX $hdrX
	} else {
	    set leftX [expr {[winfo rootx $data(vsep)] + 1}]
	}
	set rightX [expr {$hdrX + [winfo width $data(hdr)]}]
	set scroll 0
	if {($X >= $rightX && $data(X) < $rightX) ||
	    ($X < $leftX && $data(X) >= $leftX)} {
	    set scroll 1
	} elseif {($X < $rightX && $data(X) >= $rightX) ||
		  ($X >= $leftX && $data(X) < $leftX)} {
	    after cancel $data(afterId)
	    set data(afterId) ""
	}
	set data(X) $X
	if {$scroll} {
	    horizAutoScan $win
	}

	if {$x >= 1 && $x < [winfo width $w] - 1 &&
	    $y >= 0 && $y < [winfo height $w]} {
	    #
	    # The following code is needed because the event
	    # can also occur in a widget placed into the label
	    #
	    set data(inClickedLabel) 1
	    configLabel $w -cursor $data(-cursor)
	    $data(hdrTxtFrmCanv)$col configure -cursor $data(-cursor)
	    if {$data(changeRelief)} {
		configLabel $w -relief sunken -pressed 1
	    }

	    place forget $data(colGap)
	} else {
	    #
	    # The following code is needed because the event
	    # can also occur in a widget placed into the label
	    #
	    set data(inClickedLabel) 0
	    configLabel $w -relief $data(relief) -pressed 0

	    if {$data(-movablecolumns)} {
		#
		# Get the target column index
		#
		set contW [winfo containing -displayof $w $X [winfo rooty $w]]
		if {[parseLabelPath $contW dummy targetCol]} {
		    set master $contW
		    if {$X < [winfo rootx $contW] + [winfo width $contW]/2} {
			set relx 0.0
		    } else {
			incr targetCol
			set relx 1.0
		    }
		} elseif {[string compare $contW $data(colGap)] == 0} {
		    set targetCol $data(targetCol)
		    set master $data(master)
		    set relx $data(relx)
		} elseif {$X >= $rightX || $X >= [winfo rootx $w]} {
		    for {set targetCol $data(lastCol)} {$targetCol >= 0} \
			{incr targetCol -1} {
			if {!$data($targetCol-hide)} {
			    break
			}
		    }
		    incr targetCol
		    set master $data(hdrTxtFrm)
		    set relx 1.0
		} else {
		    for {set targetCol 0} {$targetCol < $data(colCount)} \
			{incr targetCol} {
			if {!$data($targetCol-hide)} {
			    break
			}
		    }
		    set master $data(hdrTxtFrm)
		    set relx 0.0
		}

		#
		# Visualize the would-be target position
		# of the clicked label if appropriate
		#
		if {$targetCol == $col || $targetCol == $col + 1 ||
		    ($data(-protecttitlecolumns) &&
		     (($col >= $data(-titlecolumns) &&
		       $targetCol < $data(-titlecolumns)) ||
		      ($col < $data(-titlecolumns) &&
		       $targetCol > $data(-titlecolumns))))} {
		    if {[info exists data(targetCol)]} {
			unset data(targetCol)
		    }
		    configLabel $w -cursor $data(-cursor)
		    $data(hdrTxtFrmCanv)$col configure -cursor $data(-cursor)
		    place forget $data(colGap)
		} else {
		    set data(targetCol) $targetCol
		    set data(master) $master
		    set data(relx) $relx
		    configLabel $w -cursor $data(-movecolumncursor)
		    $data(hdrTxtFrmCanv)$col configure -cursor \
					    $data(-movecolumncursor)
		    place $data(colGap) -in $master -anchor n \
					-bordermode outside \
					-relheight 1.0 -relx $relx
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::labelB1Enter
#
# This procedure is invoked when the mouse pointer enters the header label w of
# a tablelist widget while mouse button 1 is down.  If the label was not
# previously clicked then nothing happens.  Otherwise, if this event occured
# during a column resize operation then the procedure updates the mouse cursor
# accordingly.  Otherwise it changes the label's relief to sunken.
#------------------------------------------------------------------------------
proc tablelist::labelB1Enter w {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked)} {
	return ""
    }

    configLabel $w -cursor $data(-cursor)

    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	configLabel $w -cursor $data(-resizecursor)
    } else {
	set data(inClickedLabel) 1
	if {$data(changeRelief)} {
	    configLabel $w -relief sunken -pressed 1
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::labelB1Leave
#
# This procedure is invoked when the mouse pointer leaves the header label w of
# a tablelist widget while mouse button 1 is down.  If the label was not
# previously clicked then nothing happens.  Otherwise, if no column resize
# operation is in progress then the procedure restores the label's relief, and,
# if the columns are movable, then it changes the mouse cursor, too.
#------------------------------------------------------------------------------
proc tablelist::labelB1Leave {w x y} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked) ||
	[info exists data(colBeingResized)]} {	;# resize operation in progress
	return ""
    }

    #
    # The following code is needed because the event
    # can also occur in a widget placed into the label
    #
    if {$x >= 1 && $x < [winfo width $w] - 1 &&
	$y >= 0 && $y < [winfo height $w]} {
	return ""
    }

    set data(inClickedLabel) 0
    configLabel $w -relief $data(relief) -pressed 0
}

#------------------------------------------------------------------------------
# tablelist::labelB1Up
#
# This procedure is invoked when mouse button 1 is released, if it was
# previously clicked in a label of the tablelist widget win.  If this event
# occured during a column resize operation then the procedure redisplays the
# column and stretches the stretchable columns.  Otherwise, if the mouse button
# was released in the previously clicked label then the procedure restores the
# label's relief and invokes the command specified by the -labelcommand or
# -labelcommand2 configuration option, passing to it the widget name and the
# column number as arguments.  Otherwise the column of the previously clicked
# label is moved before the column containing the mouse cursor or to its right,
# if the columns are movable.
#------------------------------------------------------------------------------
proc tablelist::labelB1Up {w X} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(labelClicked)} {
	return ""
    }

    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	configLabel $w -cursor $data(-cursor)
	if {[winfo exists $data(focus)]} {
	    focus $data(focus)
	}
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	set col $data(colBeingResized)
	if {$data(colResized)} {
	    if {$data(-width) <= 0} {
		$data(hdr) configure -width $data(hdrWidth)
		$data(lb) configure -width \
			  [expr {$data(hdrWidth) / $data(charWidth)}]
	    } elseif {[info exists data(stretchableCols)] &&
		      [lsearch -exact $data(stretchableCols) $col] >= 0} {
		set oldColWidth \
		    [expr {$data(oldStretchedColWidth) - $data(oldColDelta)}]
		set stretchedColWidth \
		    [expr {$data(oldStretchedColWidth) + $X - $data(X)}]
		if {$oldColWidth < $data(stretchablePixels) &&
		    $stretchedColWidth >= $data(minColWidth) &&
		    $stretchedColWidth < $oldColWidth + $data(delta)} {
		    #
		    # Compute the new column width,
		    # using the following equations:
		    #
		    # $colWidth = $stretchedColWidth - $colDelta
		    # $colDelta / $colWidth =
		    #    ($data(delta) - $colWidth + $oldColWidth) /
		    #    ($data(stretchablePixels) + $colWidth - $oldColWidth)
		    #
		    set colWidth [expr {
			$stretchedColWidth *
			($data(stretchablePixels) - $oldColWidth) /
			($data(stretchablePixels) + $data(delta) -
			 $stretchedColWidth)
		    }]
		    if {$colWidth < 1} {
			set colWidth 1
		    }
		    set idx [expr {3*$col}]
		    set data(-columns) \
			[lreplace $data(-columns) $idx $idx -$colWidth]
		    set idx [expr {2*$col}]
		    set data(colList) \
			[lreplace $data(colList) $idx $idx $colWidth]
		    set data($col-delta) [expr {$stretchedColWidth - $colWidth}]
		}
	    }
	}
	unset data(colBeingResized)
	$data(body) tag remove visibleLines 1.0 end
	$data(body) tag configure visibleLines -tabs {}

	if {$data(colResized)} {
	    redisplayCol $win $col 0 last
	    adjustColumns $win {} 0
	    stretchColumns $win $col
	    updateColors $win

	    genVirtualEvent $win <<TablelistColumnResized>> $col
	}
    } else {
	if {[info exists data(X)]} {
	    unset data(X)
	    after cancel $data(afterId)
	    set data(afterId) ""
	}
    	if {$data(-movablecolumns)} {
	    if {[winfo exists $data(focus)]} {
		focus $data(focus)
	    }
	    bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	    place forget $data(colGap)
	}

	if {$data(inClickedLabel)} {
	    configLabel $w -relief $data(relief) -pressed 0
	    if {$data(shiftPressed)} {
		if {[info exists data($col-labelcommand2)]} {
		    uplevel #0 $data($col-labelcommand2) [list $win $col]
		} elseif {[string length $data(-labelcommand2)] != 0} {
		    uplevel #0 $data(-labelcommand2) [list $win $col]
		}
	    } else {
		if {[info exists data($col-labelcommand)]} {
		    uplevel #0 $data($col-labelcommand) [list $win $col]
		} elseif {[string length $data(-labelcommand)] != 0} {
		    uplevel #0 $data(-labelcommand) [list $win $col]
		}
	    }
	    if {[destroyed $win]} {
		return ""
	    }
	} elseif {$data(-movablecolumns)} {
	    $data(hdrTxtFrmCanv)$col configure -cursor $data(-cursor)
	    if {[info exists data(targetCol)]} {
		set sourceColName [doColCget $col $win -name]
		set targetColName [doColCget $data(targetCol) $win -name]

		moveCol $win $col $data(targetCol)

		set userData \
		    [list $col $data(targetCol) $sourceColName $targetColName]
		genVirtualEvent $win <<TablelistColumnMoved>> $userData

		unset data(targetCol)
	    }
	}
    }

    set data(labelClicked) 0
}

#------------------------------------------------------------------------------
# tablelist::labelB3Down
#
# This procedure is invoked when mouse button 3 is pressed in the header label
# w of a tablelist widget.  If the Shift key was down when this event occured
# then the procedure restores the last static width of the given column;
# otherwise it configures the width of the given column to be just large enough
# to hold all the elements (including the label).
#------------------------------------------------------------------------------
proc tablelist::labelB3Down {w shiftPressed} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(isDisabled) &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	if {$shiftPressed} {
	    doColConfig $col $win -width -$data($col-lastStaticWidth)
	} else {
	    doColConfig $col $win -width 0
	}

	genVirtualEvent $win <<TablelistColumnResized>> $col
    }
}

#------------------------------------------------------------------------------
# tablelist::labelDblB1
#
# This procedure is invoked when the header label w of a tablelist widget is
# double-clicked.  If the pointer is on the right border of the label then the
# procedure performs the same action as labelB3Down.
#------------------------------------------------------------------------------
proc tablelist::labelDblB1 {w x shiftPressed} {
    if {![parseLabelPath $w win col]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {!$data(isDisabled) && [inResizeArea $w $x col] &&
	$data(-resizablecolumns) && $data($col-resizable)} {
	if {$shiftPressed} {
	    doColConfig $col $win -width -$data($col-lastStaticWidth)
	} else {
	    doColConfig $col $win -width 0
	}

	genVirtualEvent $win <<TablelistColumnResized>> $col
    }
}

#------------------------------------------------------------------------------
# tablelist::escape
#
# This procedure is invoked to process <Escape> events in the top-level window
# containing the tablelist widget win during a column resize or move operation.
# The procedure cancels the action in progress and, in case of column resizing,
# it restores the initial width of the respective column.
#------------------------------------------------------------------------------
proc tablelist::escape {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrmLbl)$col
    if {[info exists data(colBeingResized)]} {	;# resize operation in progress
	configLabel $w -cursor $data(-cursor)
	update idletasks
	if {[destroyed $win]} {
	    return ""
	}
	if {[winfo exists $data(focus)]} {
	    focus $data(focus)
	}
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	set data(labelClicked) 0
	set col $data(colBeingResized)
	set idx [expr {3*$col}]
	setupColumns $win [lreplace $data(-columns) $idx $idx \
				    $data(configColWidth)] 0
	redisplayCol $win $col $data(topRow) $data(btmRow)
	unset data(colBeingResized)
	$data(body) tag remove visibleLines 1.0 end
	$data(body) tag configure visibleLines -tabs {}
	adjustColumns $win {} 1
	updateColors $win
    } elseif {!$data(inClickedLabel)} {
	configLabel $w -cursor $data(-cursor)
	$data(hdrTxtFrmCanv)$col configure -cursor $data(-cursor)
	if {[winfo exists $data(focus)]} {
	    focus $data(focus)
	}
	bind [winfo toplevel $win] <Escape> $data(topEscBinding)
	place forget $data(colGap)
	if {[info exists data(targetCol)]} {
	    unset data(targetCol)
	}
	if {[info exists data(X)]} {
	    unset data(X)
	    after cancel $data(afterId)
	    set data(afterId) ""
	}
	set data(labelClicked) 0
    }
}

#------------------------------------------------------------------------------
# tablelist::horizAutoScan
#
# This procedure is invoked when the mouse leaves the scrollable part of a
# tablelist widget's header frame while button 1 is down.  It scrolls the
# header and reschedules itself as an after command so that the header
# continues to scroll until the mouse moves back into the window or the mouse
# button is released.
#------------------------------------------------------------------------------
proc tablelist::horizAutoScan win {
    if {[destroyed $win]} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data
    if {![info exists data(X)]} {
	return ""
    }

    set X $data(X)
    set hdrX [winfo rootx $data(hdr)]
    if {$data(-titlecolumns) == 0 || ![winfo viewable $data(vsep)]} {
	set leftX $hdrX
    } else {
	set leftX [expr {[winfo rootx $data(vsep)] + 1}]
    }
    set rightX [expr {$hdrX + [winfo width $data(hdr)]}]
    if {$data(-titlecolumns) == 0} {
	set units 2
	set ms 50
    } else {
	set units 1
	set ms 250
    }

    if {$X >= $rightX} {
	::$win xview scroll $units units
    } elseif {$X < $leftX} {
	::$win xview scroll -$units units
    } else {
	return ""
    }

    set data(afterId) [after $ms [list tablelist::horizAutoScan $win]]
}

#------------------------------------------------------------------------------
# tablelist::inResizeArea
#
# Checks whether the given x coordinate relative to the header label w of a
# tablelist widget is in the resize area of that label or of the one to its
# left.
#------------------------------------------------------------------------------
proc tablelist::inResizeArea {w x colName} {
    if {![parseLabelPath $w dummy _col]} {
	return 0
    }


    upvar $colName col
    if {$x >= [winfo width $w] - 5} {
	set col $_col
	return 1
    } elseif {$x < 5} {
	set X [expr {[winfo rootx $w] - 3}]
	set contW [winfo containing -displayof $w $X [winfo rooty $w]]
	return [parseLabelPath $contW dummy col]
    } else {
	return 0
    }
}

Added libs/tablelist6.0/scripts/tablelistConfig.tcl.

























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
#==============================================================================
# Contains private configuration procedures for tablelist widgets.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#------------------------------------------------------------------------------
# tablelist::extendConfigSpecs
#
# Extends the elements of the array configSpecs.
#------------------------------------------------------------------------------
proc tablelist::extendConfigSpecs {} {
    variable usingTile
    variable helpLabel
    variable configSpecs
    variable winSys

    #
    # Extend some elements of the array configSpecs
    #
    lappend configSpecs(-acceptchildcommand)	{}
    lappend configSpecs(-acceptdropcommand)	{}
    lappend configSpecs(-activestyle)		frame
    lappend configSpecs(-autofinishediting)	0
    lappend configSpecs(-autoscan)		1
    lappend configSpecs(-collapsecommand)	{}
    lappend configSpecs(-colorizecommand)	{}
    lappend configSpecs(-columns)		{}
    lappend configSpecs(-columntitles)		{}
    lappend configSpecs(-customdragsource)	0
    lappend configSpecs(-displayondemand)	1
    lappend configSpecs(-editendcommand)	{}
    lappend configSpecs(-editselectedonly)	0
    lappend configSpecs(-editstartcommand)	{}
    lappend configSpecs(-expandcommand)		{}
    lappend configSpecs(-forceeditendcommand)	0
    lappend configSpecs(-fullseparators)	0
    lappend configSpecs(-incrarrowtype)		up
    lappend configSpecs(-instanttoggle)		0
    lappend configSpecs(-labelcommand)		{}
    lappend configSpecs(-labelcommand2)		{}
    lappend configSpecs(-labelrelief)		raised
    lappend configSpecs(-listvariable)		{}
    lappend configSpecs(-movablecolumns)	0
    lappend configSpecs(-movablerows)		0
    lappend configSpecs(-populatecommand)	{}
    lappend configSpecs(-protecttitlecolumns)	0
    lappend configSpecs(-resizablecolumns)	1
    lappend configSpecs(-selecttype)		row
    lappend configSpecs(-setfocus)		1
    lappend configSpecs(-showarrow)		1
    lappend configSpecs(-showeditcursor)	1
    lappend configSpecs(-showhorizseparator)	1
    lappend configSpecs(-showlabels)		1
    lappend configSpecs(-showseparators)	0
    lappend configSpecs(-snipstring)		...
    lappend configSpecs(-sortcommand)		{}
    lappend configSpecs(-spacing)		0
    lappend configSpecs(-stretch)		{}
    lappend configSpecs(-stripebackground)	{}
    lappend configSpecs(-stripeforeground)	{}
    lappend configSpecs(-stripeheight)		1
    lappend configSpecs(-targetcolor)		black
    lappend configSpecs(-tight)			0
    lappend configSpecs(-titlecolumns)		0
    lappend configSpecs(-tooltipaddcommand)	{}
    lappend configSpecs(-tooltipdelcommand)	{}
    lappend configSpecs(-treecolumn)		0

    #
    # Append the default values of the configuration options
    # of a temporary, invisible listbox widget to the values
    # of the corresponding elements of the array configSpecs
    #
    set helpListbox .__helpListbox
    for {set n 2} {[winfo exists $helpListbox]} {incr n} {
	set helpListbox .__helpListbox$n
    }
    listbox $helpListbox
    foreach configSet [$helpListbox configure] {
	if {[llength $configSet] != 2} {
	    set opt [lindex $configSet 0]
	    if {[info exists configSpecs($opt)]} {
		lappend configSpecs($opt) [lindex $configSet 3]
	    }
	}
    }
    destroy $helpListbox

    set helpLabel .__helpLabel
    for {set n 0} {[winfo exists $helpLabel]} {incr n} {
	set helpLabel .__helpLabel$n
    }

    if {$usingTile} {
	foreach opt {-highlightbackground -highlightcolor -highlightthickness
		     -labelactivebackground -labelactiveforeground
		     -labelbackground -labelbg -labeldisabledforeground
		     -labelheight} {
	    unset configSpecs($opt)
	}

	#
	# Append theme-specific values to some elements of the
	# array configSpecs and initialize some tree resources
	#
	if {[string compare [getCurrentTheme] "tileqt"] == 0} {
	    tileqt_kdeStyleChangeNotification 
	}
	setThemeDefaults
	variable themeDefaults
	set treeStyle $themeDefaults(-treestyle)
	${treeStyle}TreeImgs 
	variable maxIndentDepths
	set maxIndentDepths($treeStyle) 0

	ttk::label $helpLabel -takefocus 0

	#
	# Define the header label layout
	#
	style theme settings "default" {
	    style layout TablelistHeader.TLabel {
		Treeheading.cell
		Treeheading.border -children {
		    Label.padding -children {
			Label.label
		    }
		}
	    }
	}
	if {[string length [package provide ttk::theme::aqua]] != 0 ||
	    [string length [package provide tile::theme::aqua]] != 0} {
	    style theme settings "aqua" {
		if {[info exists tile::patchlevel] &&
		    [string compare $tile::patchlevel "0.6.4"] < 0} {
		    style layout TablelistHeader.TLabel {
			Treeheading.cell
			Label.padding -children {
			    Label.label -side top
			    Separator.hseparator -side bottom
			}
		    }
		} else {
		    style layout TablelistHeader.TLabel {
			Treeheading.cell
			Label.padding -children {
			    Label.label -side top
			}
		    }
		}
		style map TablelistHeader.TLabel -foreground [list \
		    {disabled background} #a3a3a3 disabled #a3a3a3 \
		    background black]
	    }
	}
    } else {
	if {$::tk_version < 8.3} {
	    unset configSpecs(-acceptchildcommand)
	    unset configSpecs(-collapsecommand)
	    unset configSpecs(-expandcommand)
	    unset configSpecs(-populatecommand)
	    unset configSpecs(-titlecolumns)
	    unset configSpecs(-treecolumn)
	    unset configSpecs(-treestyle)
	}

	#
	# Append the default values of some configuration options
	# of an invisible label widget to the values of the
	# corresponding -label* elements of the array configSpecs
	#
	tk::label $helpLabel -takefocus 0
	foreach optTail {font height} {
	    set configSet [$helpLabel configure -$optTail]
	    lappend configSpecs(-label$optTail) [lindex $configSet 3]
	}
	if {[catch {$helpLabel configure -activebackground} configSet1] == 0 &&
	    [catch {$helpLabel configure -activeforeground} configSet2] == 0} {
	    lappend configSpecs(-labelactivebackground) [lindex $configSet1 3]
	    lappend configSpecs(-labelactiveforeground) [lindex $configSet2 3]
	} else {
	    unset configSpecs(-labelactivebackground)
	    unset configSpecs(-labelactiveforeground)
	}
	if {[catch {$helpLabel configure -disabledforeground} configSet] == 0} {
	    lappend configSpecs(-labeldisabledforeground) [lindex $configSet 3]
	} else {
	    unset configSpecs(-labeldisabledforeground)
	}
	if {[string compare $winSys "win32"] == 0 &&
	    $::tcl_platform(osVersion) < 5.1} {
	    lappend configSpecs(-labelpady) 0
	} else {
	    set configSet [$helpLabel configure -pady]
	    lappend configSpecs(-labelpady) [lindex $configSet 3]
	}

	#
	# Steal the default values of some configuration
	# options from a temporary, invisible button widget
	#
	set helpButton .__helpButton
	for {set n 0} {[winfo exists $helpButton]} {incr n} {
	    set helpButton .__helpButton$n
	}
	button $helpButton
	foreach opt {-disabledforeground -state} {
	    if {[llength $configSpecs($opt)] == 3} {
		set configSet [$helpButton configure $opt]
		lappend configSpecs($opt) [lindex $configSet 3]
	    }
	}
	foreach optTail {background foreground} {
	    set configSet [$helpButton configure -$optTail]
	    lappend configSpecs(-label$optTail) [lindex $configSet 3]
	}
	if {[string compare $winSys "classic"] == 0 ||
	    [string compare $winSys "aqua"] == 0} {
	    lappend configSpecs(-labelborderwidth) 1
	} else {
	    set configSet [$helpButton configure -borderwidth]
	    lappend configSpecs(-labelborderwidth) [lindex $configSet 3]
	}
	destroy $helpButton

	#
	# Set the default values of the -arrowcolor,
	# -arrowdisabledcolor, -arrowstyle, and -treestyle options
	#
	switch $winSys {
	    x11 {
		set arrowColor		black
		set arrowDisabledColor	#a3a3a3
		set arrowStyle		flat7x5
		set treeStyle		gtk
	    }

	    win32 {
		if {$::tcl_platform(osVersion) < 5.1} {		;# Win native
		    set arrowColor		{}
		    set arrowDisabledColor	{}
		    set arrowStyle		sunken8x7
		    set treeStyle		winnative

		} elseif {$::tcl_platform(osVersion) == 5.1} {	;# Win XP
		    switch [winfo rgb . SystemHighlight] {
			"12593 27242 50629" {			;# Win XP Blue
			    set arrowColor	#aca899
			    set arrowStyle	flat9x5
			    set treeStyle	winxpBlue
			}
			"37779 41120 28784" {			;# Win XP Olive
			    set arrowColor	#aca899
			    set arrowStyle	flat9x5
			    set treeStyle	winxpOlive
			}
			"45746 46260 49087" {			;# Win XP Silver
			    set arrowColor	#aca899
			    set arrowStyle	flat9x5
			    set treeStyle	winxpSilver
			}
			default {				;# Win Classic
			    set arrowColor	SystemButtonShadow
			    set arrowStyle	flat7x4
			    set treeStyle	winnative
			}
		    }
		    set arrowDisabledColor	SystemDisabledText

		} elseif {$::tcl_platform(osVersion) == 6.0} {	;# Win Vista
		    variable scalingpct

		    switch [winfo rgb . SystemHighlight] {
			"13107 39321 65535" {			;# Vista Aero
			    set arrowColor	#569bc0
			    switch $scalingpct {
				100 { set arrowStyle	photo7x4 }
				125 { set arrowStyle	photo9x5 }
				150 { set arrowStyle	photo11x6 }
				200 { set arrowStyle	photo15x8 }
			    }
			    set treeStyle	vistaAero
			}
			default {				;# Win Classic
			    set arrowColor	SystemButtonShadow
			    switch $scalingpct {
				100 { set arrowStyle	flat7x4 }
				125 { set arrowStyle	flat9x5 }
				150 { set arrowStyle	flat11x6 }
				200 { set arrowStyle	flat15x8 }
			    }
			    set treeStyle	vistaClassic
			}
		    }
		    set arrowDisabledColor	SystemDisabledText

		} elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 7/8
		    variable scalingpct

		    switch [winfo rgb . SystemHighlight] {
			"13107 39321 65535" {			;# Win 7/8 Aero
			    set arrowColor	#569bc0
			    switch $scalingpct {
				100 { set arrowStyle	photo7x4 }
				125 { set arrowStyle	photo9x5 }
				150 { set arrowStyle	photo11x6 }
				200 { set arrowStyle	photo15x8 }
			    }
			    set treeStyle	win7Aero
			}
			default {				;# Win Classic
			    set arrowColor	SystemButtonShadow
			    switch $scalingpct {
				100 { set arrowStyle	flat7x4 }
				125 { set arrowStyle	flat9x5 }
				150 { set arrowStyle	flat11x6 }
				200 { set arrowStyle	flat15x8 }
			    }
			    set treeStyle	win7Classic
			}
		    }
		    set arrowDisabledColor	SystemDisabledText

		} else {					;# Win 10
		    variable scalingpct
		    switch $scalingpct {
			100 { set arrowStyle	flatAngle7x4 }
			125 { set arrowStyle	flatAngle9x5 }
			150 { set arrowStyle	flatAngle11x6 }
			200 { set arrowStyle	flatAngle15x8 }
		    }

		    set arrowColor		#595959
		    set arrowDisabledColor	SystemDisabledText
		    set treeStyle		win10
		}
	    }

	    classic -
	    aqua {
		scan $::tcl_platform(osVersion) "%d" majorOSVersion
		if {$majorOSVersion >= 14} {		;# OS X 10.10 or higher
		    set arrowColor	#404040
		    set arrowStyle	flatAngle7x4
		} else {
		    set arrowColor	#717171
		    variable pngSupported
		    if {$pngSupported} {
			set arrowStyle	photo7x7
		    } else {
			set arrowStyle	flat7x7
		    }
		}
		set arrowDisabledColor	#a3a3a3
		set treeStyle		aqua
	    }
	}
	lappend configSpecs(-arrowcolor)		$arrowColor
	lappend configSpecs(-arrowdisabledcolor)	$arrowDisabledColor
	lappend configSpecs(-arrowstyle)		$arrowStyle
	if {$::tk_version >= 8.3} {
	    lappend configSpecs(-treestyle)		$treeStyle
	    ${treeStyle}TreeImgs 
	    variable maxIndentDepths
	    set maxIndentDepths($treeStyle) 0
	}
    }

    #
    # Set the default values of the -movecolumncursor,
    # -movecursor, and -resizecursor options
    #
    switch $winSys {
	x11 -
	win32 {
	    set movecolumnCursor	icon
	    set moveCursor		hand2
	    set resizeCursor		sb_h_double_arrow
	}

	classic -
	aqua {
	    set movecolumnCursor	closedhand
	    set moveCursor		pointinghand
	    if {[catch {$helpLabel configure -cursor resizeleftright}] == 0} {
		set resizeCursor	resizeleftright
	    } else {
		set resizeCursor	sb_h_double_arrow
	    }
	}
    }
    lappend configSpecs(-movecolumncursor)	$movecolumnCursor
    lappend configSpecs(-movecursor)		$moveCursor
    lappend configSpecs(-resizecursor)		$resizeCursor

    variable centerArrows 0
    if {[string compare $winSys "win32"] == 0 &&
	$::tcl_platform(osVersion) >= 6.0 &&
	[string compare [winfo rgb . SystemHighlight] \
			"13107 39321 65535"] == 0} {
	set centerArrows 1
    }
}

#------------------------------------------------------------------------------
# tablelist::doConfig
#
# Applies the value val of the configuration option opt to the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::doConfig {win opt val} {
    variable usingTile
    variable helpLabel
    variable configSpecs
    upvar ::tablelist::ns${win}::data data

    #
    # Apply the value to the widget(s) corresponding to the given option
    #
    switch [lindex $configSpecs($opt) 2] {
	c {
	    #
	    # Apply the value to all children and save the
	    # properly formatted value of val in data($opt)
	    #
	    foreach w [winfo children $win] {
		if {[regexp {^(body|hdr|.sep[0-9]*)$} [winfo name $w]]} {
		    $w configure $opt $val
		}
	    }
	    $data(hdrTxt) configure $opt $val
	    $data(hdrFrmLbl) configure $opt $val
	    $data(cornerLbl) configure $opt $val
	    foreach w [winfo children $data(hdrTxtFrm)] {
		$w configure $opt $val
	    }
	    set data($opt) [$data(hdrFrmLbl) cget $opt]
	}

	b {
	    #
	    # Apply the value to both text widgets and save the
	    # properly formatted value of val in data($opt)
	    #
	    $data(hdrTxt) configure $opt $val
	    set w $data(body)
	    $w configure $opt $val
	    set data($opt) [$w cget $opt]

	    switch -- $opt {
		-background {
		    #
		    # Apply the value to the frame (because of the shadow
		    # colors of its 3-D border), to the separators,
		    # to the header frame, and to the "disabled" tag
		    #
		    if {$usingTile} {
			styleConfig Frame$win.TFrame $opt $val
			styleConfig Seps$win.TSeparator $opt $val
		    } else {
			$win configure $opt $val
			foreach c [winfo children $win] {
			    if {[regexp {^(vsep[0-9]+|hsep2)$} \
					[winfo name $c]]} {
				$c configure $opt $val
			    }
			}
		    }
		    $data(hdr) configure $opt $val
		    $data(hdrTxt) tag configure disabled $opt $val
		    $w tag configure disabled $opt $val
		    hdr_updateColorsWhenIdle $win
		    updateColorsWhenIdle $win
		}
		-font {
		    #
		    # Apply the value to the listbox child, rebuild the lists
		    # of the column fonts and tag names, configure the edit
		    # window if present, set up and adjust the columns, and
		    # make sure the items will be redisplayed at idle time
		    #
		    $data(lb) configure $opt $val
		    set data(charWidth) [font measure $val -displayof $win 0]
		    makeColFontAndTagLists $win
		    if {$data(editRow) >= 0} {
			setEditWinFont $win
		    }
		    for {set col 0} {$col < $data(colCount)} {incr col} {
			if {$data($col-maxwidth) > 0} {
			    set data($col-maxPixels) \
				[charsToPixels $win $val $data($col-maxwidth)]
			}
		    }
		    setupColumns $win $data(-columns) 0
		    adjustColumns $win allCols 1
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-foreground {
		    #
		    # Set the background color of the main separators
		    # (if any) to the specified value, and apply
		    # this value to the "disabled" tag if needed
		    #
		    if {$usingTile} {
			styleConfig Main$win.TSeparator -background $val
		    } else {
			if {[winfo exists $data(vsep)]} {
			    $data(vsep) configure -background $val
			}
			if {[winfo exists $data(hsep)1]} {
			    $data(hsep)1 configure -background $val
			}
		    }
		    if {[string length $data(-disabledforeground)] == 0} {
			$data(hdrTxt) tag configure disabled $opt $val
			$w tag configure disabled $opt $val
		    }
		    hdr_updateColorsWhenIdle $win
		    updateColorsWhenIdle $win
		}
	    }
	}

	l {
	    #
	    # Apply the value to all not individually configured labels
	    # and save the properly formatted value of val in data($opt)
	    #
	    set optTail [string range $opt 6 end]	;# remove the -label
	    configLabel $data(hdrFrmLbl) -$optTail $val
	    configLabel $data(cornerLbl) -$optTail $val
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set w $data(hdrTxtFrmLbl)$col
		if {![info exists data($col$opt)]} {
		    configLabel $w -$optTail $val
		}
	    }
	    if {$usingTile && [string compare $opt "-labelpady"] == 0} {
		set data($opt) $val
	    } else {
		set data($opt) [$data(hdrFrmLbl) cget -$optTail]
	    }

	    switch -- $opt {
		-labelbackground -
		-labelforeground {
		    #
		    # Conditionally apply the value to the
		    # canvases displaying up- or down-arrows
		    #
		    $helpLabel configure -$optTail $val
		    set data($opt) [$helpLabel cget -$optTail]
		    foreach col $data(arrowColList) {
			if {![info exists data($col$opt)]} {
			    configCanvas $win $col
			}
		    }
		}
		-labelborderwidth {
		    #
		    # Adjust the columns (including
		    # the height of the header frame)
		    #
		    adjustColumns $win allLabels 1
		    updateViewWhenIdle $win

		    set borderWidth [winfo pixels $win $data($opt)]
		    if {$borderWidth < 0} {
			set borderWidth 0
		    }
		    place configure $data(cornerLbl) -x -$borderWidth \
			-width [expr {2*$borderWidth}]
		}
		-labeldisabledforeground {
		    #
		    # Conditionally apply the value to the
		    # canvases displaying up- or down-arrows
		    #
		    foreach col $data(arrowColList) {
			if {![info exists data($col$opt)]} {
			    configCanvas $win $col
			}
		    }
		}
		-labelheight -
		-labelpady {
		    #
		    # Adjust the height of the header frame
		    #
		    adjustHeaderHeight $win
		}
	    }
	}

	f {
	    #
	    # Apply the value to the frame and save the
	    # properly formatted value of val in data($opt)
	    #
	    $win configure $opt $val
	    set data($opt) [$win cget $opt]
	}

	w {
	    switch -- $opt {
		-acceptchildcommand -
		-acceptdropcommand -
		-collapsecommand -
		-colorizecommand -
		-editendcommand -
		-editstartcommand -
		-expandcommand -
		-labelcommand -
		-labelcommand2 -
		-populatecommand -
		-selectmode -
		-sortcommand -
		-tooltipaddcommand -
		-tooltipdelcommand -
		-yscrollcommand {
		    set data($opt) $val
		}
		-activestyle {
		    #
		    # Configure the "active" tag and save the
		    # properly formatted value of val in data($opt)
		    #
		    variable activeStyles
		    set val [mwutil::fullOpt "active style" $val $activeStyles]
		    set w $data(body)
		    switch $val {
			frame {
			    $w tag configure active \
				   -borderwidth 1 -relief solid -underline ""
			}
			none {
			    $w tag configure active \
				   -borderwidth "" -relief "" -underline ""
			}
			underline {
			    $w tag configure active \
				   -borderwidth "" -relief "" -underline 1
			}
		    }
		    set data($opt) $val
		}
		-arrowcolor -
		-arrowdisabledcolor {
		    #
		    # Save the properly formatted value of val in data($opt)
		    # and set the color of the normal or disabled arrows
		    #
		    if {[string length $val] == 0} {
			set data($opt) ""
		    } else {
			$helpLabel configure -foreground $val
			set data($opt) [$helpLabel cget -foreground]
		    }
		    if {([string compare $opt "-arrowcolor"] == 0 &&
			 !$data(isDisabled)) ||
			([string compare $opt "-arrowdisabledcolor"] == 0 &&
			 $data(isDisabled))} {
			foreach w [info commands $data(hdrTxtFrmCanv)*] {
			    fillArrows $w $val $data(-arrowstyle)
			}
		    }
		}
		-arrowstyle {
		    #
		    # Save the properly formatted value of val in data($opt)
		    # and draw the corresponding arrows in the canvas widgets
		    #
		    variable arrowStyles
		    set data($opt) \
			[mwutil::fullOpt "arrow style" $val $arrowStyles]
		    regexp {^(flat|flatAngle|sunken|photo)([0-9]+)x([0-9]+)$} \
			   $data($opt) dummy relief width height
		    set data(arrowWidth) $width
		    set data(arrowHeight) $height
		    foreach w [info commands $data(hdrTxtFrmCanv)*] {
			createArrows $w $width $height $relief
			if {$data(isDisabled)} {
			    fillArrows $w $data(-arrowdisabledcolor) $data($opt)
			} else {
			    fillArrows $w $data(-arrowcolor) $data($opt)
			}
		    }
		    if {[llength $data(arrowColList)] > 0} {
			foreach col $data(arrowColList) {
			    raiseArrow $win $col
			    lappend whichWidths l$col
			}
			adjustColumns $win $whichWidths 1
			updateViewWhenIdle $win
		    }
		}
		-autofinishediting -
		-autoscan -
		-customdragsource -
		-displayondemand -
		-forceeditendcommand -
		-instanttoggle -
		-movablecolumns -
		-movablerows -
		-protecttitlecolumns -
		-resizablecolumns -
		-setfocus {
		    #
		    # Save the boolean value specified by val in data($opt)
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		}
		-columns {
		    #
		    # Set up and adjust the columns, rebuild
		    # the lists of the column fonts and tag
		    # names, and redisplay the items
		    #
		    set selCells [curCellSelection $win]
		    setupColumns $win $val 1
		    adjustColumns $win allCols 1
		    adjustColIndex $win data(anchorCol) 1
		    adjustColIndex $win data(activeCol) 1
		    makeColFontAndTagLists $win
		    redisplay $win 0 $selCells
		    updateViewWhenIdle $win
		}
		-columntitles {
		    set titleCount [llength $val]
		    set colCount $data(colCount)
		    if {$titleCount <= $colCount} {
			#
			# Update the first titleCount column
			# titles and adjust the columns
			#
			set whichWidths {}
			for {set col 0} {$col < $titleCount} {incr col} {
			    set idx [expr {3*$col + 1}]
			    set data(-columns) [lreplace $data(-columns) \
						$idx $idx [lindex $val $col]]
			    lappend whichWidths l$col
			}
			adjustColumns $win $whichWidths 1
			updateViewWhenIdle $win
		    } else {
			#
			# Update the titles of the current columns,
			# extend the column list, and do nearly the
			# same as in the case of the -columns option
			#
			set columns {}
			set col 0
			foreach {width title alignment} $data(-columns) {
			    lappend columns $width [lindex $val $col] $alignment
			    incr col
			}
			for {} {$col < $titleCount} {incr col} {
			    lappend columns 0 [lindex $val $col] left
			}
			set selCells [curCellSelection $win]
			setupColumns $win $columns 1
			adjustColumns $win allCols 1
			makeColFontAndTagLists $win
			redisplay $win 0 $selCells
			updateViewWhenIdle $win

			#
			# If this option is being set at widget creation time
			# then append "-columns" to the list of command line
			# options processed by the caller proc, to make sure
			# that the columns-related information produced by the
			# setupColumns call above won't be overridden by the
			# default -columns {} option that would otherwise
			# be processed as a non-explicitly specified option
			#
			set callerProc [lindex [info level -1] 0]
			if {[string compare $callerProc \
			     "mwutil::configureWidget"] == 0} {
			    uplevel 1 lappend cmdLineOpts "-columns"
			}
		    }
		}
		-disabledforeground {
		    #
		    # Configure the "disabled" tag in both text widgets and
		    # save the properly formatted value of val in data($opt)
		    #
		    set w $data(body)
		    if {[string length $val] == 0} {
			foreach w [list $data(hdrTxt) $data(body)] {
			    $w tag configure disabled -fgstipple gray50 \
				-foreground $data(-foreground)
			}
			set data($opt) ""
		    } else {
			foreach w [list $data(hdrTxt) $data(body)] {
			    $w tag configure disabled -fgstipple "" \
				-foreground $val
			}
			set data($opt) [$w tag cget disabled -foreground]
		    }
		    if {$data(isDisabled)} {
			hdr_updateColorsWhenIdle $win
			updateColorsWhenIdle $win
		    }
		}
		-editselectedonly {
		    #
		    # Save the boolean value specified by val in data($opt)
		    # and invoke the motion handler if necessary
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    if {$data(-showeditcursor)} {
			invokeMotionHandler $win
		    }
		}
		-exportselection {
		    #
		    # Save the boolean value specified by val in
		    # data($opt).  In addition, if the selection is
		    # exported and there are any selected rows in the
		    # widget then make win the new owner of the PRIMARY
		    # selection and register a callback to be invoked
		    # when it loses ownership of the PRIMARY selection
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    if {$val &&
			[llength [$data(body) tag nextrange select 1.0]] != 0} {
			selection own -command \
				[list ::tablelist::lostSelection $win] $win
		    }
		}
		-fullseparators -
		-showhorizseparator {
		    #
		    # Save the boolean value specified by val
		    # in data($opt) and adjust the separators
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    adjustSepsWhenIdle $win
		}
		-height {
		    #
		    # Adjust the heights of the body text widget
		    # and of the listbox child, and save the
		    # properly formatted value of val in data($opt)
		    #
		    set val [format "%d" $val]	;# integer check with error msg
		    if {$val <= 0} {
			set viewableRowCount [expr \
			    {$data(itemCount) - $data(nonViewableRowCount)}]
			$data(body) configure $opt $viewableRowCount
			$data(lb) configure $opt $viewableRowCount
		    } else {
			$data(body) configure $opt $val
			$data(lb) configure $opt $val
		    }
		    set data($opt) $val
		}
		-incrarrowtype {
		    #
		    # Save the properly formatted value of val in
		    # data($opt) and raise the corresponding arrows
		    # if the currently mapped canvas widgets
		    #
		    variable arrowTypes
		    set data($opt) \
			[mwutil::fullOpt "arrow type" $val $arrowTypes]
		    foreach col $data(arrowColList) {
			raiseArrow $win $col
		    }
		}
		-listvariable {
		    #
		    # Associate val as list variable with the
		    # given widget and save it in data($opt)
		    #
		    makeListVar $win $val
		    set data($opt) $val
		    if {[string length $val] == 0} {
			set data(hasListVar) 0
		    } else {
			set data(hasListVar) 1
		    }
		}
		-movecolumncursor -
		-movecursor -
		-resizecursor {
		    #
		    # Save the properly formatted value of val in data($opt)
		    #
		    $helpLabel configure -cursor $val
		    set data($opt) [$helpLabel cget -cursor]
		}
		-selectbackground -
		-selectforeground {
		    #
		    # Configure the "select" tag in the body text widget
		    # and save the properly formatted value of val in
		    # data($opt).  Don't use the built-in "sel" tag
		    # because on Windows the selection in a text widget only
		    # becomes visible when the window gets the input focus.
		    #
		    set w $data(body)
		    set optTail [string range $opt 7 end] ;# remove the -select
		    $w tag configure select -$optTail $val
		    set data($opt) [$w tag cget select -$optTail]
		    if {!$data(isDisabled)} {
			updateColorsWhenIdle $win
		    }
		}
		-selecttype {
		    #
		    # Save the properly formatted value of val in data($opt)
		    #
		    variable selectTypes
		    set val [mwutil::fullOpt "selection type" $val $selectTypes]
		    set data($opt) $val
		}
		-selectborderwidth {
		    #
		    # Configure the "select" tag in the body text widget
		    # and save the properly formatted value of val in
		    # data($opt).  Don't use the built-in "sel" tag
		    # because on Windows the selection in a text widget only
		    # becomes visible when the window gets the input focus.
		    # In addition, adjust the line spacing accordingly and
		    # apply the value to the listbox child, too.
		    #
		    set w $data(body)
		    set optTail [string range $opt 7 end] ;# remove the -select
		    $w tag configure select -$optTail $val
		    set data($opt) [$w tag cget select -$optTail]
		    set pixVal [winfo pixels $w $val]
		    if {$pixVal < 0} {
			set pixVal 0
		    }
		    set spacing [winfo pixels $w $data(-spacing)]
		    if {$spacing < 0} {
			set spacing 0
		    }
		    set sp1 [expr {$spacing + $pixVal}]
		    set sp3 [expr {$spacing + $pixVal + !$data(-tight)}]
		    $data(hdrTxt) configure -spacing1 $sp1 -spacing3 $sp3
		    $w configure -spacing1 $sp1 -spacing3 $sp3
		    $data(lb) configure $opt $val
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-setgrid {
		    #
		    # Apply the value to the listbox child and save
		    # the properly formatted value of val in data($opt)
		    #
		    $data(lb) configure $opt $val
		    set data($opt) [$data(lb) cget $opt]
		}
		-showarrow {
		    #
		    # Save the boolean value specified by val in
		    # data($opt) and manage or unmanage the
		    # canvases displaying up- or down-arrows
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    makeSortAndArrowColLists $win
		    adjustColumns $win allLabels 1
		    updateViewWhenIdle $win
		}
		-showeditcursor {
		    #
		    # Save the boolean value specified by val in
		    # data($opt) and invoke the motion handler
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    invokeMotionHandler $win
		}
		-showlabels {
		    #
		    # Save the boolean value specified by val in data($opt)
		    # and adjust the height of the header frame
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    adjustHeaderHeight $win
		}
		-showseparators {
		    #
		    # Save the boolean value specified by val in data($opt),
		    # and create or destroy the separators if needed
		    #
		    set oldVal $data($opt)
		    set data($opt) [expr {$val ? 1 : 0}]
		    if {!$oldVal && $data($opt)} {
			createSeps $win
		    } elseif {$oldVal && !$data($opt)} {
			foreach w [winfo children $win] {
			    if {[regexp {^(vsep[0-9]+|hsep2)$} \
					[winfo name $w]]} {
				destroy $w
			    }
			}
		    }
		}
		-snipstring {
		    #
		    # Save val in data($opt), adjust the columns, and make
		    # sure the items will be redisplayed at idle time
		    #
		    set data($opt) $val
		    adjustColumns $win {} 0
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-spacing {
		    #
		    # Adjust the line spacing and save val in data($opt)
		    #
		    set w $data(body)
		    set pixVal [winfo pixels $w $val]
		    if {$pixVal < 0} {
			set pixVal 0
		    }
		    set selectBd [winfo pixels $w $data(-selectborderwidth)]
		    if {$selectBd < 0} {
			set selectBd 0
		    }
		    set sp1 [expr {$pixVal + $selectBd}]
		    set sp3 [expr {$pixVal + $selectBd + !$data(-tight)}]
		    $data(hdrTxt) configure -spacing1 $sp1 -spacing3 $sp3
		    $w configure -spacing1 $sp1 -spacing3 $sp3
		    set data($opt) $val
		    redisplayWhenIdle $win
		    updateViewWhenIdle $win
		}
		-state {
		    #
		    # Apply the value to all labels and their sublabels
		    # (if any), as well as to the edit window (if present),
		    # add/remove the "disabled" tag to/from the contents
		    # of the text widgets, configure the borderwidth
		    # of the "active" and "select" tags, save the
		    # properly formatted value of val in data($opt),
		    # and raise the corresponding arrow in the canvas
		    #
		    variable states
		    set val [mwutil::fullOpt "state" $val $states]
		    catch {
			configLabel $data(hdrFrmLbl) $opt $val
			configLabel $data(cornerLbl) $opt $val
			for {set col 0} {$col < $data(colCount)} {incr col} {
			    configLabel $data(hdrTxtFrmLbl)$col $opt $val
			}
		    }
		    if {$data(editRow) >= 0} {
			catch {$data(bodyFrmEd) configure $opt $val}
		    }
		    set w $data(body)
		    switch $val {
			disabled {
			    $data(hdrTxt) tag add disabled 2.0 end
			    $w tag add disabled 1.0 end
			    $w tag configure select -relief flat
			    $w tag configure curRow -relief flat
			    set data(isDisabled) 1
			}
			normal {
			    $data(hdrTxt) tag remove disabled 2.0 end
			    $w tag remove disabled 1.0 end
			    $w tag configure select -relief raised
			    $w tag configure curRow -relief raised
			    set data(isDisabled) 0
			}
		    }
		    set data($opt) $val
		    foreach col $data(arrowColList) {
			configCanvas $win $col
			raiseArrow $win $col
		    }
		    hdr_updateColorsWhenIdle $win
		    updateColorsWhenIdle $win
		}
		-stretch {
		    #
		    # Save the properly formatted value of val in
		    # data($opt) and stretch the stretchable columns
		    #
		    if {[string first $val "all"] == 0} {
			set data($opt) all
		    } else {
			set data($opt) $val
			sortStretchableColList $win
		    }
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}
		-stripebackground -
		-stripeforeground {
		    #
		    # Configure the "stripe" tag in the body text
		    # widget, save the properly formatted value of val
		    # in data($opt), and draw the stripes if necessary
		    #
		    set w $data(body)
		    set optTail [string range $opt 7 end] ;# remove the -stripe
		    $w tag configure stripe -$optTail $val
		    set data($opt) [$w tag cget stripe -$optTail]
		    makeStripesWhenIdle $win
		}
		-stripeheight {
		    #
		    # Save the properly formatted value of val in
		    # data($opt) and draw the stripes if necessary
		    #
		    set val [format "%d" $val]	;# integer check with error msg
		    set data($opt) $val
		    makeStripesWhenIdle $win
		}
		-targetcolor {
		    #
		    # Set the color of the row and column gaps, and save
		    # the properly formatted value of val in data($opt)
		    #
		    $data(rowGap) configure -background $val
		    $data(colGap) configure -background $val
		    set data($opt) [$data(rowGap) cget -background]
		}
		-tight {
		    #
		    # Save the boolean value specified by val
		    # in data($opt) and adjust the line spacing
		    #
		    set data($opt) [expr {$val ? 1 : 0}]
		    set w $data(body)
		    set sp1 [$w cget -spacing1]
		    set sp3 [expr {$sp1 + !$data($opt)}]
		    $data(hdrTxt) configure -spacing3 $sp3
		    $w configure -spacing3 $sp3
		    updateViewWhenIdle $win
		}
		-titlecolumns {
		    #
		    # Update the value of the -xscrollcommand option, save
		    # the properly formatted value of val in data($opt), and
		    # create or destroy the vertical main separator if needed
		    #
		    set oldVal $data($opt)
		    set val [format "%d" $val]	;# integer check with error msg
		    if {$val < 0} {
			set val 0
		    }
		    xviewSubCmd $win 0
		    set w $data(vsep)
		    if {$val == 0} {
			$data(hdrTxt) configure -xscrollcommand \
				      $data(-xscrollcommand)
			if {$oldVal > 0} {
			    destroy $w
			}
		    } else {
			$data(hdrTxt) configure -xscrollcommand ""
			if {$oldVal == 0} {
			    if {$usingTile} {
				ttk::separator $w -style Main$win.TSeparator \
						  -cursor $data(-cursor) \
						  -orient vertical -takefocus 0
			    } else {
				tk::frame $w -background $data(-foreground) \
					     -borderwidth 1 -container 0 \
					     -cursor $data(-cursor) \
					     -highlightthickness 0 \
					     -relief sunken -takefocus 0 \
					     -width 2
			    }
			    bindtags $w [lreplace [bindtags $w] 1 1 \
					 $data(bodyTag) TablelistBody]
			}
			adjustSepsWhenIdle $win
		    }
		    set data($opt) $val
		    updateHScrlbarWhenIdle $win
		}
		-treecolumn {
		    #
		    # Save the properly formatted value of val in
		    # data($opt), its adjusted value in data(treeCol),
		    # and move the tree images into the new tree column
		    #
		    set oldTreeCol $data(treeCol)
		    set newTreeCol [colIndex $win $val 0]
		    set data($opt) $newTreeCol
		    adjustColIndex $win newTreeCol
		    set data(treeCol) $newTreeCol
		    if {$data(colCount) != 0} {
			set data($opt) $newTreeCol
		    }
		    if {$newTreeCol != $oldTreeCol} {
			for {set row 0} {$row < $data(itemCount)} {incr row} {
			    doCellConfig $row $newTreeCol $win -indent \
				[doCellCget $row $oldTreeCol $win -indent]
			    doCellConfig $row $oldTreeCol $win -indent ""
			}
		    }
		}
		-treestyle {
		    #
		    # Update the tree images and save the properly
		    # formatted value of val in data($opt)
		    #
		    variable treeStyles
		    set newStyle [mwutil::fullOpt "tree style" $val $treeStyles]
		    set oldStyle $data($opt)
		    set treeCol $data(treeCol)
		    if {[string compare $newStyle $oldStyle] != 0} {
			${newStyle}TreeImgs 
			variable maxIndentDepths
			if {![info exists maxIndentDepths($newStyle)]} {
			    set maxIndentDepths($newStyle) 0
			}
			if {$data(colCount) != 0} {
			    for {set row 0} {$row < $data(itemCount)} \
				{incr row} {
				set oldImg \
				    [doCellCget $row $treeCol $win -indent]
				set newImg [strMap \
				    [list $oldStyle $newStyle "Sel" ""] $oldImg]
				if {[regexp {^.+Img([0-9]+)$} $newImg \
				     dummy depth]} {
				    if {$depth > $maxIndentDepths($newStyle)} {
					createTreeImgs $newStyle $depth
					set maxIndentDepths($newStyle) $depth
				    }
				    doCellConfig $row $treeCol $win \
						 -indent $newImg
				}
			    }
			}
		    }
		    set data($opt) $newStyle
		    switch -glob $newStyle {
			baghira -
			klearlooks -
			oxygen? -
			phase -
			plastik -
			vista* -
			winnative -
			winxp*		{ set data(protectIndents) 1 }
			default		{ set data(protectIndents) 0 }
		    }
		    set selCells [curCellSelection $win 1]
		    foreach {key col} $selCells {
			set row [keyToRow $win $key]
			cellSelection $win set $row $col $row $col
		    }
		    if {$data(ownsFocus) && ![info exists data(dispId)]} {
			addActiveTag $win
		    }
		}
		-width {
		    #
		    # Adjust the widths of the body text widget,
		    # header frame, and listbox child, and save the
		    # properly formatted value of val in data($opt)
		    #
		    set val [format "%d" $val]	;# integer check with error msg
		    $data(body) configure $opt $val
		    if {$val <= 0} {
			$data(hdr) configure $opt $data(hdrWidth)
			$data(lb) configure $opt \
				  [expr {$data(hdrWidth) / $data(charWidth)}]
		    } else {
			$data(hdr) configure $opt 0
			$data(lb) configure $opt $val
		    }
		    set data($opt) $val
		}
		-xscrollcommand {
		    #
		    # Save val in data($opt), and apply it to the header text
		    # widget if (and only if) no title columns are being used
		    #
		    set data($opt) $val
		    if {$data(-titlecolumns) == 0} {
			$data(hdrTxt) configure $opt $val
		    } else {
			$data(hdrTxt) configure $opt ""
		    }
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doCget
#
# Returns the value of the configuration option opt for the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::doCget {win opt} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $opt "-columntitles"] == 0} {
	set colTitles {}
	foreach {width title alignment} $data(-columns) {
	    lappend colTitles $title
	}
	return $colTitles
    } else {
	return $data($opt)
    }
}

#------------------------------------------------------------------------------
# tablelist::doColConfig
#
# Applies the value val of the column configuration option opt to the col'th
# column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doColConfig {col win opt val} {
    variable canElide
    variable pu
    upvar ::tablelist::ns${win}::data data

    switch -- $opt {
	-align {
	    #
	    # Set up and adjust the columns, and make sure the
	    # given column will be redisplayed at idle time
	    #
	    set idx [expr {3*$col + 2}]
	    setupColumns $win [lreplace $data(-columns) $idx $idx $val] 0
	    adjustColumns $win {} 0
	    redisplayColWhenIdle $win $col
	}

	-background -
	-foreground {
	    set name $col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in both text widgets
		#
		foreach w [list $data(hdrTxt) $data(body)] {
		    set tag col$opt-$val
		    $w tag configure $tag $opt $val
		    $w tag lower $tag
		}

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		hdr_updateColorsWhenIdle $win
		updateColorsWhenIdle $win
	    }
	}

	-changesnipside -
	-wrap {
	    #
	    # Save the boolean value specified by val in data($col$opt) and
	    # make sure the given column will be redisplayed at idle time
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    if {[lindex $data(-columns) [expr {3*$col}]] != 0} {
		redisplayColWhenIdle $win $col
		updateViewWhenIdle $win
	    }
	}

	-changetitlesnipside {
	    #
	    # Save the boolean value specified by val in
	    # data($col$opt) and adjust the col'th label
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    if {$pixels != 0} {	
		incr pixels $data($col-delta)
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    adjustLabel $win $col $pixels $alignment
	}

	-editable {
	    #
	    # Save the boolean value specified by val in data($col$opt)
	    # and invoke the motion handler if necessary
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    if {$data(-showeditcursor)} {
		invokeMotionHandler $win
	    }
	}

	-editwindow {
	    variable editWin
	    if {[info exists editWin($val-creationCmd)]} {
		set data($col$opt) $val
	    } else {
		return -code error "name \"$val\" is not registered\
				    for interactive cell editing"
	    }
	}

	-font {
	    set name $col$opt

	    if {[info exists data($name)] &&
		(!$data($col-hide) || $canElide)} {
		#
		# Remove the tag col$opt-$data($name)
		# from the elements of the given column
		#
		set tag col$opt-$data($name)
		set maxHdrLine [expr {$data(hdr_itemCount) + 1}]
		foreach w [list $data(hdrTxt) $data(body)] min {2 1} \
			max [list $maxHdrLine $data(itemCount)] {
		    for {set line $min} {$line <= $max} {incr line} {
			findTabs $win $w $line $col $col tabIdx1 tabIdx2
			$w tag remove $tag $tabIdx1 $tabIdx2+1$pu
		    }
		}
	    }

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in both text widgets
		#
		set tag col$opt-$val
		foreach w [list $data(hdrTxt) $data(body)] {
		    $w tag configure $tag $opt $val
		    $w tag lower $tag
		}

		if {!$data($col-hide) || $canElide} {
		    #
		    # Apply the tag to the elements of the given column
		    #
		    set maxHdrLine [expr {$data(hdr_itemCount) + 1}]
		    foreach w [list $data(hdrTxt) $data(body)] min {2 1} \
			    max [list $maxHdrLine $data(itemCount)] {
			for {set line $min} {$line <= $max} {incr line} {
			    findTabs $win $w $line $col $col tabIdx1 tabIdx2
			    $w tag add $tag $tabIdx1 $tabIdx2+1$pu
			}
		    }
		}

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    #
	    # Rebuild the lists of the column fonts and tag names
	    #
	    makeColFontAndTagLists $win

	    #
	    # Adjust the columns, and make sure the specified
	    # column will be redisplayed at idle time
	    #
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win

	    if {$col == $data(editCol)} {
		#
		# Configure the edit window
		#
		setEditWinFont $win
	    }
	}

	-formatcommand {
	    if {[string length $val] == 0} {
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
		set fmtCmdFlag 0
	    } else {
		set data($col$opt) $val
		set fmtCmdFlag 1
	    }

	    #
	    # Update the corresponding element of the list data(fmtCmdFlagList)
	    #
	    set data(fmtCmdFlagList) \
		[lreplace $data(fmtCmdFlagList) $col $col $fmtCmdFlag]
	    set data(hasFmtCmds) \
		[expr {[lsearch -exact $data(fmtCmdFlagList) 1] >= 0}]

	    #
	    # Adjust the columns and make sure the specified
	    # column will be redisplayed at idle time
	    #
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win
	}

	-hide {
	    #
	    # Save the boolean value specified by val in data($col$opt),
	    # adjust the columns, and redisplay the items
	    #
	    set oldVal $data($col$opt)
	    set newVal [expr {$val ? 1 : 0}]
	    if {$newVal != $oldVal} {
		if {!$canElide} {
		    set selCells [curCellSelection $win]
		}
		set data($col$opt) $newVal
		if {$newVal} {				;# hiding the column
		    incr data(hiddenColCount)
		    adjustColIndex $win data(anchorCol) 1
		    adjustColIndex $win data(activeCol) 1
		    if {$col == $data(editCol)} {
			doCancelEditing $win
		    }
		} else {
		    incr data(hiddenColCount) -1
		}
		makeColFontAndTagLists $win
		adjustColumns $win $col 1
		if {!$canElide} {
		    redisplay $win 0 $selCells
		    if {!$newVal &&
			[string compare $data(-selecttype) "row"] == 0} {
			foreach row [curSelection $win] {
			    rowSelection $win set $row $row
			}
		    }
		}
		updateViewWhenIdle $win

		genVirtualEvent $win <<TablelistColHiddenStateChanged>> $col
	    }
	}

	-labelalign {
	    if {[string length $val] == 0} {
		#
		# Unset data($col$opt)
		#
		set alignment [lindex $data(colList) [expr {2*$col + 1}]]
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Save the properly formatted value of val in data($col$opt)
		#
		variable alignments
		set val [mwutil::fullOpt "label alignment" $val $alignments]
		set alignment $val
		set data($col$opt) $val
	    }

	    #
	    # Adjust the col'th label
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    if {$pixels != 0} {	
		incr pixels $data($col-delta)
	    }
	    adjustLabel $win $col $pixels $alignment
	}

	-labelbackground -
	-labelforeground {
	    set w $data(hdrTxtFrmLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget
		# configuration option to the col'th label and
		# its sublabels (if any), and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and
		# its sublabels (if any), and save the properly
		# formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		variable helpLabel
		$helpLabel configure -$optTail $val
		set data($col$opt) [$helpLabel cget -$optTail]
	    }

	    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
		configCanvas $win $col
	    }
	}

	-labelborderwidth {
	    set w $data(hdrTxtFrmLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget configuration
		# option to the col'th label and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and save the
		# properly formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		set data($col$opt) [$w cget -$optTail]
	    }

	    #
	    # Adjust the columns (including the height of the header frame)
	    #
	    adjustColumns $win l$col 1
	    updateViewWhenIdle $win
	}

	-labelcommand -
	-labelcommand2 -
	-name -
	-sortcommand {
	    if {[string length $val] == 0} {
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		set data($col$opt) $val
	    }
	}

	-labelfont {
	    set w $data(hdrTxtFrmLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget
		# configuration option to the col'th label and
		# its sublabels (if any), and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and
		# its sublabels (if any), and save the properly
		# formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		set data($col$opt) [$w cget -$optTail]
	    }

	    #
	    # Adjust the columns (including the height of the header frame)
	    #
	    adjustColumns $win l$col 1
	    updateViewWhenIdle $win
	}

	-labelheight -
	-labelpady {
	    set w $data(hdrTxtFrmLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget configuration
		# option to the col'th label and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and save the
		# properly formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		variable usingTile
		if {$usingTile} {
		    set data($col$opt) $val
		} else {
		    set data($col$opt) [$w cget -$optTail]
		}
	    }

	    #
	    # Adjust the height of the header frame
	    #
	    adjustHeaderHeight $win
	}

	-labelimage {
	    set w $data(hdrTxtFrmLbl)$col
	    if {[string length $val] == 0} {
		foreach l [getSublabels $w] {
		    destroy $l
		}
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		if {![winfo exists $w-il]} {
		    variable configSpecs
		    variable configOpts
		    foreach l [list $w-il $w-tl] {	;# image and text labels
			#
			# Create the label $l
			#
			tk::label $l -borderwidth 0 -height 0 \
				     -highlightthickness 0 -padx 0 \
				     -pady 0 -takefocus 0 -width 0

			#
			# Apply to it the current configuration options
			#
			foreach opt2 $configOpts {
			    if {[string compare \
				 [lindex $configSpecs($opt2) 2] "c"] == 0} {
				$l configure $opt2 $data($opt2)
			    }
			}
			if {[string compare [winfo class $w] "TLabel"] == 0} {
			    variable themeDefaults
			    $l configure -background \
					 $themeDefaults(-labelbackground)
			} else {
			    $l configure -background [$w cget -background]
			    $l configure -foreground [$w cget -foreground]
			}
			$l configure -font [$w cget -font]
			foreach opt2 {-activebackground -activeforeground
				      -disabledforeground -state} {
			    catch {$l configure $opt2 [$w cget $opt2]}
			}

			#
			# Replace the binding tag Label with $w,
			# $data(labelTag), and TablelistSubLabel in
			# the list of binding tags of the label $l
			#
			bindtags $l [lreplace [bindtags $l] 1 1 \
				     $w $data(labelTag) TablelistSubLabel]
		    }
		}

		#
		# Display the specified image in the label
		# $w-il and save val in data($col$opt)
		#
		$w-il configure -image $val
		set data($col$opt) $val
	    }

	    #
	    # Adjust the columns (including the height of the header frame)
	    #
	    adjustColumns $win l$col 1
	    updateViewWhenIdle $win
	}

	-labelrelief {
	    set w $data(hdrTxtFrmLbl)$col
	    set optTail [string range $opt 6 end]	;# remove the -label
	    if {[string length $val] == 0} {
		#
		# Apply the value of the corresponding widget configuration
		# option to the col'th label and unset data($col$opt)
		#
		configLabel $w -$optTail $data($opt)
		if {[info exists data($col$opt)]} {
		    unset data($col$opt)
		}
	    } else {
		#
		# Apply the given value to the col'th label and save the
		# properly formatted value of val in data($col$opt)
		#
		configLabel $w -$optTail $val
		set data($col$opt) [$w cget -$optTail]
	    }
	}

	-maxwidth {
	    #
	    # Save the properly formatted value of val in
	    # data($col$opt), adjust the columns, and make sure
	    # the specified column will be redisplayed at idle time
	    #
	    set val [format "%d" $val]	;# integer check with error message
	    set data($col$opt) $val
	    if {$val > 0} {		;# convention: max. width in characters
		set pixels [charsToPixels $win $data(-font) $val]
	    } elseif {$val < 0} {	;# convention: max. width in pixels
		set pixels [expr {(-1)*$val}]
	    } else {			;# convention: no max. width
		set pixels 0
	    }
	    set data($col-maxPixels) $pixels
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win
	}

	-resizable {
	    #
	    # Save the boolean value specified by val in data($col$opt)
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	}

	-selectbackground -
	-selectforeground {
	    set w $data(body)
	    set name $col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in the body text widget
		#
		set tag col$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -select
		$w tag configure $tag -$optTail $val
		$w tag raise $tag select

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-showarrow {
	    #
	    # Save the boolean value specified by val in data($col$opt) and
	    # manage or unmanage the canvas displaying an up- or down-arrow
	    #
	    set data($col$opt) [expr {$val ? 1 : 0}]
	    makeSortAndArrowColLists $win
	    adjustColumns $win l$col 1
	    updateViewWhenIdle $win
	}

	-showlinenumbers {
	    #
	    # Save the boolean value specified by val in
	    # data($col$opt), and make sure the line numbers
	    # will be redisplayed at idle time if needed
	    #
	    set val [expr {$val ? 1 : 0}]
	    if {!$data($col$opt) && $val} {
		showLineNumbersWhenIdle $win
	    }
	    set data($col$opt) $val
	}

	-sortmode {
	    #
	    # Save the properly formatted value of val in data($col$opt)
	    #
	    variable sortModes
	    set data($col$opt) [mwutil::fullOpt "sort mode" $val $sortModes]
	}

	-stretchable {
	    set flag [expr {$val ? 1 : 0}]
	    if {$flag} {
		if {[string compare $data(-stretch) "all"] != 0 &&
		    [lsearch -exact $data(-stretch) $col] < 0} {
		    #
		    # col was not found in data(-stretch): add it to the list
		    #
		    lappend data(-stretch) $col
		    sortStretchableColList $win
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}
	    } elseif {[string compare $data(-stretch) "all"] == 0} {
		#
		# Replace the value "all" of data(-stretch) with
		# the list of all column indices different from col
		#
		set data(-stretch) {}
		for {set n 0} {$n < $data(colCount)} {incr n} {
		    if {$n != $col} {
			lappend data(-stretch) $n
		    }
		}
		set data(forceAdjust) 1
		stretchColumnsWhenIdle $win
	    } else {
		#
		# If col is contained in data(-stretch)
		# then remove it from the list
		#
		if {[set n [lsearch -exact $data(-stretch) $col]] >= 0} {
		    set data(-stretch) [lreplace $data(-stretch) $n $n]
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}

		#
		# If col indicates the last column and data(-stretch)
		# contains "end" then remove "end" from the list
		#
		if {$col == $data(lastCol) &&
		    [string compare [lindex $data(-stretch) end] "end"] == 0} {
		    set data(-stretch) [lreplace $data(-stretch) end end]
		    set data(forceAdjust) 1
		    stretchColumnsWhenIdle $win
		}
	    }
	}

	-stripebackground -
	-stripeforeground {
	    set w $data(body)
	    set name $col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag col$opt-$val in the body text widget
		#
		set tag col$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -stripe
		$w tag configure $tag -$optTail $val
		$w tag raise $tag stripe

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-text {
	    if {$data(isDisabled) || $data($col-showlinenumbers)} {
		return ""
	    }

	    #
	    # Replace the column's content in the internal list
	    #
	    set newItemList {}
	    set row 0
	    foreach item $data(itemList) text [lrange $val 0 $data(lastRow)] {
		set item [lreplace $item $col $col $text]
		lappend newItemList $item
	    }
	    set data(itemList) $newItemList

	    #
	    # Update the list variable if present
	    #
	    condUpdateListVar $win

	    #
	    # Adjust the columns and make sure the specified
	    # column will be redisplayed at idle time
	    #
	    adjustColumns $win $col 1
	    redisplayColWhenIdle $win $col
	    updateViewWhenIdle $win
	}

	-title {
	    #
	    # Save the given value in the corresponding
	    # element of data(-columns) and adjust the columns
	    #
	    set idx [expr {3*$col + 1}]
	    set data(-columns) [lreplace $data(-columns) $idx $idx $val]
	    adjustColumns $win l$col 1
	    updateViewWhenIdle $win
	}

	-valign {
	    #
	    # Save the properly formatted value of val in data($col$opt) and
	    # make sure the given column will be redisplayed at idle time
	    #
	    variable valignments
	    set val [mwutil::fullOpt "vertical alignment" $val $valignments]
	    if {[string compare $val $data($col$opt)] != 0} {
		set data($col$opt) $val
		redisplayColWhenIdle $win $col
	    }
	}

	-width {
	    #
	    # Set up and adjust the columns, and make sure the
	    # given column will be redisplayed at idle time
	    #
	    set idx [expr {3*$col}]
	    if {$val != [lindex $data(-columns) $idx]} {
		setupColumns $win [lreplace $data(-columns) $idx $idx $val] 0
		redisplayColWhenIdle $win $col	;# here before adjustColumns!
		adjustColumns $win $col 1
		updateViewWhenIdle $win
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doColCget
#
# Returns the value of the column configuration option opt for the col'th
# column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doColCget {col win opt} {
    upvar ::tablelist::ns${win}::data data

    switch -- $opt {
	-align {
	    return [lindex $data(-columns) [expr {3*$col + 2}]]
	}

	-stretchable {
	    return [expr {
		[string compare $data(-stretch) "all"] == 0 ||
		[lsearch -exact $data(-stretch) $col] >= 0 ||
		($col == $data(lastCol) && \
		 [string compare [lindex $data(-stretch) end] "end"] == 0)
	    }]
	}

	-text {
	    set result {}
	    foreach item $data(itemList) {
		lappend result [lindex $item $col]
	    }
	    return $result
	}

	-title {
	    return [lindex $data(-columns) [expr {3*$col + 1}]]
	}

	-width {
	    return [lindex $data(-columns) [expr {3*$col}]]
	}

	default {
	    if {[info exists data($col$opt)]} {
		return $data($col$opt)
	    } else {
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doRowConfig
#
# Applies the value val of the row configuration option opt to the row'th row
# of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doRowConfig {row win opt val} {
    variable canElide
    variable elide
    variable snipSides
    variable pu
    upvar ::tablelist::ns${win}::data data
    foreach {row p w inBody diff} [getConfigParams $win $row] {}

    switch -- $opt {
	-background -
	-foreground {
	    set key [lindex $data(${p}keyList) $row]
	    set name $key$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag row$opt-$val in the text widget
		#
		set tag row$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag disabled

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		${p}updateColorsWhenIdle $win
	    }
	}

	-elide {
	    set val [expr {$val ? 1 : 0}]
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key$opt
	    set line [expr {$row + 1}]
	    set viewChanged 0

	    if {$val} {					;# eliding the row
		if {![info exists data($name)]} {
		    set data($name) 1
		    $w tag add elidedRow $line.0 $line.end+1$pu

		    if {![info exists data($key-hide)]} {
			incr data(nonViewableRowCount)
			set viewChanged 1

			if {$row == $data(editRow)} {
			    doCancelEditing $win
			}
		    }
		}
	    } else {					;# uneliding the row
		if {[info exists data($name)]} {
		    unset data($name)
		    $w tag remove elidedRow $line.0 $line.end+1$pu

		    if {![info exists data($key-hide)]} {
			incr data(nonViewableRowCount) -1
			set viewChanged 1
		    }
		}
	    }

	    if {$viewChanged} {
		#
		# Adjust the heights of the body text widget
		# and of the listbox child, if necessary
		#
		if {$data(-height) <= 0} {
		    set viewableRowCount \
			[expr {$data(itemCount) - $data(nonViewableRowCount)}]
		    $w configure -height $viewableRowCount
		    $data(lb) configure -height $viewableRowCount
		}

		#
		# Build the list of those dynamic-width columns
		# whose widths are affected by (un)eliding the row
		#
		set colWidthsChanged 0
		set colIdxList {}
		set displayedItem [lrange $item 0 $data(lastCol)]
		if {$data(hasFmtCmds)} {
		    set displayedItem [formatItem $win $key $row $displayedItem]
		}
		if {[string match "*\t*" $displayedItem]} {
		    set displayedItem [mapTabs $displayedItem]
		}
		set col 0
		foreach text $displayedItem {pixels alignment} $data(colList) {
		    if {($data($col-hide) && !$canElide) || $pixels != 0} {
			incr col
			continue
		    }

		    getAuxData $win $key $col auxType auxWidth
		    getIndentData $win $key $col indentWidth
		    set cellFont [getCellFont $win $key $col]
		    set elemWidth [getElemWidth $win $text $auxWidth \
				   $indentWidth $cellFont]
		    if {$val} {				;# eliding the row
			if {$elemWidth == $data($col-elemWidth) &&
			    [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    } else {				;# uneliding the row
			if {$elemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$elemWidth > $data($col-elemWidth)} {
			    set data($col-elemWidth) $elemWidth
			    set data($col-widestCount) 1
			    if {$elemWidth > $data($col-reqPixels)} {
				set data($col-reqPixels) $elemWidth
				set colWidthsChanged 1
			    }
			}
		    }

		    incr col
		}

		#
		# Invalidate the list of row indices indicating the
		# viewable rows and adjust the columns if necessary
		#
		set data(viewableRowList) {-1}
		if {$colWidthsChanged} {
		    adjustColumns $win $colIdxList 1
		}
	    }
	}

	-font {
	    #
	    # Save the current cell fonts in a temporary array
	    #
	    set item [lindex $data(${p}itemList) $row]
	    set key [lindex $item end]
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set oldCellFonts($col) [getCellFont $win $key $col]
	    }

	    set name $key$opt
	    if {[info exists data($name)]} {
		#
		# Remove the tag row$opt-$data($name) from the given row
		#
		set line [expr {$row + $diff}]
		$w tag remove row$opt-$data($name) $line.0 $line.end
	    }

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    if {$inBody} {
			incr data(rowTagRefCount) -1
		    }
		}
	    } else {
		#
		# Configure the tag row$opt-$val in the
		# text widget and apply it to the given row
		#
		set tag row$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag disabled
		set line [expr {$row + $diff}]
		$w tag add $tag $line.0 $line.end

		#
		# Save val in data($name)
		#
		if {$inBody && ![info exists data($name)]} {
		    incr data(rowTagRefCount)
		}
		set data($name) $val
	    }

	    set displayedItem [lrange $item 0 $data(lastCol)]
	    if {$data(hasFmtCmds)} {
		set displayedItem [formatItem $win $key $row $displayedItem]
	    }
	    if {[string match "*\t*" $displayedItem]} {
		set displayedItem [mapTabs $displayedItem]
	    }
	    set colWidthsChanged 0
	    set colIdxList {}
	    set line [expr {$row + $diff}]
	    set textIdx1 $line.1
	    set col 0
	    foreach text $displayedItem {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Adjust the cell text and the image or window width
		#
		set multiline [string match "*\n*" $text]
		set cellFont [getCellFont $win $key $col]
		set workPixels $pixels
		if {$pixels == 0} {		;# convention: dynamic width
		    set textSav $text
		    getAuxData $win $key $col auxType auxWidthSav
		    getIndentData $win $key $col indentWidthSav

		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set workPixels $data($col-maxPixels)
			}
		    }
		}
		set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
		set indent [getIndentData $win $key $col indentWidth]
		set maxTextWidth $workPixels
		if {$workPixels != 0} {
		    incr workPixels $data($col-delta)
		    set maxTextWidth \
			[getMaxTextWidth $workPixels $auxWidth $indentWidth]

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $maxTextWidth} {
			    set multiline 1
			}
		    }
		}
		set snipSide $snipSides($alignment,$data($col-changesnipside))
		if {$multiline} {
		    set list [split $text "\n"]
		    if {$data($col-wrap)} {
			set snipSide ""
		    }
		    adjustMlElem $win list auxWidth indentWidth $cellFont \
				 $workPixels $snipSide $data(-snipstring)
		    set msgScript [list ::tablelist::displayText $win $key \
				   $col [join $list "\n"] $cellFont \
				   $maxTextWidth $alignment]
		} else {
		    adjustElem $win text auxWidth indentWidth $cellFont \
			       $workPixels $snipSide $data(-snipstring)
		}

		if {$inBody &&
		    $row == $data(editRow) && $col == $data(editCol)} {
		    #
		    # Configure the edit window
		    #
		    setEditWinFont $win
		} else {
		    #
		    # Update the text widget's content between the two tabs
		    #
		    set textIdx2 [$w search $elide "\t" $textIdx1 $line.end]
		    if {$multiline} {
			updateMlCell $w $textIdx1 $textIdx2 $msgScript $aux \
				     $auxType $auxWidth $indent $indentWidth \
				     $alignment [getVAlignment $win $key $col]
		    } else {
			updateCell $w $textIdx1 $textIdx2 $text $aux \
				   $auxType $auxWidth $indent $indentWidth \
				   $alignment [getVAlignment $win $key $col]
		    }
		}

		if {$pixels == 0 && ![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    #
		    # Check whether the width of the current column has changed
		    #
		    set text $textSav
		    set auxWidth $auxWidthSav
		    set indentWidth $indentWidthSav
		    set newElemWidth [getElemWidth $win $text $auxWidth \
				      $indentWidth $cellFont]
		    if {$newElemWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $newElemWidth
			set data($col-widestCount) 1
			if {$newElemWidth > $data($col-reqPixels)} {
			    set data($col-reqPixels) $newElemWidth
			    set colWidthsChanged 1
			}
		    } else {
			set oldElemWidth [getElemWidth $win $text $auxWidth \
					  $indentWidth $oldCellFonts($col)]
			if {$oldElemWidth < $data($col-elemWidth) &&
			    $newElemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$oldElemWidth == $data($col-elemWidth) &&
				  $newElemWidth < $oldElemWidth &&
				  [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    }
		}

		set textIdx1 [$w search $elide "\t" $textIdx1 $line.end]+2$pu
		incr col
	    }

	    #
	    # Adjust the columns if necessary and schedule
	    # some operations for execution at idle time
	    #
	    if {$colWidthsChanged} {
		adjustColumns $win $colIdxList 1
	    }
	    updateViewWhenIdle $win
	}

	-hide {
	    set val [expr {$val ? 1 : 0}]
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key$opt
	    set line [expr {$row + 1}]
	    set viewChanged 0
	    set callerProc [lindex [info level -1] 0]

	    if {$val} {					;# hiding the row
		if {![info exists data($name)]} {
		    set data($name) 1
		    $w tag add hiddenRow $line.0 $line.end+1$pu

		    if {![info exists data($key-elide)]} {
			incr data(nonViewableRowCount)
			set viewChanged 1

			#
			# Elide the descendants of this item
			#
			set fromRow [expr {$row + 1}]
			set toRow [nodeRow $win $key end]
			for {set _row $fromRow} {$_row < $toRow} {incr _row} {
			    doRowConfig $_row $win -elide 1
			}

			if {[string match "*configureWidget" $callerProc]} {
			    adjustRowIndex $win data(anchorRow) 1

			    set activeRow $data(activeRow)
			    adjustRowIndex $win activeRow 1
			    set data(activeRow) $activeRow
			}

			if {$row == $data(editRow)} {
			    doCancelEditing $win
			}
		    }
		}
	    } else {					;# unhiding the row
		if {[info exists data($name)]} {
		    unset data($name)
		    $w tag remove hiddenRow $line.0 $line.end+1$pu

		    if {![info exists data($key-elide)]} {
			incr data(nonViewableRowCount) -1
			set viewChanged 1

			if {[info exists data($key,$data(treeCol)-indent)] &&
			    [string match "*expanded*" \
			     $data($key,$data(treeCol)-indent)]} {
			    expandSubCmd $win [list $row -partly]
			}
		    }
		}
	    }

	    if {$viewChanged} {
		#
		# Adjust the heights of the body text widget
		# and of the listbox child, if necessary
		#
		if {$data(-height) <= 0} {
		    set viewableRowCount \
			[expr {$data(itemCount) - $data(nonViewableRowCount)}]
		    $w configure -height $viewableRowCount
		    $data(lb) configure -height $viewableRowCount
		}

		#
		# Build the list of those dynamic-width columns
		# whose widths are affected by (un)hiding the row
		#
		set colWidthsChanged 0
		set colIdxList {}
		set displayedItem [lrange $item 0 $data(lastCol)]
		if {$data(hasFmtCmds)} {
		    set displayedItem [formatItem $win $key $row $displayedItem]
		}
		if {[string match "*\t*" $displayedItem]} {
		    set displayedItem [mapTabs $displayedItem]
		}
		set col 0
		foreach text $displayedItem {pixels alignment} $data(colList) {
		    if {($data($col-hide) && !$canElide) || $pixels != 0} {
			incr col
			continue
		    }

		    getAuxData $win $key $col auxType auxWidth
		    getIndentData $win $key $col indentWidth
		    set cellFont [getCellFont $win $key $col]
		    set elemWidth [getElemWidth $win $text $auxWidth \
				   $indentWidth $cellFont]
		    if {$val} {				;# hiding the row
			if {$elemWidth == $data($col-elemWidth) &&
			    [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    } else {				;# unhiding the row
			if {$elemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$elemWidth > $data($col-elemWidth)} {
			    set data($col-elemWidth) $elemWidth
			    set data($col-widestCount) 1
			    if {$elemWidth > $data($col-reqPixels)} {
				set data($col-reqPixels) $elemWidth
				set colWidthsChanged 1
			    }
			}
		    }

		    incr col
		}

		#
		# Invalidate the list of row indices indicating the
		# viewable rows and adjust the columns if necessary
		#
		set data(viewableRowList) {-1}
		if {$colWidthsChanged} {
		    adjustColumns $win $colIdxList 1
		}

		#
		# Schedule some operations for execution at idle time
		# and generate a virtual event only if the caller proc
		# is configureWidget, in order to make sure that only
		# one event per caller proc invocation will be generated
		#
		if {[string match "*configureWidget" $callerProc]} {
		    makeStripesWhenIdle $win
		    showLineNumbersWhenIdle $win
		    updateViewWhenIdle $win

		    genVirtualEvent $win <<TablelistRowHiddenStateChanged>> $row
		}
	    }
	}

	-name {
	    set key [lindex $data(${p}keyList) $row]
	    if {[string length $val] == 0} {
		if {[info exists data($key$opt)]} {
		    unset data($key$opt)
		}
	    } else {
		set data($key$opt) $val
	    }
	}

	-selectable {
	    set val [expr {$val ? 1 : 0}]
	    set key [lindex $data(keyList) $row]

	    if {$val} {
		if {[info exists data($key$opt)]} {
		    unset data($key$opt)
		}
	    } else {
		#
		# Set data($key$opt) to 0 and deselect the row
		#
		set data($key$opt) 0
		rowSelection $win clear $row $row
	    }
	}

	-selectbackground -
	-selectforeground {
	    set key [lindex $data(keyList) $row]
	    set name $key$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag row$opt-$val in the body text widget
		#
		set tag row$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -select
		$w tag configure $tag -$optTail $val
		$w tag lower $tag disabled

		#
		# Save val in data($name)
		#
		set data($name) [$w tag cget $tag -$optTail]
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-text {
	    if {$data(isDisabled)} {
		return ""
	    }

	    set colWidthsChanged 0
	    set colIdxList {}
	    set oldItem [lindex $data(${p}itemList) $row]
	    set key [lindex $oldItem end]
	    set newItem [adjustItem $val $data(colCount)]
	    if {$data(hasFmtCmds)} {
		set displayedItem [formatItem $win $key $row $newItem]
	    } else {
		set displayedItem $newItem
	    }
	    if {[string match "*\t*" $displayedItem]} {
		set displayedItem [mapTabs $displayedItem]
	    }
	    set line [expr {$row + $diff}]
	    set textIdx1 $line.1
	    set col 0
	    foreach text $displayedItem {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Adjust the cell text and the image or window width
		#
		set multiline [string match "*\n*" $text]
		set cellFont [getCellFont $win $key $col]
		set workPixels $pixels
		if {$pixels == 0} {		;# convention: dynamic width
		    set textSav $text
		    getAuxData $win $key $col auxType auxWidthSav
		    getIndentData $win $key $col indentWidthSav

		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set workPixels $data($col-maxPixels)
			}
		    }
		}
		set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
		set indent [getIndentData $win $key $col indentWidth]
		set maxTextWidth $workPixels
		if {$workPixels != 0} {
		    incr workPixels $data($col-delta)
		    set maxTextWidth \
			[getMaxTextWidth $workPixels $auxWidth $indentWidth]

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $maxTextWidth} {
			    set multiline 1
			}
		    }
		}
		set snipSide $snipSides($alignment,$data($col-changesnipside))
		if {$multiline} {
		    set list [split $text "\n"]
		    if {$data($col-wrap)} {
			set snipSide ""
		    }
		    adjustMlElem $win list auxWidth indentWidth $cellFont \
				 $workPixels $snipSide $data(-snipstring)
		    set msgScript [list ::tablelist::displayText $win $key \
				   $col [join $list "\n"] $cellFont \
				   $maxTextWidth $alignment]
		} else {
		    adjustElem $win text auxWidth indentWidth $cellFont \
			       $workPixels $snipSide $data(-snipstring)
		}

		if {!$inBody ||
		    $row != $data(editRow) || $col != $data(editCol)} {
		    #
		    # Update the text widget's content between the two tabs
		    #
		    set textIdx2 [$w search $elide "\t" $textIdx1 $line.end]
		    if {$multiline} {
			updateMlCell $w $textIdx1 $textIdx2 $msgScript $aux \
				     $auxType $auxWidth $indent $indentWidth \
				     $alignment [getVAlignment $win $key $col]
		    } else {
			updateCell $w $textIdx1 $textIdx2 $text $aux \
				   $auxType $auxWidth $indent $indentWidth \
				   $alignment [getVAlignment $win $key $col]
		    }
		}

		if {$pixels == 0 && ![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    #
		    # Check whether the width of the current column has changed
		    #
		    set text $textSav
		    set auxWidth $auxWidthSav
		    set indentWidth $indentWidthSav
		    set newElemWidth [getElemWidth $win $text $auxWidth \
				      $indentWidth $cellFont]
		    if {$newElemWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $newElemWidth
			set data($col-widestCount) 1
			if {$newElemWidth > $data($col-reqPixels)} {
			    set data($col-reqPixels) $newElemWidth
			    set colWidthsChanged 1
			}
		    } else {
			set oldText [lindex $oldItem $col]
			if {[lindex $data(fmtCmdFlagList) $col]} {
			    set oldText \
				[formatElem $win $key $row $col $oldText]
			}
			if {[string match "*\t*" $oldText]} {
			    set oldText [mapTabs $oldText]
			}
			set oldElemWidth [getElemWidth $win $oldText $auxWidth \
					  $indentWidth $cellFont]
			if {$oldElemWidth < $data($col-elemWidth) &&
			    $newElemWidth == $data($col-elemWidth)} {
			    incr data($col-widestCount)
			} elseif {$oldElemWidth == $data($col-elemWidth) &&
				  $newElemWidth < $oldElemWidth &&
				  [incr data($col-widestCount) -1] == 0} {
			    set colWidthsChanged 1
			    lappend colIdxList $col
			}
		    }
		}

		set textIdx1 [$w search $elide "\t" $textIdx1 $line.end]+2$pu
		incr col
	    }

	    #
	    # Replace the row's content in the list variable if present
	    #
	    if {$inBody && $data(hasListVar)} {
		upvar #0 $data(-listvariable) var
		trace vdelete var wu $data(listVarTraceCmd)
		set var [lreplace $var $row $row $newItem]
		trace variable var wu $data(listVarTraceCmd)
	    }

	    #
	    # Replace the row's content in the internal list
	    #
	    lappend newItem $key
	    set data(${p}itemList) \
		[lreplace $data(${p}itemList) $row $row $newItem]

	    #
	    # Adjust the columns if necessary and schedule
	    # some operations for execution at idle time
	    #
	    if {$colWidthsChanged} {
		adjustColumns $win $colIdxList 1
	    }
	    if {$inBody} {
		showLineNumbersWhenIdle $win
	    }
	    updateViewWhenIdle $win
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doRowCget
#
# Returns the value of the row configuration option opt for the row'th row of
# the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doRowCget {row win opt} {
    upvar ::tablelist::ns${win}::data data
    foreach {row p w inBody diff} [getConfigParams $win $row] {}
    set item [lindex $data(${p}itemList) $row]

    switch -- $opt {
	-text {
	    return [lrange $item 0 $data(lastCol)]
	}

	-elide -
	-hide {
	    set key [lindex $item end]
	    if {[info exists data($key$opt)]} {
		return $data($key$opt)
	    } else {
		return 0
	    }
	}

	-selectable {
	    set key [lindex $item end]
	    if {[info exists data($key$opt)]} {
		return $data($key$opt)
	    } else {
		return 1
	    }
	}

	default {
	    set key [lindex $item end]
	    if {[info exists data($key$opt)]} {
		return $data($key$opt)
	    } else {
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doCellConfig
#
# Applies the value val of the cell configuration option opt to the cell
# row,col of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doCellConfig {row col win opt val} {
    variable canElide
    variable snipSides
    variable pu
    upvar ::tablelist::ns${win}::data data
    foreach {row p w inBody diff} [getConfigParams $win $row] {}

    switch -- $opt {
	-background -
	-foreground {
	    set key [lindex $data(${p}keyList) $row]
	    set name $key,$col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag cell$opt-$val in the text widget
		#
		set tag cell$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag disabled

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		${p}updateColorsWhenIdle $win
	    }
	}

	-editable {
	    #
	    # Save the boolean value specified by val in data($key,$col$opt)
	    # and invoke the motion handler if necessary
	    #
	    set key [lindex $data(keyList) $row]
	    set data($key,$col$opt) [expr {$val ? 1 : 0}]
	    if {$data(-showeditcursor)} {
		invokeMotionHandler $win
	    }
	}

	-editwindow {
	    variable editWin
	    if {[info exists editWin($val-creationCmd)]} {
		set key [lindex $data(keyList) $row]
		set data($key,$col$opt) $val
	    } else {
		return -code error "name \"$val\" is not registered\
				    for interactive cell editing"
	    }
	}

	-font {
	    #
	    # Save the current cell font
	    #
	    set item [lindex $data(${p}itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    set oldCellFont [getCellFont $win $key $col]

	    if {[info exists data($name)] &&
		(!$data($col-hide) || $canElide)} {
		#
		# Remove the tag cell$opt-$data($name) from the given cell
		#
		findTabs $win $w [expr {$row + $diff}] $col $col tabIdx1 tabIdx2
		$w tag remove cell$opt-$data($name) $tabIdx1 $tabIdx2+1$pu
	    }

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    if {$inBody} {
			incr data(cellTagRefCount) -1
		    }
		}
	    } else {
		#
		# Configure the tag cell$opt-$val in the text widget
		#
		set tag cell$opt-$val
		$w tag configure $tag $opt $val
		$w tag lower $tag disabled

		if {!$data($col-hide) || $canElide} {
		    #
		    # Apply the tag to the given cell
		    #
		    findTabs $win $w [expr {$row + $diff}] $col $col \
			     tabIdx1 tabIdx2
		    $w tag add $tag $tabIdx1 $tabIdx2+1$pu
		}

		#
		# Save val in data($name)
		#
		if {$inBody && ![info exists data($name)]} {
		    incr data(cellTagRefCount)
		}
		set data($name) $val
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {!$data($col-hide)} {
		if {$inBody &&
		    $row == $data(editRow) && $col == $data(editCol)} {
		    #
		    # Configure the edit window
		    #
		    setEditWinFont $win
		} else {
		    #
		    # Update the text widget's content between the two tabs
		    #
		    findTabs $win $w [expr {$row + $diff}] $col $col \
			     tabIdx1 tabIdx2
		    if {$multiline} {
			updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
				     $auxType $auxWidth $indent $indentWidth \
				     $alignment [getVAlignment $win $key $col]
		    } else {
			updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
				   $auxType $auxWidth $indent $indentWidth \
				   $alignment [getVAlignment $win $key $col]
		    }
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $text $auxWidth \
				      $indentWidth $oldCellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-image {
	    if {$data(isDisabled)} {
		return ""
	    }

	    #
	    # Save the old image or window width
	    #
	    set item [lindex $data(${p}itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    getAuxData $win $key $col oldAuxType oldAuxWidth

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    set imgLabel $w.img_$key,$col
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    if {$inBody} {
			incr data(imgCount) -1
		    }
		    destroy $imgLabel
		}
	    } else {
		if {$inBody && ![info exists data($name)]} {
		    incr data(imgCount)
		}
		if {[winfo exists $imgLabel] &&
		    [string compare $val $data($name)] != 0} {
		    destroy $imgLabel
		}
		set data($name) $val
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set oldText $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) && (!$inBody ||
		$row != $data(editRow) || $col != $data(editCol))} {
		#
		# Delete the old cell content between the two tabs,
		# and insert the text and the auxiliary object
		#
		findTabs $win $w [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $oldText $oldAuxWidth \
				      $indentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-indent {
	    if {$data(isDisabled)} {
		return ""
	    }

	    #
	    # Save the old indentation width
	    #
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    getIndentData $win $key $col oldIndentWidth

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    set indentLabel $w.ind_$key,$col
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    incr data(indentCount) -1
		    destroy $indentLabel
		}
	    } else {
		if {![info exists data($name)]} {
		    incr data(indentCount)
		}
		if {[winfo exists $indentLabel] &&
		    [string compare $val $data($name)] != 0} {
		    destroy $indentLabel
		}
		set data($name) $val
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set oldText $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) &&
		($row != $data(editRow) || $col != $data(editCol))} {
		#
		# Delete the old cell content between the two tabs,
		# and insert the text and the auxiliary object
		#
		findTabs $win $w [expr {$row + 1}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $oldText $auxWidth \
				      $oldIndentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-selectbackground -
	-selectforeground {
	    set key [lindex $data(keyList) $row]
	    set name $key,$col$opt

	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		#
		# Configure the tag cell$opt-$val in the body text widget
		#
		set tag cell$opt-$val
		set optTail [string range $opt 7 end]	;# remove the -select
		$w tag configure $tag -$optTail $val
		$w tag lower $tag disabled

		#
		# Save val in data($name)
		#
		set data($name) $val
	    }

	    if {!$data(isDisabled)} {
		updateColorsWhenIdle $win
	    }
	}

	-stretchwindow {
	    #
	    # Save the boolean value specified by val in data($key,$col$opt)
	    #
	    set item [lindex $data(${p}itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    if {$val} {
		set data($name) 1
	    } elseif {[info exists data($name)]} {
		unset data($name)
	    }

	    if {($data($col-hide) && !$canElide) ||
		($inBody && $row == $data(editRow) && $col == $data(editCol))} {
		return ""
	    }

	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $pixels]
	    if {$auxType < 2} {			;# no window
		return ""
	    }

	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $pixels
	    if {$pixels != 0} {
		incr pixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $pixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }

	    #
	    # Adjust the cell text and the window width
	    #
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $pixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key $row \
			       [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $pixels $snipSide $data(-snipstring)
	    }

	    #
	    # Update the text widget's content between the two tabs
	    #
	    findTabs $win $w [expr {$row + $diff}] $col $col tabIdx1 tabIdx2
	    if {$multiline} {
		updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
			     $auxType $auxWidth $indent $indentWidth \
			     $alignment [getVAlignment $win $key $col]
	    } else {
		updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
			   $auxType $auxWidth $indent $indentWidth \
			   $alignment [getVAlignment $win $key $col]
	    }
	}

	-text {
	    if {$data(isDisabled)} {
		return ""
	    }

	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text $val
	    set oldItem [lindex $data(${p}itemList) $row]
	    set key [lindex $oldItem end]
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    if {$fmtCmdFlag} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set textSav $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) && (!$inBody ||
		$row != $data(editRow) || $col != $data(editCol))} {
		#
		# Update the text widget's content between the two tabs
		#
		findTabs $win $w [expr {$row + $diff}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Replace the cell's content in the internal list
	    #
	    set newItem [lreplace $oldItem $col $col $val]
	    set data(${p}itemList) \
		[lreplace $data(${p}itemList) $row $row $newItem]

	    #
	    # Replace the cell's content in the list variable if present
	    #
	    if {$inBody && $data(hasListVar)} {
		upvar #0 $data(-listvariable) var
		trace vdelete var wu $data(listVarTraceCmd)
		set var [lreplace $var $row $row \
			 [lrange $newItem 0 $data(lastCol)]]
		trace variable var wu $data(listVarTraceCmd)
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldText [lindex $oldItem $col]
		    if {$fmtCmdFlag} {
			set oldText [formatElem $win $key $row $col $oldText]
		    }
		    if {[string match "*\t*" $oldText]} {
			set oldText [mapTabs $oldText]
		    }
		    set oldElemWidth [getElemWidth $win $oldText $auxWidth \
				      $indentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    if {$inBody} {
		showLineNumbersWhenIdle $win
	    }
	    updateViewWhenIdle $win
	}

	-valign {
	    #
	    # Save the properly formatted value of val in
	    # data($key,$col$opt) and redisplay the cell
	    #
	    variable valignments
	    set val [mwutil::fullOpt "vertical alignment" $val $valignments]
	    set key [lindex $data(${p}keyList) $row]
	    set data($key,$col$opt) $val
	    redisplayCol $win $col $row $row
	}

	-window {
	    if {$data(isDisabled)} {
		return ""
	    }

	    #
	    # Save the old image or window width
	    #
	    set item [lindex $data(${p}itemList) $row]
	    set key [lindex $item end]
	    set name $key,$col$opt
	    getAuxData $win $key $col oldAuxType oldAuxWidth
	    getIndentData $win $key $col oldIndentWidth

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    set aux $w.frm_$key,$col
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		    unset data($key,$col-reqWidth)
		    unset data($key,$col-reqHeight)

		    #
		    # If the cell index is contained in the list
		    # data(${p}cellsToReconfig) then remove it from the list
		    #
		    set n [lsearch -exact $data(${p}cellsToReconfig) $row,$col]
		    if {$n >= 0} {
			set data(${p}cellsToReconfig) \
			    [lreplace $data(${p}cellsToReconfig) $n $n]
		    }
		    if {$inBody} {
			incr data(winCount) -1
		    }
		    destroy $aux
		}
	    } else {
		if {$inBody && ![info exists data($name)]} {
		    incr data(winCount)
		}
		if {[info exists data($name)] &&
		    [string compare $val $data($name)] != 0} {
		    destroy $aux
		}
		if {![winfo exists $aux]} {
		    #
		    # Create the frame and evaluate the specified script
		    # that creates a child widget within the frame
		    #
		    tk::frame $aux -borderwidth 0 -class TablelistWindow \
				   -container 0 -highlightthickness 0 \
				   -relief flat -takefocus 0
		    catch {$aux configure -padx 0 -pady 0}
		    if {$inBody} {
			bindtags $aux [linsert [bindtags $aux] 1 \
				       $data(bodyTag) TablelistBody]
		    } else {
			bindtags $aux [linsert [bindtags $aux] 1 \
				       $data(headerTag) TablelistHeader]
		    }
		    uplevel #0 $val [list $win $row $col $aux.w]
		}
		set data($name) $val
		set data($key,$col-reqWidth) [winfo reqwidth $aux.w]
		set data($key,$col-reqHeight) [winfo reqheight $aux.w]
		$aux configure -height $data($key,$col-reqHeight)

		#
		# Add the cell index to the list data(${p}cellsToReconfig)
		# if the window's requested width or height is not yet known
		#
		if {($data($key,$col-reqWidth) == 1 ||
		     $data($key,$col-reqHeight) == 1) &&
		    [lsearch -exact $data(${p}cellsToReconfig) $row,$col] < 0} {
		    lappend data(${p}cellsToReconfig) $row,$col
		    if {![info exists data(reconfigId)]} {
			set data(reconfigId) \
			    [after idle [list tablelist::reconfigWindows $win]]
		    }
		}
	    }

	    #
	    # Adjust the cell text and the image or window width
	    #
	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    set workPixels $pixels
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }
	    set oldText $text
	    set multiline [string match "*\n*" $text]
	    set cellFont [getCellFont $win $key $col]
	    if {$pixels == 0} {			;# convention: dynamic width
		set textSav $text
		getAuxData $win $key $col auxType auxWidthSav
		getIndentData $win $key $col indentWidthSav

		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set workPixels $data($col-maxPixels)
		    }
		}
	    }
	    set aux [getAuxData $win $key $col auxType auxWidth $workPixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set maxTextWidth $workPixels
	    if {$workPixels != 0} {
		incr workPixels $data($col-delta)
		set maxTextWidth \
		    [getMaxTextWidth $workPixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			set multiline 1
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    if {$multiline} {
		set list [split $text "\n"]
		if {$data($col-wrap)} {
		    set snipSide ""
		}
		adjustMlElem $win list auxWidth indentWidth $cellFont \
			     $workPixels $snipSide $data(-snipstring)
		set msgScript [list ::tablelist::displayText $win $key \
			       $col [join $list "\n"] $cellFont \
			       $maxTextWidth $alignment]
	    } else {
		adjustElem $win text auxWidth indentWidth $cellFont \
			   $workPixels $snipSide $data(-snipstring)
	    }

	    if {(!$data($col-hide) || $canElide) && (!$inBody ||
		$row != $data(editRow) || $col != $data(editCol))} {
		#
		# Delete the old cell content between the two tabs,
		# and insert the text and the auxiliary object
		#
		findTabs $win $w [expr {$row + $diff}] $col $col tabIdx1 tabIdx2
		if {$multiline} {
		    updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
				 $auxType $auxWidth $indent $indentWidth \
				 $alignment [getVAlignment $win $key $col]
		} else {
		    updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
			       $auxType $auxWidth $indent $indentWidth \
			       $alignment [getVAlignment $win $key $col]
		}
	    }

	    #
	    # Adjust the columns if necessary
	    #
	    if {$pixels == 0 && ![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set text $textSav
		set auxWidth $auxWidthSav
		set indentWidth $indentWidthSav
		set newElemWidth [getElemWidth $win $text $auxWidth \
				  $indentWidth $cellFont]
		if {$newElemWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $newElemWidth
		    set data($col-widestCount) 1
		    if {$newElemWidth > $data($col-reqPixels)} {
			set data($col-reqPixels) $newElemWidth
			adjustColumns $win {} 1
		    }
		} else {
		    set oldElemWidth [getElemWidth $win $oldText $oldAuxWidth \
				      $oldIndentWidth $cellFont]
		    if {$oldElemWidth < $data($col-elemWidth) &&
			$newElemWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$oldElemWidth == $data($col-elemWidth) &&
			      $newElemWidth < $oldElemWidth &&
			      [incr data($col-widestCount) -1] == 0} {
			adjustColumns $win $col 1
		    }
		}
	    }

	    updateViewWhenIdle $win
	}

	-windowdestroy -
	-windowupdate {
	    set key [lindex $data(${p}keyList) $row]
	    set name $key,$col$opt

	    #
	    # Delete data($name) or save the specified value in it
	    #
	    if {[string length $val] == 0} {
		if {[info exists data($name)]} {
		    unset data($name)
		}
	    } else {
		set data($name) $val
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doCellCget
#
# Returns the value of the cell configuration option opt for the cell row,col
# of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::doCellCget {row col win opt} {
    upvar ::tablelist::ns${win}::data data
    foreach {row p w inBody diff} [getConfigParams $win $row] {}

    switch -- $opt {
	-editable {
	    return [isCellEditable $win $row $col]
	}

	-editwindow {
	    return [getEditWindow $win $row $col 0]
	}

	-stretchwindow {
	    set key [lindex $data(${p}keyList) $row]
	    if {[info exists data($key,$col$opt)]} {
		return $data($key,$col$opt)
	    } else {
		return 0
	    }
	}

	-text {
	    return [lindex [lindex $data(${p}itemList) $row] $col]
	}

	-valign {
	    set key [lindex $data(${p}keyList) $row]
	    return [getVAlignment $win $key $col]
	}

	default {
	    set key [lindex $data(${p}keyList) $row]
	    if {[info exists data($key,$col$opt)]} {
		return $data($key,$col$opt)
	    } else {
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::makeListVar
#
# Arranges for the global variable specified by varName to become the list
# variable associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeListVar {win varName} {
    upvar ::tablelist::ns${win}::data data
    if {[string length $varName] == 0} {
	#
	# If there is an old list variable associated with the
	# widget then remove the trace set on this variable
	#
	if {$data(hasListVar)} {
	    synchronize $win
	    upvar #0 $data(-listvariable) var
	    trace vdelete var wu $data(listVarTraceCmd)
	}
	return ""
    }

    #
    # The list variable may be an array element but must not be an array
    #
    if {![regexp {^(.*)\((.*)\)$} $varName dummy name1 name2]} {
	if {[array exists $varName]} {
	    return -code error "variable \"$varName\" is array"
	}
	set name1 $varName
	set name2 ""
    }

    #
    # If there is an old list variable associated with the
    # widget then remove the trace set on this variable
    #
    if {$data(hasListVar)} {
	synchronize $win
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
    }

    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)]
	}
    }

    #
    # Set a trace on the new list variable
    #
    trace variable var wu $data(listVarTraceCmd)
}

#------------------------------------------------------------------------------
# tablelist::isRowViewable
#
# Checks whether the given row of the tablelist widget win is viewable.
#------------------------------------------------------------------------------
proc tablelist::isRowViewable {win row} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [expr {![info exists data($key-elide)] &&
		  ![info exists data($key-hide)]}]
}

#------------------------------------------------------------------------------
# tablelist::getCellFont
#
# Returns the font to be used in the tablelist cell specified by win, key, and
# col.
#------------------------------------------------------------------------------
proc tablelist::getCellFont {win key col} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data($key,$col-font)]} {
	return $data($key,$col-font)
    } elseif {[info exists data($key-font)]} {
	return $data($key-font)
    } else {
	return [lindex $data(colFontList) $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::reconfigWindows
#
# Invoked as an after idle callback, this procedure forces any geometry manager
# calculations to be completed and then applies the -window option a second
# time to those cells whose embedded windows' requested widths or heights were
# still unknown.
#------------------------------------------------------------------------------
proc tablelist::reconfigWindows win {
    #
    # Force any geometry manager calculations to be completed first
    #
    update idletasks
    if {[destroyed $win]} {
	return ""
    }

    #
    # Reconfigure the cells specified in the list data(cellsToReconfig)
    #
    upvar ::tablelist::ns${win}::data data
    foreach cellIdx $data(cellsToReconfig) {
	foreach {row col} [split $cellIdx ","] {}
	set key [lindex $data(keyList) $row]
	if {[info exists data($key,$col-window)]} {
	    doCellConfig $row $col $win -window $data($key,$col-window)
	}
    }

    #
    # Reconfigure the cells specified in the list data(hdr_cellsToReconfig)
    #
    foreach cellIdx $data(hdr_cellsToReconfig) {
	foreach {row col} [split $cellIdx ","] {}
	set key [lindex $data(hdr_keyList) $row]
	if {[info exists data($key,$col-window)]} {
	    doCellConfig h$row $col $win -window $data($key,$col-window)
	}
    }

    unset data(reconfigId)
    set data(cellsToReconfig) {}
    set data(hdr_cellsToReconfig) {}
}

#------------------------------------------------------------------------------
# tablelist::isCellEditable
#
# Checks whether the given cell of the tablelist widget win is editable.
#------------------------------------------------------------------------------
proc tablelist::isCellEditable {win row col} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    if {[info exists data($key,$col-editable)]} {
	return $data($key,$col-editable)
    } else {
	return $data($col-editable)
    }
}

#------------------------------------------------------------------------------
# tablelist::getEditWindow
#
# Returns the value of the -editwindow option at cell or column level for the
# given cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getEditWindow {win row col {skipLeadingColons 1}} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    if {[info exists data($key,$col-editwindow)]} {
	set name $data($key,$col-editwindow)
    } elseif {[info exists data($col-editwindow)]} {
	set name $data($col-editwindow)
    } else {
	return "entry"
    }

    if {[regexp {^::ttk::(entry|spinbox|combobox|checkbutton|menubutton)$} \
	 $name] && $skipLeadingColons} {
	set name [string range $name 2 end]
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::getVAlignment
#
# Returns the value of the -valign option at cell or column level for the given
# cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getVAlignment {win key col} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data($key,$col-valign)]} {
	return $data($key,$col-valign)
    } else {
	return $data($col-valign)
    }
}

#------------------------------------------------------------------------------
# tablelist::getConfigParams
#
# For a given row argument of the form h<number> or <number>, the procedure
# returns a list consisting of <number>, the prefix "hdr_" or "" (for
# "keyList", "itemList", "cellsToReconfig", and "updateColorsWhenIdle"), the
# text widget path name $data(hdrTxt) or $data(body), 0 (false) or 1 (true)
# indicating whether this is the tablelist's body, and 2 or 1 (the difference
# between the text widget line number corresponding to <number> and <number>
# itself).
#------------------------------------------------------------------------------
proc tablelist::getConfigParams {win row} {
    upvar ::tablelist::ns${win}::data data

    if {[string match "h*" $row]} {
	return [list [string range $row 1 end] "hdr_" $data(hdrTxt) 0 2]
    } else {
	return [list $row "" $data(body) 1 1]
    }
}

Added libs/tablelist6.0/scripts/tablelistEdit.tcl.























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
#==============================================================================
# Contains the implementation of interactive cell editing in tablelist widgets.
#
# Structure of the module:
#   - Namespace initialization
#   - Public procedures related to interactive cell editing
#   - Private procedures implementing the interactive cell editing
#   - Private procedures used in bindings related to interactive cell editing
#
# Copyright (c) 2003-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Namespace initialization
# ========================
#

namespace eval tablelist {
    #
    # Register the Tk core widgets entry, text, checkbutton,
    # menubutton, and spinbox for interactive cell editing
    #
    proc addTkCoreWidgets {} {
	variable editWin
	variable pu

	set name entry
	array set editWin [list \
	    $name-creationCmd	"$name %W -width 0" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	0 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right} \
	]

	set name text
	array set editWin [list \
	    $name-creationCmd	"$name %W -padx 2 -pady 2 -wrap none" \
	    $name-putValueCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	    $name-getValueCmd	"%W get 1.0 end-1$pu" \
	    $name-putTextCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	    $name-getTextCmd	"%W get 1.0 end-1$pu" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	0 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down Prior Next
				 Control-Home Control-End Meta-b Meta-f
				 Control-p Control-n Meta-less Meta-greater} \
	]

	set name checkbutton
	array set editWin [list \
	    $name-creationCmd	"createCheckbutton %W" \
	    $name-putValueCmd	{set [%W cget -variable] %T} \
	    $name-getValueCmd	{set [%W cget -variable]} \
	    $name-putTextCmd	{set [%W cget -variable] %T} \
	    $name-getTextCmd	{set [%W cget -variable]} \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"%W invoke" \
	    $name-fontOpt	"" \
	    $name-useFormat	0 \
	    $name-useReqWidth	1 \
	    $name-usePadX	0 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	set name menubutton
	array set editWin [list \
	    $name-creationCmd	"createMenubutton %W" \
	    $name-putValueCmd	{set [%W cget -textvariable] %T} \
	    $name-getValueCmd	"%W cget -text" \
	    $name-putTextCmd	{set [%W cget -textvariable] %T} \
	    $name-getTextCmd	"%W cget -text" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"event generate %W <Button-1>" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	if {$::tk_version < 8.4} {
	    return ""
	}

	set name spinbox
	array set editWin [list \
	    $name-creationCmd	"$name %W -width 0" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down} \
	]
    }
    addTkCoreWidgets 

    #
    # Register the tile widgets ttk::entry, ttk::spinbox, ttk::combobox,
    # ttk::checkbutton, and ttk::menubutton for interactive cell editing
    #
    proc addTileWidgets {} {
	variable editWin

	set name ttk::entry
	array set editWin [list \
	    $name-creationCmd	"createTileEntry %W" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	0 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right} \
	]

	set name ttk::spinbox
	array set editWin [list \
	    $name-creationCmd	"createTileSpinbox %W" \
	    $name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down} \
	]

	set name ttk::combobox
	array set editWin [list \
	    $name-creationCmd	"createTileCombobox %W" \
	    $name-putValueCmd	"%W set %T" \
	    $name-getValueCmd	"%W get" \
	    $name-putTextCmd	"%W set %T" \
	    $name-getTextCmd	"%W get" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"event generate %W <Button-1>" \
	    $name-fontOpt	-font \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	1 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{Left Right Up Down} \
	]

	set name ttk::checkbutton
	array set editWin [list \
	    $name-creationCmd	"createTileCheckbutton %W" \
	    $name-putValueCmd	{set [%W cget -variable] %T} \
	    $name-getValueCmd	{set [%W cget -variable]} \
	    $name-putTextCmd	{set [%W cget -variable] %T} \
	    $name-getTextCmd	{set [%W cget -variable]} \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	{%W instate !pressed {%W invoke}} \
	    $name-fontOpt	"" \
	    $name-useFormat	0 \
	    $name-useReqWidth	1 \
	    $name-usePadX	0 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	set name ttk::menubutton
	array set editWin [list \
	    $name-creationCmd	"createTileMenubutton %W" \
	    $name-putValueCmd	{set [%W cget -textvariable] %T} \
	    $name-getValueCmd	"%W cget -text" \
	    $name-putTextCmd	{set [%W cget -textvariable] %T} \
	    $name-getTextCmd	"%W cget -text" \
	    $name-putListCmd	"" \
	    $name-getListCmd	"" \
	    $name-selectCmd	"" \
	    $name-invokeCmd	"event generate %W <Button-1>" \
	    $name-fontOpt	"" \
	    $name-useFormat	1 \
	    $name-useReqWidth	0 \
	    $name-usePadX	1 \
	    $name-isEntryLike	0 \
	    $name-focusWin	%W \
	    $name-reservedKeys	{} \
	]

	foreach {name value} [array get editWin ttk::*-creationCmd] {
	    set editWin(::$name) $value
	}
    }
    if {$::tk_version >= 8.4 && [llength [package versions tile]] > 0} {
	addTileWidgets 
    }
}

#
# Public procedures related to interactive cell editing
# =====================================================
#

#------------------------------------------------------------------------------
# tablelist::addBWidgetEntry
#
# Registers the Entry widget from the BWidget package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addBWidgetEntry {{name Entry}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"Entry %W -width 0" \
	$name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		0 \
	$name-isEntryLike	1 \
	$name-focusWin		%W \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addBWidgetSpinBox
#
# Registers the SpinBox widget from the BWidget package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addBWidgetSpinBox {{name SpinBox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"SpinBox %W -editable 1 -width 0" \
	$name-putValueCmd	"%W configure -text %T" \
	$name-getValueCmd	"%W cget -text" \
	$name-putTextCmd	"%W configure -text %T" \
	$name-getTextCmd	"%W cget -text" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.e \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addBWidgetComboBox
#
# Registers the ComboBox widget from the BWidget package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addBWidgetComboBox {{name ComboBox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"createBWidgetComboBox %W" \
	$name-putValueCmd	"%W configure -text %T" \
	$name-getValueCmd	"%W cget -text" \
	$name-putTextCmd	"%W configure -text %T" \
	$name-getTextCmd	"%W cget -text" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"%W.a invoke" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.e \
	$name-reservedKeys	{Left Right Up Down} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrEntryfield
#
# Registers the entryfield widget from the Iwidgets package for interactive
# cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrEntryfield {{name entryfield}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::entryfield %W -width 0" \
	$name-putValueCmd	"%W clear; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		0 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrDateTimeWidget
#
# Registers the datefield, dateentry, timefield, or timeentry widget from the
# Iwidgets package, with or without the -clicks option for its get subcommand,
# for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrDateTimeWidget {widgetType args} {
    if {![regexp {^(datefield|dateentry|timefield|timeentry)$} $widgetType]} {
	return -code error \
	       "bad widget type \"$widgetType\": must be\
		datefield, dateentry, timefield, or timeentry"
    }

    switch [llength $args] {
	0 {
	    set useClicks 0
	    set name $widgetType
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-seconds"] == 0} {
		set useClicks 1
		set name $widgetType
	    } else {
		set useClicks 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-seconds"] != 0} {
		return -code error "bad option \"$arg0\": must be -seconds"
	    }

	    set useClicks 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addIncrDateTimeWidget\
		    datefield|dateentry|timefield|timeentry ?-seconds? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::$widgetType %W" \
	$name-putValueCmd	"%W show %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W show %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useReqWidth	1 \
	$name-usePadX		[string match "*entry" $widgetType] \
	$name-useFormat		1 \
	$name-isEntryLike	1 \
	$name-reservedKeys	{Left Right Up Down} \
    ]
    if {$useClicks} {
	lappend editWin($name-getValueCmd) -clicks
	set editWin($name-useFormat) 0
    }
    if {[string match "date*" $widgetType]} {
	set editWin($name-focusWin) {[%W component date]}
    } else {
	set editWin($name-focusWin) {[%W component time]}
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrSpinner
#
# Registers the spinner widget from the Iwidgets package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrSpinner {{name spinner}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::spinner %W -width 0" \
	$name-putValueCmd	"%W clear; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrSpinint
#
# Registers the spinint widget from the Iwidgets package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrSpinint {{name spinint}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"iwidgets::spinint %W -width 0" \
	$name-putValueCmd	"%W clear; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIncrCombobox
#
# Registers the combobox widget from the Iwidgets package for interactive cell
# editing.
#------------------------------------------------------------------------------
proc tablelist::addIncrCombobox {{name combobox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"createIncrCombobox %W" \
	$name-putValueCmd	"%W clear entry; %W insert entry 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W clear entry; %W insert entry 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	{eval [list %W insert list end] %L} \
	$name-getListCmd	"%W component list get 0 end" \
	$name-selectCmd		"%W selection set %I" \
	$name-invokeCmd		"%W invoke" \
	$name-fontOpt		-textfont \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		{[%W component entry]} \
	$name-reservedKeys	{Left Right Up Down Control-p Control-n} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addCtext
#
# Registers the ctext widget for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addCtext {{name ctext}} {
    checkEditWinName $name

    variable editWin
    variable pu
    array set editWin [list \
	$name-creationCmd	"ctext %W -padx 2 -pady 2 -wrap none" \
	$name-putValueCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	$name-getValueCmd	"%W get 1.0 end-1$pu" \
	$name-putTextCmd	"%W delete 1.0 end; %W insert 1.0 %T" \
	$name-getTextCmd	"%W get 1.0 end-1$pu" \
	$name-putListCmd	"" \
	$name-getListCmd	"" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		0 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.t \
	$name-reservedKeys	{Left Right Up Down Prior Next
				 Control-Home Control-End Meta-b Meta-f
				 Control-p Control-n Meta-less Meta-greater} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addOakleyCombobox
#
# Registers Bryan Oakley's combobox widget for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addOakleyCombobox {{name combobox}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"createOakleyCombobox %W" \
	$name-putValueCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getValueCmd	"%W get" \
	$name-putTextCmd	"%W delete 0 end; %W insert 0 %T" \
	$name-getTextCmd	"%W get" \
	$name-putListCmd	{eval [list %W list insert end] %L} \
	$name-getListCmd	"%W list get 0 end" \
	$name-selectCmd		"%W select %I" \
	$name-invokeCmd		"%W open" \
	$name-fontOpt		-font \
	$name-useFormat		1 \
	$name-useReqWidth	0 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		%W.entry \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    #
    # Patch the ::combobox::UpdateVisualAttributes procedure to make sure it
    # won't change the background and trough colors of the vertical scrollbar
    #
    catch {combobox::combobox}	;# enforces the evaluation of "combobox.tcl"
    if {[catch {rename ::combobox::UpdateVisualAttributes \
		::combobox::_UpdateVisualAttributes}] == 0} {
	proc ::combobox::UpdateVisualAttributes w {
	    set vsbBackground [$w.top.vsb cget -background]
	    set vsbTroughColor [$w.top.vsb cget -troughcolor]

	    ::combobox::_UpdateVisualAttributes $w

	    $w.top.vsb configure -background $vsbBackground
	    $w.top.vsb configure -troughcolor $vsbTroughColor
	}
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addDateMentry
#
# Registers the widget created by the mentry::dateMentry command from the
# Mentry package, with a given format and separator and with or without the
# "-gmt 1" option for the mentry::putClockVal and mentry::getClockVal commands,
# for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addDateMentry {fmt sep args} {
    #
    # Parse the fmt argument
    #
    if {![regexp {^([dmyY])([dmyY])([dmyY])$} $fmt dummy \
		 fields(0) fields(1) fields(2)]} {
	return -code error \
	       "bad format \"$fmt\": must be a string of length 3,\
		consisting of the letters d, m, and y or Y"
    }

    #
    # Check whether all the three date components are represented in fmt
    #
    for {set n 0} {$n < 3} {incr n} {
	set lfields($n) [string tolower $fields($n)]
    }
    if {[string compare $lfields(0) $lfields(1)] == 0 ||
	[string compare $lfields(0) $lfields(2)] == 0 ||
	[string compare $lfields(1) $lfields(2)] == 0} {
	return -code error \
	       "bad format \"$fmt\": must have unique components for the\
		day, month, and year"
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useGMT 0
	    set name dateMentry
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-gmt"] == 0} {
		set useGMT 1
		set name dateMentry
	    } else {
		set useGMT 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-gmt"] != 0} {
		return -code error "bad option \"$arg0\": must be -gmt"
	    }

	    set useGMT 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addDateMentry format separator ?-gmt? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::dateMentry %W $fmt $sep] \
	$name-putValueCmd	"mentry::putClockVal %T %W -gmt $useGMT" \
	$name-getValueCmd	"mentry::getClockVal %W -gmt $useGMT" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addTimeMentry
#
# Registers the widget created by the mentry::timeMentry command from the
# Mentry package, with a given format and separator and with or without the
# "-gmt 1" option for the mentry::putClockVal and mentry::getClockVal commands,
# for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addTimeMentry {fmt sep args} {
    #
    # Parse the fmt argument
    #
    if {![regexp {^(H|I)(M)(S?)$} $fmt dummy fields(0) fields(1) fields(2)]} {
	return -code error \
	       "bad format \"$fmt\": must be a string of length 2 or 3\
		starting with H or I, followed by M and optionally by S"
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useGMT 0
	    set name timeMentry
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-gmt"] == 0} {
		set useGMT 1
		set name timeMentry
	    } else {
		set useGMT 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-gmt"] != 0} {
		return -code error "bad option \"$arg0\": must be -gmt"
	    }

	    set useGMT 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addTimeMentry format separator ?-gmt? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::timeMentry %W $fmt $sep] \
	$name-putValueCmd	"mentry::putClockVal %T %W -gmt $useGMT" \
	$name-getValueCmd	"mentry::getClockVal %W -gmt $useGMT" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addDateTimeMentry
#
# Registers the widget created by the mentry::dateTimeMentry command from the
# Mentry package, with a given format and given separators and with or without
# the "-gmt 1" option for the mentry::putClockVal and mentry::getClockVal
# commands, for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addDateTimeMentry {fmt dateSep timeSep args} {
    #
    # Parse the fmt argument
    #
    if {![regexp {^([dmyY])([dmyY])([dmyY])(H|I)(M)(S?)$} $fmt dummy \
		 fields(0) fields(1) fields(2) fields(3) fields(4) fields(5)]} {
	return -code error \
	       "bad format \"$fmt\": must be a string of length 5 or 6,\
		with the first 3 characters consisting of the letters d, m,\
		and y or Y, followed by H or I, then M, and optionally by S"
    }

    #
    # Check whether all the three date components are represented in fmt
    #
    for {set n 0} {$n < 3} {incr n} {
	set lfields($n) [string tolower $fields($n)]
    }
    if {[string compare $lfields(0) $lfields(1)] == 0 ||
	[string compare $lfields(0) $lfields(2)] == 0 ||
	[string compare $lfields(1) $lfields(2)] == 0} {
	return -code error \
	       "bad format \"$fmt\": must have unique components for the\
		day, month, and year"
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useGMT 0
	    set name dateTimeMentry
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-gmt"] == 0} {
		set useGMT 1
		set name dateTimeMentry
	    } else {
		set useGMT 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-gmt"] != 0} {
		return -code error "bad option \"$arg0\": must be -gmt"
	    }

	    set useGMT 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addDateTimeMentry format dateSeparator\
				  timeSeparator ?-gmt? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::dateTimeMentry %W $fmt \
				      $dateSep $timeSep] \
	$name-putValueCmd	"mentry::putClockVal %T %W -gmt $useGMT" \
	$name-getValueCmd	"mentry::getClockVal %W -gmt $useGMT" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addFixedPointMentry
#
# Registers the widget created by the mentry::fixedPointMentry command from the
# Mentry package, with a given number of characters before and a given number
# of digits after the decimal point, with or without the -comma option, for
# interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addFixedPointMentry {cnt1 cnt2 args} {
    #
    # Check the arguments cnt1 and cnt2
    #
    if {![isInteger $cnt1] || $cnt1 <= 0} {
	return -code error "expected positive integer but got \"$cnt1\""
    }
    if {![isInteger $cnt2] || $cnt2 <= 0} {
	return -code error "expected positive integer but got \"$cnt2\""
    }

    #
    # Parse the remaining arguments (if any)
    #
    switch [llength $args] {
	0 {
	    set useComma 0
	    set name fixedPointMentry_$cnt1.$cnt2
	}

	1 {
	    set arg [lindex $args 0]
	    if {[string compare $arg "-comma"] == 0} {
		set useComma 1
		set name fixedPointMentry_$cnt1,$cnt2
	    } else {
		set useComma 0
		set name $arg
	    }
	}

	2 {
	    set arg0 [lindex $args 0]
	    if {[string compare $arg0 "-comma"] != 0} {
		return -code error "bad option \"$arg0\": must be -comma"
	    }

	    set useComma 1
	    set name [lindex $args 1]
	}

	default {
	    mwutil::wrongNumArgs "addFixedPointMentry count1 count2\
				  ?-comma? ?name?"
	}
    }
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	[list mentry::fixedPointMentry %W $cnt1 $cnt2] \
	$name-putValueCmd	"mentry::putReal %T %W" \
	$name-getValueCmd	"mentry::getReal %W" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right} \
    ]
    if {$useComma} {
	lappend editWin($name-creationCmd) -comma
    }

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIPAddrMentry
#
# Registers the widget created by the mentry::ipAddrMentry command from the
# Mentry package for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIPAddrMentry {{name ipAddrMentry}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"mentry::ipAddrMentry %W" \
	$name-putValueCmd	"mentry::putIPAddr %T %W" \
	$name-getValueCmd	"mentry::getIPAddr %W" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#------------------------------------------------------------------------------
# tablelist::addIPv6AddrMentry
#
# Registers the widget created by the mentry::ipv6AddrMentry command from the
# Mentry package for interactive cell editing.
#------------------------------------------------------------------------------
proc tablelist::addIPv6AddrMentry {{name ipv6AddrMentry}} {
    checkEditWinName $name

    variable editWin
    array set editWin [list \
	$name-creationCmd	"mentry::ipv6AddrMentry %W" \
	$name-putValueCmd	"mentry::putIPv6Addr %T %W" \
	$name-getValueCmd	"mentry::getIPv6Addr %W" \
	$name-putTextCmd	"" \
	$name-getTextCmd	"%W getstring" \
	$name-putListCmd	{eval [list %W put 0] %L} \
	$name-getListCmd	"%W getlist" \
	$name-selectCmd		"" \
	$name-invokeCmd		"" \
	$name-fontOpt		-font \
	$name-useFormat		0 \
	$name-useReqWidth	1 \
	$name-usePadX		1 \
	$name-isEntryLike	1 \
	$name-focusWin		"" \
	$name-reservedKeys	{Left Right Up Down Prior Next} \
    ]

    return $name
}

#
# Private procedures implementing the interactive cell editing
# ============================================================
#

#------------------------------------------------------------------------------
# tablelist::checkEditWinName
#
# Generates an error if the given edit window name is one of "entry", "text",
# "spinbox", "checkbutton", "menubutton", "ttk::entry", "ttk::spinbox",
# "ttk::combobox", "ttk::checkbutton", or "ttk::menubutton".
#------------------------------------------------------------------------------
proc tablelist::checkEditWinName name {
    if {[regexp {^(entry|text|spinbox|checkbutton|menubutton)$} $name]} {
	return -code error \
	       "edit window name \"$name\" is reserved for Tk $name widgets"
    }

    if {[regexp {^(::)?ttk::(entry|spinbox|combobox|checkbutton|menubutton)$} \
	 $name]} {
	return -code error \
	       "edit window name \"$name\" is reserved for tile $name widgets"
    }
}

#------------------------------------------------------------------------------
# tablelist::createCheckbutton
#
# Creates a checkbutton widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createCheckbutton {w args} {
    makeCheckbutton $w

    foreach {opt val} $args {
	switch -- $opt {
	    -state  { $w configure $opt $val }
	    default {}
	}
    }

    set win [getTablelistPath $w]
    $w configure -variable ::tablelist::ns${win}::data(editText)
}

#------------------------------------------------------------------------------
# tablelist::createMenubutton
#
# Creates a menubutton widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createMenubutton {w args} {
    set win [getTablelistPath $w]
    menubutton $w -anchor w -indicatoron 1 -justify left -padx 2 -pady 2 \
	-relief raised -textvariable ::tablelist::ns${win}::data(editText)

    foreach {opt val} $args {
	$w configure $opt $val
    }

    variable winSys
    upvar ::tablelist::ns${win}::data data
    if {[string compare $winSys "aqua"] == 0} {
	catch {
	    set data(useCustomMDEFSav) $::tk::mac::useCustomMDEF
	    set ::tk::mac::useCustomMDEF 1
	}
    }

    set menu $w.menu
    menu $menu -tearoff 0 -postcommand [list tablelist::postMenuCmd $w]
    foreach event {<Map> <Unmap>} {
	bind $menu $event {
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }
    if {[string compare $winSys "x11"] == 0} {
	$menu configure -background $data(-background) \
			-foreground $data(-foreground) \
			-activebackground $data(-selectbackground) \
			-activeforeground $data(-selectforeground) \
			-activeborderwidth $data(-selectborderwidth)
    }

    $w configure -menu $menu
}

#------------------------------------------------------------------------------
# tablelist::postMenuCmd
#
# Activates the radiobutton entry of the menu associated with the menubutton
# widget having the given path name whose -value option was set to the
# menubutton's text.
#------------------------------------------------------------------------------
proc tablelist::postMenuCmd w {
    set menu [$w cget -menu]
    variable winSys
    if {[string compare $winSys "x11"] == 0} {
	set last [$menu index last]
	if {[string compare $last "none"] != 0} {
	    set text [$w cget -text]
	    for {set idx 0} {$idx <= $last} {incr idx} {
		if {[string compare [$menu type $idx] "radiobutton"] == 0 &&
		    [string compare [$menu entrycget $idx -value] $text] == 0} {
		    $menu activate $idx
		}
	    }
	}
    } else {
	if {[catch {set ::tk::Priv(postedMb) ""}] != 0} {
	    set ::tkPriv(postedMb) ""
	}

	if {[string compare [winfo class $w] "TMenubutton"] == 0} {
	    if {[catch {set ::tk::Priv(popup) $menu}] != 0} {
		set ::tkPriv(popup) $menu
	    }
	}

	if {[string compare $winSys "aqua"] == 0} {
	    set win [getTablelistPath $w]
	    upvar ::tablelist::ns${win}::data data
	    if {[string compare [$data(body) cget -cursor] $data(-cursor)]
		!= 0} {
		$data(body) configure -cursor $data(-cursor)
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileEntry
#
# Creates a tile entry widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileEntry {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    #
    # The style of the tile entry widget should have -borderwidth
    # 2 and -padding 1.  For those themes that don't honor the
    # -borderwidth 2 setting, set the padding to another value.
    #
    set win [getTablelistPath $w]
    switch -- [getCurrentTheme] {
	aqua {
	    set padding {0 0 0 -1}
	}

	tileqt {
	    set padding 3
	}

	xpnative {
	    switch [winfo rgb . SystemHighlight] {
		"12593 27242 50629" -
		"37779 41120 28784" -
		"45746 46260 49087" -
		"13107 39321 65535"	{ set padding 2 }
		default			{ set padding 1 }
	    }
	}

	default {
	    set padding 1
	}
    }
    styleConfig Tablelist.TEntry -borderwidth 2 -highlightthickness 0 \
				 -padding $padding

    ttk::entry $w -style Tablelist.TEntry

    foreach {opt val} $args {
	$w configure $opt $val
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileSpinbox
#
# Creates a tile spinbox widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileSpinbox {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.8.3
    }
    createTileAliases 

    #
    # The style of the tile entry widget should have -borderwidth
    # 2 and -padding 1.  For those themes that don't honor the
    # -borderwidth 2 setting, set the padding to another value.
    #
    set win [getTablelistPath $w]
    switch -- [getCurrentTheme] {
	aqua {
	    set padding {0 0 0 -1}
	}

	tileqt {
	    set padding 3
	}

	vista {
	    switch [winfo rgb . SystemHighlight] {
		"13107 39321 65535"	{ set padding 0 }
		default			{ set padding 1 }
	    }
	}

	xpnative {
	    switch [winfo rgb . SystemHighlight] {
		"12593 27242 50629" -
		"37779 41120 28784" -
		"45746 46260 49087" -
		"13107 39321 65535"	{ set padding 2 }
		default			{ set padding 1 }
	    }
	}

	default {
	    set padding 1
	}
    }
    styleConfig Tablelist.TSpinbox -borderwidth 2 -highlightthickness 0 \
				   -padding $padding

    ttk::spinbox $w -style Tablelist.TSpinbox

    foreach {opt val} $args {
	$w configure $opt $val
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileCombobox
#
# Creates a tile combobox widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileCombobox {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    set win [getTablelistPath $w]
    if {[string compare [getCurrentTheme] "aqua"] == 0} {
	styleConfig Tablelist.TCombobox -borderwidth 2 -padding {0 0 0 -1}
    } else {
	styleConfig Tablelist.TCombobox -borderwidth 2 -padding 1
    }

    ttk::combobox $w -style Tablelist.TCombobox

    foreach {opt val} $args {
	$w configure $opt $val
    }
}

#------------------------------------------------------------------------------
# tablelist::createTileCheckbutton
#
# Creates a tile checkbutton widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileCheckbutton {w args} {
    makeTileCheckbutton $w

    foreach {opt val} $args {
	switch -- $opt {
	    -state  { $w configure $opt $val }
	    default {}
	}
    }

    set win [getTablelistPath $w]
    $w configure -variable ::tablelist::ns${win}::data(editText)
}

#------------------------------------------------------------------------------
# tablelist::createTileMenubutton
#
# Creates a tile menubutton widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createTileMenubutton {w args} {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    styleConfig Tablelist.TMenubutton -anchor w -justify left -padding 1 \
				      -relief raised

    set win [getTablelistPath $w]
    ttk::menubutton $w -style Tablelist.TMenubutton \
		       -textvariable ::tablelist::ns${win}::data(editText)

    foreach {opt val} $args {
	switch -- $opt {
	    -state  { $w configure $opt $val }
	    default {}
	}
    }

    variable winSys
    upvar ::tablelist::ns${win}::data data
    if {[string compare $winSys "aqua"] == 0} {
	catch {
	    set data(useCustomMDEFSav) $::tk::mac::useCustomMDEF
	    set ::tk::mac::useCustomMDEF 1
	}
    }

    set menu $w.menu
    menu $menu -tearoff 0 -postcommand [list tablelist::postMenuCmd $w]
    if {[string compare $winSys "x11"] == 0} {
	$menu configure -background $data(-background) \
			-foreground $data(-foreground) \
			-activebackground $data(-selectbackground) \
			-activeforeground $data(-selectforeground) \
			-activeborderwidth $data(-selectborderwidth)
    }

    $w configure -menu $menu
}

#------------------------------------------------------------------------------
# tablelist::createBWidgetComboBox
#
# Creates a BWidget ComboBox widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createBWidgetComboBox {w args} {
    eval [list ComboBox $w -editable 1 -width 0] $args
    ComboBox::_create_popup $w

    foreach event {<Map> <Unmap>} {
	bind $w.shell.listb $event {
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createIncrCombobox
#
# Creates an [incr Widgets] combobox of the given path name for interactive
# cell editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createIncrCombobox {w args} {
    eval [list iwidgets::combobox $w -dropdown 1 -editable 1 -width 0] $args

    foreach event {<Map> <Unmap>} {
	bind [$w component list] $event {+
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }

    #
    # Make sure that the entry component will receive the input focus
    # whenever the list component (a scrolledlistbox widget) gets unmapped
    #
    bind [$w component list] <Unmap> +[list focus [$w component entry]]
}

#------------------------------------------------------------------------------
# tablelist::createOakleyCombobox
#
# Creates an Oakley combobox widget of the given path name for interactive cell
# editing in a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::createOakleyCombobox {w args} {
    eval [list combobox::combobox $w -editable 1 -width 0] $args

    foreach event {<Map> <Unmap>} {
	bind $w.top.list $event {
	    tablelist::invokeMotionHandler [tablelist::getTablelistPath %W]
	}
    }

    #
    # Repack the widget's components, to make sure that the
    # button will remain visible when shrinking the combobox.
    # This patch is needed for combobox versions earlier than 2.3.
    #
    pack forget $w.entry $w.button
    pack $w.button -side right -fill y    -expand 0
    pack $w.entry  -side left  -fill both -expand 1
}

#------------------------------------------------------------------------------
# tablelist::doEditCell
#
# Processes the tablelist editcell subcommand.  cmd may be an empty string,
# "condChangeSelection", or "changeSelection".  charPos stands for the
# character position component of the index in the body text widget of the
# character underneath the mouse cursor if this command was invoked by clicking
# mouse button 1 in the body of the tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::doEditCell {win row col restore {cmd ""} {charPos -1}} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || ![isRowViewable $win $row] || $data($col-hide) ||
	![isCellEditable $win $row $col]} {
	return ""
    }
    if {$data(editRow) == $row && $data(editCol) == $col} {
	return ""
    }
    if {$data(editRow) >= 0 && ![doFinishEditing $win]} {
	return ""
    }
    set item [lindex $data(itemList) $row]
    set key [lindex $item end]
    getIndentData $win $key $col indentWidth
    set pixels [colWidth $win $col -stretched]
    if {$indentWidth >= $pixels} {
	return ""
    }

    #
    # Create a frame to be embedded into the tablelist's body, together with
    # a child of column/cell-specific type; replace the binding tag Frame with
    # $data(editwinTag) and TablelistEdit in the frame's list of binding tags
    #
    seeCell $win $row $col
    set netRowHeight [lindex [bboxSubCmd $win $row] 3]
    set frameHeight [expr {$netRowHeight + 6}]	;# because of the -pady -3 below
    set f $data(bodyFrm)
    tk::frame $f -borderwidth 0 -container 0 -height $frameHeight \
		 -highlightthickness 0 -relief flat -takefocus 0
    catch {$f configure -padx 0 -pady 0}
    bindtags $f [lreplace [bindtags $f] 1 1 $data(editwinTag) TablelistEdit]
    set name [getEditWindow $win $row $col]
    variable editWin
    set creationCmd [strMap {"%W" "$w"} $editWin($name-creationCmd)]
    append creationCmd { $editWin($name-fontOpt) [getCellFont $win $key $col]} \
		       { -state normal}
    set w $data(bodyFrmEd)
    if {[catch {eval $creationCmd} result] != 0} {
	destroy $f
	return -code error $result
    }
    catch {$w configure -highlightthickness 0}
    clearTakefocusOpt $w
    set class [winfo class $w]
    set isCheckbtn [string match "*Checkbutton" $class]
    set isMenubtn [string match "*Menubutton" $class]
    set isText [expr {[string compare $class "Text"] == 0 ||
		      [string compare $class "Ctext"] == 0}]
    set isMentry [expr {[string compare $class "Mentry"] == 0}]
    if {!$isCheckbtn && !$isMenubtn} {
	catch {$w configure -relief ridge}
	catch {$w configure -borderwidth 2}
    }
    if {$isText && $data($col-wrap) && $::tk_version >= 8.5} {
	$w configure -wrap word
    }
    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
    if {!$isText && !$isMentry} {
	catch {$w configure -justify $alignment}
    }

    #
    # Define some bindings for the above frame
    #
    bind $f <Enter> {
	set tablelist::W [tablelist::getTablelistPath %W]
	set tablelist::ns${tablelist::W}::data(inEditWin) 1
	tablelist::invokeMotionHandler $tablelist::W
    }
    bind $f <Leave> {
	set tablelist::W [tablelist::getTablelistPath %W]
	set tablelist::ns${tablelist::W}::data(inEditWin) 0
	set tablelist::ns${tablelist::W}::data(prevCell) -1,-1
	tablelist::invokeMotionHandler $tablelist::W
    }
    bind $f <Destroy> {
	set tablelist::W [tablelist::getTablelistPath %W]
	array set tablelist::ns${tablelist::W}::data \
	      {editKey ""  editRow -1  editCol -1  inEditWin 0  prevCell -1,-1}
	if {[catch {tk::CancelRepeat}] != 0} {
	    tkCancelRepeat 
	}
	if {[catch {ttk::CancelRepeat}] != 0} {
	    catch {tile::CancelRepeat}
	}
	tablelist::invokeMotionHandler $tablelist::W
    }

    #
    # Replace the cell's content between the two tabs with the above frame
    #
    array set data [list editKey $key editRow $row editCol $col]
    set b $data(body)
    findTabs $win $b [expr {$row + 1}] $col $col tabIdx1 tabIdx2
    getIndentData $win $data(editKey) $data(editCol) indentWidth
    variable pu
    if {$indentWidth == 0} {
	set textIdx [$b index $tabIdx1+1$pu]
    } else {
	$b mark set editIndentMark [$b index $tabIdx1+1$pu]
	set textIdx [$b index $tabIdx1+2$pu]
    }
    if {$isCheckbtn} {
	set editIdx $textIdx
	$b delete $editIdx $tabIdx2
    } else {
	getAuxData $win $data(editKey) $data(editCol) auxType auxWidth
	if {$auxType == 0 || $auxType > 1} {			;# no image
	    set editIdx $textIdx
	    $b delete $editIdx $tabIdx2
	} elseif {[string compare $alignment "right"] == 0} {
	    $b mark set editAuxMark $tabIdx2-1$pu
	    set editIdx $textIdx
	    $b delete $editIdx $tabIdx2-1$pu
	} else {
	    $b mark set editAuxMark $textIdx
	    set editIdx [$b index $textIdx+1$pu]
	    $b delete $editIdx $tabIdx2
	}
    }
    $b window create $editIdx -padx -3 -pady -3 -window $f
    $b mark set editMark $editIdx

    #
    # Insert the binding tags $data(editwinTag) and TablelistEdit
    # into the list of binding tags of some components
    # of w, just before the respective path names
    #
    if {$isMentry} {
	set compList [$w entries]
    } else {
	set comp [subst [strMap {"%W" "$w"} $editWin($name-focusWin)]]
	set compList [list $comp]
	set data(editFocus) $comp
    }
    foreach comp $compList {
	set bindTags [bindtags $comp]
	set idx [lsearch -exact $bindTags $comp]
	bindtags $comp [linsert $bindTags $idx $data(editwinTag) TablelistEdit]
    }

    #
    # Restore or initialize some of the edit window's data
    #
    if {$restore} {
	restoreEditData $win
    } else {
	#
	# Put the cell's content to the edit window
	#
	set data(canceled) 0
	set data(invoked) 0
	set text [lindex $item $col]
	if {$editWin($name-useFormat) && [lindex $data(fmtCmdFlagList) $col]} {
	    set text [formatElem $win $key $row $col $text]
	}
	catch {
	    eval [strMap {"%W" "$w"  "%T" "$text"} $editWin($name-putValueCmd)]
	}

	#
	# Save the edit window's text
	#
	set data(origEditText) \
	    [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]

	if {[string length $data(-editstartcommand)] != 0} {
	    set text [uplevel #0 $data(-editstartcommand) \
		      [list $win $row $col $text]]
	    if {[destroyed $win]} {
		return ""
	    }

	    variable winSys
	    if {[string compare $winSys "aqua"] == 0} {
		catch {set ::tk::mac::useCustomMDEF $data(useCustomMDEFSav)}
	    }

	    if {$data(canceled)} {
		return ""
	    }

	    catch {
		eval [strMap {"%W" "$w"  "%T" "$text"} \
		      $editWin($name-putValueCmd)]
	    }
	}

	if {$isMenubtn} {
	    set menu [$w cget -menu]
	    set last [$menu index last]
	    if {[string compare $last "none"] != 0} {
		set varName [$w cget -textvariable]
		for {set idx 0} {$idx <= $last} {incr idx} {
		    if {[string compare [$menu type $idx] "radiobutton"] == 0} {
			$menu entryconfigure $idx -variable $varName
		    }
		}
	    }
	}

	#
	# Save the edit window's text again
	#
	set data(origEditText) \
	    [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]
	set data(rejected) 0

	if {[string length $editWin($name-getListCmd)] != 0 &&
	    [string length $editWin($name-selectCmd)] != 0} {
	    #
	    # Select the edit window's item corresponding to text
	    #
	    set itemList [eval [strMap {"%W" "$w"} $editWin($name-getListCmd)]]
	    if {[set idx [lsearch -exact $itemList $text]] >= 0} {
		eval [strMap {"%W" "$w"  "%I" "$idx"} $editWin($name-selectCmd)]
	    }
	}

	#
	# Evaluate the optional command passed as argument
	#
	if {[string length $cmd] != 0} {
	    eval [list $cmd $win $row $col]
	}

	#
	# Set the focus and the insertion cursor
	#
	if {$charPos >= 0} {
	    if {$isText || !$editWin($name-isEntryLike)} {
		focus $w
	    } else {
		set hasAuxObject [expr {
		    [info exists data($key,$col-image)] ||
		    [info exists data($key,$col-window)]}]
		if {[string compare $alignment "right"] == 0} {
		    scan $tabIdx2 "%d.%d" line tabCharIdx2
		    if {$isMentry} {
			set len [string length [$w getstring]]
		    } else {
			set len [$comp index end]
		    }
		    set number [expr {$len - $tabCharIdx2 + $charPos}]
		    if {$hasAuxObject} {
			incr number 2
		    }
		} else {
		    scan $tabIdx1 "%d.%d" line tabCharIdx1
		    set number [expr {$charPos - $tabCharIdx1 - 1}]
		    if {$hasAuxObject} {
			incr number -2
		    }
		}
		if {$isMentry} {
		    setMentryCursor $w $number
		} else {
		    focus $comp
		    $comp icursor $number
		}
	    }
	} else {
	    if {$isText || $isMentry || !$editWin($name-isEntryLike)} {
		focus $w
	    } else {
		focus $comp
		$comp icursor end
		$comp selection range 0 end
	    }
	}
    }

    if {$data(-autofinishediting)} {
	#
	# Make sure that selecting a combobox or menu
	# entry will automatically finish the editing
	#
	switch $class {
	    TCombobox {
		bind $w <<ComboboxSelected>> \
		    {+ [tablelist::getTablelistPath %W] finishediting}
	    }

	    ComboBox {					;# BWidget
		set cmd [$w cget -modifycmd]
		$w configure -modifycmd [format {
		    eval [list %s]
		    after 0 [list %s finishediting]
		} $cmd $win]
	    }

	    Combobox {					;# IWidgets or Oakley
		if {[catch {$w cget -selectioncommand} cmd] == 0} {  ;# IWidgets
		    set cmd [$w cget -selectioncommand]
		    $w configure -selectioncommand [format {
			eval [list %s]
			after 0 [list %s finishediting]
		    } $cmd $win]
		} elseif {[catch {$w cget -command} cmd] == 0} {     ;# Oakley
		    if {[string length $cmd] == 0} {
			proc ::tablelist::comboboxCmd {w val} [format {
			    after 0 [list %s finishediting]
			} $win]
		    } else {
			proc ::tablelist::comboboxCmd {w val} [format {
			    eval [list %s $w $val]
			    after 0 [list %s finishediting]
			} $cmd $win]
		    }
		    $w configure -command ::tablelist::comboboxCmd
		}
	    }

	    Menubutton -
	    TMenubutton {
		set menu [$w cget -menu]
		set last [$menu index last]
		if {[string compare $last "none"] != 0} {
		    for {set idx 0} {$idx <= $last} {incr idx} {
			if {[regexp {^(command|checkbutton|radiobutton)$} \
			     [$menu type $idx]]} {
			    set cmd [$menu entrycget $idx -command]
			    $menu entryconfigure $idx -command [format {
				eval [list %s]
				after 0 [list %s finishediting]
			    } $cmd $win]
			}
		    }
		}
	    }
	}
    }

    #
    # Adjust the frame's height
    #
    if {$isText} {
	if {[string compare [$w cget -wrap] "none"] == 0 ||
	    $::tk_version < 8.5} {
	    set numLines [expr {int([$w index end-1$pu])}]
	    $w configure -height $numLines
	    update idletasks				;# needed for ctext
	    if {[destroyed $win]} {
		return ""
	    }
	    $f configure -height [winfo reqheight $w]
	} else {
	    bind $w <Configure> {
		%W configure -height [%W count -displaylines 1.0 end]
		[winfo parent %W] configure -height [winfo reqheight %W]
	    }
	}
	if {[info exists ::wcb::version]} {
	    wcb::cbappend $w after insert tablelist::adjustTextHeight
	    wcb::cbappend $w after delete tablelist::adjustTextHeight
	}
    } elseif {!$isCheckbtn} {
	update idletasks
	if {[destroyed $win]} {
	    return ""
	}
	$f configure -height [winfo reqheight $w]
    }

    #
    # Adjust the frame's width and paddings
    #
    if {!$isCheckbtn} {
	place $w -relwidth 1.0 -relheight 1.0
	adjustEditWindow $win $pixels
	update idletasks
	if {[destroyed $win]} {
	    return ""
	}
    }

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::doCancelEditing
#
# Processes the tablelist cancelediting subcommand.  Aborts the interactive
# cell editing and restores the cell's content after destroying the edit
# window.
#------------------------------------------------------------------------------
proc tablelist::doCancelEditing win {
    upvar ::tablelist::ns${win}::data data
    if {[set row $data(editRow)] < 0} {
	return ""
    }
    set col $data(editCol)

    #
    # Invoke the command specified by the -editendcommand option if needed
    #
    set data(canceled) 1
    if {$data(-forceeditendcommand) &&
	[string length $data(-editendcommand)] != 0} {
	uplevel #0 $data(-editendcommand) \
		[list $win $row $col $data(origEditText)]
	if {[destroyed $win]} {
	    return ""
	}
    }

    if {[winfo exists $data(bodyFrm)]} {
	destroy $data(bodyFrm)
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	foreach opt {-window -image} {
	    if {[info exists data($key,$col$opt)]} {
		doCellConfig $row $col $win $opt $data($key,$col$opt)
		break
	    }
	}
	doCellConfig $row $col $win -text [lindex $item $col]
    }

    focus $data(body)

    set userData [list $row $col]
    genVirtualEvent $win <<TablelistCellRestored>> $userData

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::doFinishEditing
#
# Processes the tablelist finishediting subcommand.  Invokes the command
# specified by the -editendcommand option if needed, and updates the element
# just edited after destroying the edit window if the latter's content was not
# rejected.  Returns 1 on normal termination and 0 otherwise.
#------------------------------------------------------------------------------
proc tablelist::doFinishEditing win {
    upvar ::tablelist::ns${win}::data data
    if {[set row $data(editRow)] < 0} {
	return 1
    }
    set col $data(editCol)

    #
    # Get the edit window's text, and invoke the command
    # specified by the -editendcommand option if needed
    #
    set w $data(bodyFrmEd)
    set name [getEditWindow $win $row $col]
    variable editWin
    set text [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]
    set item [lindex $data(itemList) $row]
    if {!$data(-forceeditendcommand) &&
	[string compare $text $data(origEditText)] == 0} {
	set text [lindex $item $col]
    } else {
	if {[catch {
	    eval [strMap {"%W" "$w"} $editWin($name-getValueCmd)]
	} text] != 0} {
	    set data(rejected) 1
	}
	if {[string length $data(-editendcommand)] != 0} {
	    set text \
		[uplevel #0 $data(-editendcommand) [list $win $row $col $text]]
	    if {[destroyed $win]} {
		return 0
	    }
	}
    }

    #
    # Check whether the input was rejected (by the above "set data(rejected) 1"
    # statement or within the command specified by the -editendcommand option)
    #
    if {$data(rejected)} {
	if {[winfo exists $data(bodyFrm)]} {
	    seeCell $win $row $col
	    if {[string compare [winfo class $w] "Mentry"] != 0} {
		focus $data(editFocus)
	    }
	} else {
	    focus $data(body)
	}

	set data(rejected) 0
	set result 0
    } else {
	if {[winfo exists $data(bodyFrm)]} {
	    destroy $data(bodyFrm)
	    set key [lindex $item end]
	    foreach opt {-window -image} {
		if {[info exists data($key,$col$opt)]} {
		    doCellConfig $row $col $win $opt $data($key,$col$opt)
		    break
		}
	    }
	    doCellConfig $row $col $win -text $text
	    set result 1
	} else {
	    set result 0
	}

	focus $data(body)

	set userData [list $row $col]
	genVirtualEvent $win <<TablelistCellUpdated>> $userData
    }

    updateViewWhenIdle $win
    return $result
}

#------------------------------------------------------------------------------
# tablelist::clearTakefocusOpt
#
# Sets the -takefocus option of all members of the widget hierarchy starting
# with w to 0.
#------------------------------------------------------------------------------
proc tablelist::clearTakefocusOpt w {
    catch {$w configure -takefocus 0}
    foreach c [winfo children $w] {
	clearTakefocusOpt $c
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustTextHeight
#
# This procedure is an after-insert and after-delete callback asociated with a
# (c)text widget used for interactive cell editing.  It sets the height of the
# edit window to the number of lines currently contained in it.
#------------------------------------------------------------------------------
proc tablelist::adjustTextHeight {w args} {
    if {$::tk_version >= 8.5} {
	#
	# Count the display lines (taking into account the line wraps)
	#
	set numLines [$w count -displaylines 1.0 end]
    } else {
	#
	# We can only count the logical lines (irrespective of wrapping)
	#
	variable pu
	set numLines [expr {int([$w index end-1$pu])}]
    }
    $w configure -height $numLines

    set path [wcb::pathname $w]
    [winfo parent $path] configure -height [winfo reqheight $path]
}

#------------------------------------------------------------------------------
# tablelist::setMentryCursor
#
# Sets the focus to the entry child of the mentry widget w that contains the
# global character position specified by number, and sets the insertion cursor
# in that entry to the relative character position corresponding to number.  If
# that entry is not enabled then the procedure sets the focus to the last
# enabled entry child preceding the found one and sets the insertion cursor to
# its end.
#------------------------------------------------------------------------------
proc tablelist::setMentryCursor {w number} {
    #
    # Find the entry child containing the given character
    # position; if the latter is contained in a label child
    # then take the entry immediately preceding that label
    #
    set entryIdx -1
    set childIdx 0
    set childCount [llength [$w cget -body]]
    foreach c [winfo children $w] {
	set class [winfo class $c]
	switch $class {
	    Entry {
		set str [$c get]
		set entry $c
		incr entryIdx
	    }
	    Frame {
		set str [$c.e get]
		set entry $c.e
		incr entryIdx
	    }
	    Label { set str [$c cget -text] }
	}
	set len [string length $str]

	if {$number < $len} {
	    break
	} elseif {$childIdx < $childCount - 1} {
	    incr number -$len
	}

	incr childIdx
    }

    #
    # If the entry's state is normal then set the focus to this entry and
    # the insertion cursor to the relative character position corresponding
    # to number; otherwise set the focus to the last enabled entry child
    # preceding the found one and set the insertion cursor to its end
    #
    switch $class {
	Entry -
	Frame { set relIdx $number }
	Label { set relIdx end }
    }
    if {[string compare [$entry cget -state] "normal"] == 0} {
	focus $entry
	$entry icursor $relIdx
    } else {
	for {incr entryIdx -1} {$entryIdx >= 0} {incr entryIdx -1} {
	    set entry [$w entrypath $entryIdx]
	    if {[string compare [$entry cget -state] "normal"] == 0} {
		focus $entry
		$entry icursor end
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustEditWindow
#
# Adjusts the width and the horizontal padding of the frame containing the edit
# window associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::adjustEditWindow {win pixels} {
    #
    # Adjust the width of the auxiliary object (if any)
    #
    upvar ::tablelist::ns${win}::data data
    set indent [getIndentData $win $data(editKey) $data(editCol) indentWidth]
    set aux [getAuxData $win $data(editKey) $data(editCol) auxType auxWidth]
    if {$indentWidth >= $pixels} {
	set indentWidth $pixels
	set pixels 0
	set auxWidth 0
    } else {
	incr pixels -$indentWidth
	if {$auxType == 1} {					;# image
	    if {$auxWidth + 5 <= $pixels} {
		incr auxWidth 3
		incr pixels -[expr {$auxWidth + 2}]
	    } elseif {$auxWidth <= $pixels} {
		set pixels 0
	    } else {
		set auxWidth $pixels
		set pixels 0
	    }
	}
    }

    if {$indentWidth != 0} {
	insertOrUpdateIndent $data(body) editIndentMark $indent $indentWidth
    }
    if {$auxType == 1} {					;# image
	setImgLabelWidth $data(body) editAuxMark $auxWidth
    }

    #
    # Compute an appropriate width and horizontal
    # padding for the frame containing the edit window
    #
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    if {$editWin($name-useReqWidth) &&
	[set reqWidth [winfo reqwidth $data(bodyFrmEd)]] <=
	$pixels + 2*$data(charWidth)} {
	set width $reqWidth
	set padX [expr {$reqWidth <= $pixels ? -3 : ($pixels - $reqWidth) / 2}]
    } else {
	if {$editWin($name-usePadX)} {
	    set amount $data(charWidth)
	} else {
	    switch -- $name {
		text { set amount 4 }
		ttk::entry {
		    if {[string compare [getCurrentTheme] "aqua"] == 0} {
			set amount 5
		    } else {
			set amount 3
		    }
		}
		default { set amount 3 }
	    }
	}
	set width [expr {$pixels + 2*$amount}]
	set padX -$amount
    }

    $data(bodyFrm) configure -width $width
    $data(body) window configure editMark -padx $padX
}

#------------------------------------------------------------------------------
# tablelist::setEditWinFont
#
# Sets the font of the edit window associated with the tablelist widget win to
# that of the cell currently being edited.
#------------------------------------------------------------------------------
proc tablelist::setEditWinFont win {
    upvar ::tablelist::ns${win}::data data
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    if {[string length $editWin($name-fontOpt)] == 0} {
	return ""
    }

    set key [lindex $data(keyList) $data(editRow)]
    set cellFont [getCellFont $win $key $data(editCol)]
    $data(bodyFrmEd) configure $editWin($name-fontOpt) $cellFont

    $data(bodyFrm) configure -height [winfo reqheight $data(bodyFrmEd)]
}

#------------------------------------------------------------------------------
# tablelist::saveEditData
#
# Saves some data of the edit window associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::saveEditData win {
    upvar ::tablelist::ns${win}::data data
    set w $data(bodyFrmEd)
    set entry $data(editFocus)
    set class [winfo class $w]
    set isText [expr {[string compare $class "Text"] == 0 ||
		      [string compare $class "Ctext"] == 0}]
    set isMentry [expr {[string compare $class "Mentry"] == 0}]

    #
    # Miscellaneous data
    #
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    set data(editText) [eval [strMap {"%W" "$w"} $editWin($name-getTextCmd)]]
    if {[string length $editWin($name-getListCmd)] != 0} {
	set data(editList) \
	    [eval [strMap {"%W" "$w"} $editWin($name-getListCmd)]]
    }
    if {$isText} {
	set data(editPos) [$w index insert]
	set data(textSelRanges) [$w tag ranges sel]
    } elseif {$editWin($name-isEntryLike)} {
	set data(editPos) [$entry index insert]
	if {[set data(entryHadSel) [$entry selection present]]} {
	    set data(entrySelFrom) [$entry index sel.first]
	    set data(entrySelTo)   [$entry index sel.last]
	}
    }
    set data(editHadFocus) \
	[expr {[string compare [focus -lastfor $entry] $entry] == 0}]

    #
    # Configuration options and widget callbacks
    #
    saveEditConfigOpts $w
    if {[info exists ::wcb::version] &&
	$editWin($name-isEntryLike) && !$isMentry} {
	set wcbOptList {insert delete motion}
	if {$isText} {
	    lappend wcbOptList selset selclear
	    if {$::wcb::version >= 3.2} {
		lappend wcbOptList replace
	    }
	}
	foreach when {before after} {
	    foreach opt $wcbOptList {
		set data(entryCb-$when-$opt) \
		    [::wcb::callback $entry $when $opt]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::saveEditConfigOpts
#
# Saves the non-default values of the configuration options of the edit window
# w associated with a tablelist widget, as well as those of its descendants.
#------------------------------------------------------------------------------
proc tablelist::saveEditConfigOpts w {
    regexp {^(.+)\.body\.f\.(e.*)$} $w dummy win tail
    upvar ::tablelist::ns${win}::data data

    foreach configSet [$w configure] {
	if {[llength $configSet] != 2} {
	    set default [lindex $configSet 3]
	    set current [lindex $configSet 4]
	    if {[string compare $default $current] != 0} {
		set opt [lindex $configSet 0]
		set data($tail$opt) $current
	    }
	}
    }

    foreach c [winfo children $w] {
	saveEditConfigOpts $c
    }

    if {[string match "*Menubutton" [winfo class $w]]} {
	set menu [$w cget -menu]
	set last [$menu index last]
	set types {}

	if {[string compare $last "none"] != 0} {
	    for {set idx 0} {$idx <= $last} {incr idx} {
		lappend types [$menu type $idx]
		foreach configSet [$menu entryconfigure $idx] {
		    set default [lindex $configSet 3]
		    set current [lindex $configSet 4]
		    if {[string compare $default $current] != 0} {
			set opt [lindex $configSet 0]
			set data($menu,$idx$opt) $current
		    }
		}
	    }
	}

	set data($menu:types) $types
    }
}

#------------------------------------------------------------------------------
# tablelist::restoreEditData
#
# Restores some data of the edit window associated with the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::restoreEditData win {
    upvar ::tablelist::ns${win}::data data
    set w $data(bodyFrmEd)
    set entry $data(editFocus)
    set class [winfo class $w]
    set isText [expr {[string compare $class "Text"] == 0 ||
		      [string compare $class "Ctext"] == 0}]
    set isMentry [expr {[string compare $class "Mentry"] == 0}]
    set isIncrDateTimeWidget [regexp {^(Date.+|Time.+)$} $class]

    #
    # Miscellaneous data
    #
    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    if {[string length $editWin($name-putTextCmd)] != 0} {
	eval [strMap {"%W" "$w"  "%T" "$data(editText)"} \
	      $editWin($name-putTextCmd)]
    }
    if {[string length $editWin($name-putListCmd)] != 0 &&
	[string length $data(editList)] != 0} {
	eval [strMap {"%W" "$w"  "%L" "$data(editList)"} \
	      $editWin($name-putListCmd)]
    }
    if {[string length $editWin($name-selectCmd)] != 0 &&
	[set idx [lsearch -exact $data(editList) $data(editText)]] >= 0} {
	eval [strMap {"%W" "$w"  "%I" "$idx"} $editWin($name-selectCmd)]
    }
    if {$isText} {
	$w mark set insert $data(editPos)
	if {[llength $data(textSelRanges)] != 0} {
	    eval [list $w tag add sel] $data(textSelRanges)
	}
    } elseif {$editWin($name-isEntryLike)} {
	$entry icursor $data(editPos)
	if {$data(entryHadSel)} {
	    $entry selection range $data(entrySelFrom) $data(entrySelTo)
	}
    }
    if {$data(editHadFocus)} {
	focus $entry
    }

    #
    # Configuration options and widget callbacks
    #
    restoreEditConfigOpts $w
    if {[info exists ::wcb::version] &&
	$editWin($name-isEntryLike) && !$isMentry} {
	set wcbOptList {insert delete motion}
	if {$isText} {
	    lappend wcbOptList selset selclear
	    if {$::wcb::version >= 3.2} {
		lappend wcbOptList replace
	    }
	}
	foreach when {before after} {
	    foreach opt $wcbOptList {
		eval [list ::wcb::callback $entry $when $opt] \
		     $data(entryCb-$when-$opt)
	    }
	}
    }

    #
    # If the edit window is a datefield, dateentry, timefield, or timeentry
    # widget then restore its text here, because otherwise it would be
    # overridden when the above invocation of restoreEditConfigOpts sets
    # the widget's -format option.  Note that this is a special case; in
    # general we must restore the text BEFORE the configuration options.
    #
    if {$isIncrDateTimeWidget} {
	eval [strMap {"%W" "$w"  "%T" "$data(editText)"} \
	      $editWin($name-putTextCmd)]
    }
}

#------------------------------------------------------------------------------
# tablelist::restoreEditConfigOpts
#
# Restores the non-default values of the configuration options of the edit
# window w associated with a tablelist widget, as well as those of its
# descendants.
#------------------------------------------------------------------------------
proc tablelist::restoreEditConfigOpts w {
    regexp {^(.+)\.body\.f\.(e.*)$} $w dummy win tail
    upvar ::tablelist::ns${win}::data data
    set isMentry [expr {[string compare [winfo class $w] "Mentry"] == 0}]

    foreach name [array names data $tail-*] {
	set opt [string range $name [string last "-" $name] end]
	if {!$isMentry || [string compare $opt "-body"] != 0} {
	    $w configure $opt $data($name)
	}
	unset data($name)
    }

    foreach c [winfo children $w] {
	restoreEditConfigOpts $c
    }

    if {[string match "*Menubutton" [winfo class $w]]} {
	set menu [$w cget -menu]
	foreach type $data($menu:types) {
	    $menu add $type
	}
	unset data($menu:types)

	foreach name [array names data $menu,*] {
	    regexp {^.+,(.+)(-.+)$} $name dummy idx opt
	    $menu entryconfigure $idx $opt $data($name)
	    unset data($name)
	}
    }
}

#
# Private procedures used in bindings related to interactive cell editing
# =======================================================================
#

#------------------------------------------------------------------------------
# tablelist::defineTablelistEdit
#
# Defines the bindings for the binding tag TablelistEdit.
#------------------------------------------------------------------------------
proc tablelist::defineTablelistEdit {} {
    #
    # Get the supported modifier keys in the set {Alt, Meta, Command} on
    # the current windowing system ("x11", "win32", "classic", or "aqua")
    #
    variable winSys
    switch $winSys {
	x11	{ set modList {Alt Meta} }
	win32	{ set modList {Alt} }
	classic -
	aqua	{ set modList {Command} }
    }

    #
    # Define some bindings for the binding tag TablelistEdit
    #
    bind TablelistEdit <Button-1> {
	#
	# Very short left-clicks on the tablelist's body are sometimes
	# unexpectedly propagated to the edit window just created - make
	# sure they won't be handled by the latter's default bindings
	#
	if {$tablelist::priv(justReleased)} {
	    break
	}

	set tablelist::priv(clickedInEditWin) 1
	focus %W
    }
    bind TablelistEdit <ButtonRelease-1> {
	if {%X >= 0} {				;# i.e., no generated event
	    foreach {tablelist::W tablelist::x tablelist::y} \
		[tablelist::convEventFields %W %x %y] {}

	    set tablelist::priv(x) ""
	    set tablelist::priv(y) ""
	    after cancel $tablelist::priv(afterId)
	    set tablelist::priv(afterId) ""
	    set tablelist::priv(justReleased) 1
	    after 100 [list set tablelist::priv(justReleased) 0]
	    set tablelist::priv(releasedInEditWin) 1
	    if {!$tablelist::priv(clickedInEditWin)} {
		if {$tablelist::priv(justClicked)} {
		    tablelist::moveOrActivate $tablelist::W \
			$tablelist::priv(row) $tablelist::priv(col) 1
		} else {
		    tablelist::moveOrActivate $tablelist::W \
			[$tablelist::W nearest       $tablelist::y] \
			[$tablelist::W nearestcolumn $tablelist::x] \
			[expr {$tablelist::x >= 0 &&
			       $tablelist::x < [winfo width $tablelist::W] &&
			       $tablelist::y >= [winfo y $tablelist::W.body] &&
			       $tablelist::y < [winfo height $tablelist::W]}]
		}
	    }
	    after 100 [list tablelist::condEvalInvokeCmd $tablelist::W]
	}
    }
    bind TablelistEdit <Control-i>    { tablelist::insertChar %W "\t" }
    bind TablelistEdit <Control-j>    { tablelist::insertChar %W "\n" }
    bind TablelistEdit <Escape>       { tablelist::cancelEditing %W }
    foreach key {Return KP_Enter} {
	bind TablelistEdit <$key> {
	    if {[string compare [winfo class %W] "Text"] == 0 ||
		[string compare [winfo class %W] "Ctext"] == 0} {
		tablelist::insertChar %W "\n"
	    } else {
		tablelist::finishEditing %W
	    }
	}
	bind TablelistEdit <Control-$key> {
	    tablelist::finishEditing %W
	}
    }
    bind TablelistEdit <Tab>	      { tablelist::goToNextPrevCell %W  1 }
    bind TablelistEdit <Shift-Tab>    { tablelist::goToNextPrevCell %W -1 }
    bind TablelistEdit <<PrevWindow>> { tablelist::goToNextPrevCell %W -1 }
    foreach modifier $modList {
	bind TablelistEdit <$modifier-Left> {
	    tablelist::goLeftRight %W -1
	}
	bind TablelistEdit <$modifier-Right> {
	    tablelist::goLeftRight %W 1
	}
	bind TablelistEdit <$modifier-Up> {
	    tablelist::goUpDown %W -1
	}
	bind TablelistEdit <$modifier-Down> {
	    tablelist::goUpDown %W 1
	}
	bind TablelistEdit <$modifier-Prior> {
	    tablelist::goToPriorNextPage %W -1
	}
	bind TablelistEdit <$modifier-Next> {
	    tablelist::goToPriorNextPage %W 1
	}
	bind TablelistEdit <$modifier-Home> {
	    tablelist::goToNextPrevCell %W 1 0 -1
	}
	bind TablelistEdit <$modifier-End> {
	    tablelist::goToNextPrevCell %W -1 0 0
	}
    }
    foreach direction {Left Right} amount {-1 1} {
	bind TablelistEdit <$direction> [format {
	    if {![tablelist::isKeyReserved %%W %%K]} {
		tablelist::goLeftRight %%W %d
	    }
	} $amount]
    }
    foreach direction {Up Down} amount {-1 1} {
	bind TablelistEdit <$direction> [format {
	    if {![tablelist::isKeyReserved %%W %%K]} {
		tablelist::goUpDown %%W %d
	    }
	} $amount]
    }
    foreach page {Prior Next} amount {-1 1} {
	bind TablelistEdit <$page> [format {
	    if {![tablelist::isKeyReserved %%W %%K]} {
		tablelist::goToPriorNextPage %%W %d
	    }
	} $amount]
    }
    bind TablelistEdit <Control-Home> {
	if {![tablelist::isKeyReserved %W Control-Home]} {
	    tablelist::goToNextPrevCell %W 1 0 -1
	}
    }
    bind TablelistEdit <Control-End> {
	if {![tablelist::isKeyReserved %W Control-End]} {
	    tablelist::goToNextPrevCell %W -1 0 0
	}
    }
    foreach pattern {Tab Shift-Tab ISO_Left_Tab hpBackTab} {
	catch {
	    foreach modifier {Control Meta} {
		bind TablelistEdit <$modifier-$pattern> [format {
		    mwutil::processTraversal %%W Tablelist <%s>
		} $pattern]
	    }
	}
    }
    bind TablelistEdit <FocusIn> {
	set tablelist::W [tablelist::getTablelistPath %W]
	set tablelist::ns${tablelist::W}::data(editFocus) %W
    }

    #
    # Define some emacs-like key bindings for the binding tag TablelistEdit
    #
    foreach pattern {Meta-b Meta-f} amount {-1 1} {
	bind TablelistEdit <$pattern> [format {
	    if {!$tk_strictMotif && ![tablelist::isKeyReserved %%W %s]} {
		tablelist::goLeftRight %%W %d
	    }
	} $pattern $amount]
    }
    foreach pattern {Control-p Control-n} amount {-1 1} {
	bind TablelistEdit <$pattern> [format {
	    if {!$tk_strictMotif && ![tablelist::isKeyReserved %%W %s]} {
		tablelist::goUpDown %%W %d
	    }
	} $pattern $amount]
    }
    bind TablelistEdit <Meta-less> {
	if {!$tk_strictMotif &&
	    ![tablelist::isKeyReserved %W Meta-less]} {
	    tablelist::goToNextPrevCell %W 1 0 -1
	}
    }
    bind TablelistEdit <Meta-greater> {
	if {!$tk_strictMotif &&
	    ![tablelist::isKeyReserved %W Meta-greater]} {
	    tablelist::goToNextPrevCell %W -1 0 0
	}
    }

    #
    # Define some bindings for the binding tag TablelistEdit that
    # propagate the mousewheel events to the tablelist's body
    #
    catch {
	bind TablelistEdit <MouseWheel> {
	    if {![tablelist::hasMouseWheelBindings %W] &&
		![tablelist::isComboTopMapped %W]} {
		tablelist::genMouseWheelEvent \
		    [[tablelist::getTablelistPath %W] bodypath] %D
	    }
	}
	bind TablelistEdit <Option-MouseWheel> {
	    if {![tablelist::hasMouseWheelBindings %W] &&
		![tablelist::isComboTopMapped %W]} {
		tablelist::genOptionMouseWheelEvent \
		    [[tablelist::getTablelistPath %W] bodypath] %D
	    }
	}
    }
    foreach detail {4 5} {
	bind TablelistEdit <Button-$detail> [format {
	    if {![tablelist::hasMouseWheelBindings %%W] &&
		![tablelist::isComboTopMapped %%W]} {
		event generate \
		    [[tablelist::getTablelistPath %%W] bodypath] <Button-%s>
	    }
	} $detail]
    }
}

#------------------------------------------------------------------------------
# tablelist::insertChar
#
# Inserts the string str ("\t" or "\n") into the entry-like widget w at the
# point of the insertion cursor.
#------------------------------------------------------------------------------
proc tablelist::insertChar {w str} {
    set class [winfo class $w]
    if {[string compare $class "Text"] == 0 ||
	[string compare $class "Ctext"] == 0} {
	if {[string compare $str "\n"] == 0} {
	    eval [strMap {"%W" "$w"} [bind Text <Return>]]
	} else {
	    eval [strMap {"%W" "$w"} [bind Text <Control-i>]]
	}
	return -code break ""
    } elseif {[regexp {^(T?Entry|TCombobox|T?Spinbox)$} $class]} {
	if {[string match "T*" $class]} {
	    if {[string length [info procs "::ttk::entry::Insert"]] != 0} {
		ttk::entry::Insert $w $str
	    } else {
		tile::entry::Insert $w $str
	    }
	} elseif {[string length [info procs "::tk::EntryInsert"]] != 0} {
	    tk::EntryInsert $w $str
	} else {
	    tkEntryInsert $w $str
	}
	return -code break ""
    }
}

#------------------------------------------------------------------------------
# tablelist::cancelEditing
#
# Invokes the doCancelEditing procedure.
#------------------------------------------------------------------------------
proc tablelist::cancelEditing w {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(sourceRow)]} {	;# move operation in progress
	return ""
    }

    doCancelEditing $win
    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::finishEditing
#
# Invokes the doFinishEditing procedure.
#------------------------------------------------------------------------------
proc tablelist::finishEditing w {
    if {[isComboTopMapped $w]} {
	return ""
    }

    doFinishEditing [getTablelistPath $w]
    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::goToNextPrevCell
#
# Moves the edit window into the next or previous editable cell different from
# the one indicated by the given row and column, if there is such a cell.
#------------------------------------------------------------------------------
proc tablelist::goToNextPrevCell {w amount args} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    variable winSys
    if {[string compare $winSys "aqua"] == 0 &&
	([string length $::tk::Priv(postedMb)] != 0 ||
	 [string length $::tk::Priv(popup)] != 0)} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    if {[llength $args] == 0} {
	set row $data(editRow)
	set col $data(editCol)
	set cmd condChangeSelection
    } else {
	foreach {row col} $args {}
	set cmd changeSelection
    }

    if {![doFinishEditing $win]} {
	return ""
    }

    set oldRow $row
    set oldCol $col

    while 1 {
	incr col $amount
	if {$col < 0} {
	    incr row $amount
	    if {$row < 0} {
		set row $data(lastRow)
	    }
	    set col $data(lastCol)
	} elseif {$col > $data(lastCol)} {
	    incr row $amount
	    if {$row > $data(lastRow)} {
		set row 0
	    }
	    set col 0
	}

	if {$row == $oldRow && $col == $oldCol} {
	    return -code break ""
	} elseif {[isRowViewable $win $row] && !$data($col-hide) &&
		  [isCellEditable $win $row $col]} {
	    doEditCell $win $row $col 0 $cmd
	    return -code break ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::goLeftRight
#
# Moves the edit window into the previous or next editable cell of the current
# row if the cell being edited is not the first/last editable one within that
# row.
#------------------------------------------------------------------------------
proc tablelist::goLeftRight {w amount} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    set row $data(editRow)
    set col $data(editCol)

    if {![doFinishEditing $win]} {
	return ""
    }

    while 1 {
	incr col $amount
	if {$col < 0 || $col > $data(lastCol)} {
	    return -code break ""
	} elseif {!$data($col-hide) && [isCellEditable $win $row $col]} {
	    doEditCell $win $row $col 0 condChangeSelection
	    return -code break ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::goUpDown
#
# Invokes the goToPrevNextLine procedure.
#------------------------------------------------------------------------------
proc tablelist::goUpDown {w amount} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    goToPrevNextLine $w $amount $data(editRow) $data(editCol) \
	condChangeSelection
    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::goToPrevNextLine
#
# Moves the edit window into the last or first editable cell that is located in
# the specified column and has a row index less/greater than the given one, if
# there is such a cell.
#------------------------------------------------------------------------------
proc tablelist::goToPrevNextLine {w amount row col cmd} {
    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    if {![doFinishEditing $win]} {
	return ""
    }

    while 1 {
	incr row $amount
	if {$row < 0 || $row > $data(lastRow)} {
	    return 0
	} elseif {[isRowViewable $win $row] &&
		  [isCellEditable $win $row $col]} {
	    doEditCell $win $row $col 0 $cmd
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::goToPriorNextPage
#
# Moves the edit window up or down by one page within the current column if the
# cell being edited is not the first/last editable one within that column.
#------------------------------------------------------------------------------
proc tablelist::goToPriorNextPage {w amount} {
    if {[isComboTopMapped $w]} {
	return ""
    }

    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    #
    # Check whether there is any viewable editable cell
    # above/below the current one, in the same column
    #
    set row $data(editRow)
    set col $data(editCol)
    while 1 {
	incr row $amount
	if {$row < 0 || $row > $data(lastRow)} {
	    return -code break ""
	} elseif {[isRowViewable $win $row] &&
		  [isCellEditable $win $row $col]} {
	    break
	}
    }

    #
    # Scroll up/down the view by one page and get the corresponding row index
    #
    set row $data(editRow)
    seeRow $win $row
    set bbox [bboxSubCmd $win $row]
    yviewSubCmd $win [list scroll $amount pages]
    set newRow [rowIndex $win @0,[lindex $bbox 1] 0]

    if {$amount < 0} {
	if {$newRow < $row} {
	    if {![goToPrevNextLine $w -1 [expr {$newRow + 1}] $col \
		  changeSelection]} {
		goToPrevNextLine $w 1 $newRow $col changeSelection
	    }
	} else {
	    goToPrevNextLine $w 1 -1 $col changeSelection
	}
    } else {
	if {$newRow > $row} {
	    if {![goToPrevNextLine $w 1 [expr {$newRow - 1}] $col \
		  changeSelection]} {
		goToPrevNextLine $w -1 $newRow $col changeSelection
	    }
	} else {
	    goToPrevNextLine $w -1 $data(itemCount) $col changeSelection
	}
    }

    return -code break ""
}

#------------------------------------------------------------------------------
# tablelist::genMouseWheelEvent
#
# Generates a <MouseWheel> event with the given delta on the widget w.
#------------------------------------------------------------------------------
proc tablelist::genMouseWheelEvent {w delta} {
    set focus [focus -displayof $w]
    focus $w
    event generate $w <MouseWheel> -delta $delta
    focus $focus
}

#------------------------------------------------------------------------------
# tablelist::genOptionMouseWheelEvent
#
# Generates an <Option-MouseWheel> event with the given delta on the widget w.
#------------------------------------------------------------------------------
proc tablelist::genOptionMouseWheelEvent {w delta} {
    set focus [focus -displayof $w]
    focus $w
    event generate $w <Option-MouseWheel> -delta $delta
    focus $focus
}

#------------------------------------------------------------------------------
# tablelist::isKeyReserved
#
# Checks whether the given keysym is used in the standard binding scripts
# associated with the widget w, which is assumed to be the edit window or one
# of its descendants.
#------------------------------------------------------------------------------
proc tablelist::isKeyReserved {w keySym} {
    set win [getTablelistPath $w]
    upvar ::tablelist::ns${win}::data data

    set name [getEditWindow $win $data(editRow) $data(editCol)]
    variable editWin
    return [expr {[lsearch -exact $editWin($name-reservedKeys) $keySym] >= 0}]
}

#------------------------------------------------------------------------------
# tablelist::hasMouseWheelBindings
#
# Checks whether the given widget, which is assumed to be the edit window or
# one of its descendants, has mouse wheel bindings.
#------------------------------------------------------------------------------
proc tablelist::hasMouseWheelBindings w {
    if {[regexp {^(Text|Ctext|TCombobox|TSpinbox)$} [winfo class $w]]} {
	return 1
    } else {
	set bindTags [bindtags $w]
	return [expr {([lsearch -exact $bindTags "MentryDateTime"] >= 0 ||
		       [lsearch -exact $bindTags "MentryMeridian"] >= 0 ||
		       [lsearch -exact $bindTags "MentryIPAddr"] >= 0 ||
		       [lsearch -exact $bindTags "MentryIPv6Addr"] >= 0) &&
		      ($mentry::version >= 3.2)}]
    }
}

#------------------------------------------------------------------------------
# tablelist::isComboTopMapped
#
# Checks whether the given widget is a component of an Oakley combobox having
# its toplevel child mapped.  This is needed in our binding scripts to make
# sure that the interactive cell editing won't be terminated prematurely,
# because Bryan Oakley's combobox keeps the focus on its entry child even if
# its toplevel component is mapped.
#------------------------------------------------------------------------------
proc tablelist::isComboTopMapped w {
    set par [winfo parent $w]
    if {[string compare [winfo class $par] "Combobox"] == 0 &&
	[winfo exists $par.top] && [winfo ismapped $par.top]} {
	return 1
    } else {
	return 0
    }
}

Added libs/tablelist6.0/scripts/tablelistImages.tcl.













































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
#==============================================================================
# Contains procedures that create various bitmap and photo images.  The
# argument w specifies a canvas displaying a sort arrow, while the argument win
# stands for a tablelist widget.
#
# Copyright (c) 2006-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#------------------------------------------------------------------------------
# tablelist::flat5x3Arrows
#------------------------------------------------------------------------------
proc tablelist::flat5x3Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp5x3_width 5
#define triangleUp5x3_height 3
static unsigned char triangleUp5x3_bits[] = {
   0x04, 0x0e, 0x1f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn5x3_width 5
#define triangleDn5x3_height 3
static unsigned char triangleDn5x3_bits[] = {
   0x1f, 0x0e, 0x04};
"
}

#------------------------------------------------------------------------------
# tablelist::flat5x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat5x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp5x4_width 5
#define triangleUp5x4_height 4
static unsigned char triangleUp5x4_bits[] = {
   0x04, 0x0e, 0x1f, 0x1f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn5x4_width 5
#define triangleDn5x4_height 4
static unsigned char triangleDn5x4_bits[] = {
   0x1f, 0x1f, 0x0e, 0x04};
"
}

#------------------------------------------------------------------------------
# tablelist::flat6x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat6x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp6x4_width 6
#define triangleUp6x4_height 4
static unsigned char triangleUp6x4_bits[] = {
   0x0c, 0x1e, 0x3f, 0x3f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn6x4_width 6
#define triangleDn6x4_height 4
static unsigned char triangleDn7x4_bits[] = {
   0x3f, 0x3f, 0x1e, 0x0c};
"
}

#------------------------------------------------------------------------------
# tablelist::flat7x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat7x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x4_width 7
#define triangleUp7x4_height 4
static unsigned char triangleUp7x4_bits[] = {
   0x08, 0x1c, 0x3e, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x4_width 7
#define triangleDn7x4_height 4
static unsigned char triangleDn7x4_bits[] = {
   0x7f, 0x3e, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flat7x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flat7x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x5_width 7
#define triangleUp7x5_height 5
static unsigned char triangleUp7x5_bits[] = {
   0x08, 0x1c, 0x3e, 0x7f, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x5_width 7
#define triangleDn7x5_height 5
static unsigned char triangleDn7x5_bits[] = {
   0x7f, 0x7f, 0x3e, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flat7x7Arrows
#------------------------------------------------------------------------------
proc tablelist::flat7x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x7_width 7
#define triangleUp7x7_height 7
static unsigned char triangleUp7x7_bits[] = {
   0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x7_width 7
#define triangleDn7x7_height 7
static unsigned char triangleDn7x7_bits[] = {
   0x7f, 0x7f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flat8x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flat8x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp8x4_width 8
#define triangleUp8x4_height 4
static unsigned char triangleUp8x4_bits[] = {
   0x18, 0x3c, 0x7e, 0xff};
"
    image create bitmap triangleDn$w -data "
#define triangleDn8x4_width 8
#define triangleDn8x4_height 4
static unsigned char triangleDn8x4_bits[] = {
   0xff, 0x7e, 0x3c, 0x18};
"
}

#------------------------------------------------------------------------------
# tablelist::flat8x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flat8x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp8x5_width 8
#define triangleUp8x5_height 5
static unsigned char triangleUp8x5_bits[] = {
   0x18, 0x3c, 0x7e, 0xff, 0xff};
"
    image create bitmap triangleDn$w -data "
#define triangleDn8x5_width 8
#define triangleDn8x5_height 5
static unsigned char triangleDn8x5_bits[] = {
   0xff, 0xff, 0x7e, 0x3c, 0x18};
"
}

#------------------------------------------------------------------------------
# tablelist::flat9x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flat9x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x5_width 9
#define triangleUp9x5_height 5
static unsigned char triangleUp9x5_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x5_width 9
#define triangleDn9x5_height 5
static unsigned char triangleDn9x5_bits[] = {
   0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flat9x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flat9x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x6_width 9
#define triangleUp9x6_height 6
static unsigned char triangleUp9x6_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xff, 0x01, 0xff, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x6_width 9
#define triangleDn9x6_height 6
static unsigned char triangleDn9x6_bits[] = {
   0xff, 0x01, 0xff, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flat11x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flat11x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp11x6_width 11
#define triangleUp11x6_height 6
static unsigned char triangleUp11x6_bits[] = {
   0x20, 0x00, 0x70, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe, 0x03, 0xff, 0x07};
"
    image create bitmap triangleDn$w -data "
#define triangleDn11x6_width 11
#define triangleDn11x6_height 6
static unsigned char triangleDn11x6_bits[] = {
   0xff, 0x07, 0xfe, 0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00, 0x20, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flat15x8Arrows
#------------------------------------------------------------------------------
proc tablelist::flat15x8Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp15x8_width 15
#define triangleUp15x8_height 8
static unsigned char triangleUp15x8_bits[] = {
   0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
   0xfe, 0x3f, 0xff, 0x7f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn15x8_width 15
#define triangleDn15x8_height 8
static unsigned char triangleDn15x8_bits[] = {
   0xff, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03,
   0xc0, 0x01, 0x80, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle7x4Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle7x4Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x4_width 7
#define triangleUp7x4_height 4
static unsigned char triangleUp7x4_bits[] = {
   0x08, 0x1c, 0x36, 0x63};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x4_width 7
#define triangleDn7x4_height 4
static unsigned char triangleDn7x4_bits[] = {
   0x63, 0x36, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle7x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle7x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp7x5_width 7
#define triangleUp7x5_height 5
static unsigned char triangleUp7x5_bits[] = {
   0x08, 0x1c, 0x3e, 0x77, 0x63};
"
    image create bitmap triangleDn$w -data "
#define triangleDn7x5_width 7
#define triangleDn7x5_height 5
static unsigned char triangleDn7x5_bits[] = {
   0x63, 0x77, 0x3e, 0x1c, 0x08};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle9x5Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle9x5Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x5_width 9
#define triangleUp9x5_height 5
static unsigned char triangleUp9x5_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x6c, 0x00, 0xc6, 0x00, 0x83, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x5_width 9
#define triangleDn9x5_height 5
static unsigned char triangleDn9x5_bits[] = {
   0x83, 0x01, 0xc6, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle9x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle9x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x6_width 9
#define triangleUp9x6_height 6
static unsigned char triangleUp9x6_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xee, 0x00, 0xc7, 0x01, 0x83, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x6_width 9
#define triangleDn9x6_height 6
static unsigned char triangleDn9x6_bits[] = {
   0x83, 0x01, 0xc7, 0x01, 0xee, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle9x7Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle9x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp9x7_width 9
#define triangleUp9x7_height 7
static unsigned char triangleUp9x7_bits[] = {
   0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0xef, 0x01, 0xc7, 0x01,
   0x83, 0x01};
"
    image create bitmap triangleDn$w -data "
#define triangleDn9x7_width 9
#define triangleDn9x7_height 7
static unsigned char triangleDn9x7_bits[] = {
   0x83, 0x01, 0xc7, 0x01, 0xef, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00,
   0x10, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle10x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle10x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp10x6_width 10
#define triangleUp10x6_height 6
static unsigned char triangleUp10x6_bits[] = {
   0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xce, 0x01, 0x87, 0x03, 0x03, 0x03};
"
    image create bitmap triangleDn$w -data "
#define triangleDn10x6_width 10
#define triangleDn10x6_height 6
static unsigned char triangleDn10x6_bits[] = {
   0x03, 0x03, 0x87, 0x03, 0xce, 0x01, 0xfc, 0x00, 0x78, 0x00, 0x30, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle10x7Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle10x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp10x7_width 10
#define triangleUp10x7_height 7
static unsigned char triangleUp10x7_bits[] = {
   0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xfe, 0x01, 0xcf, 0x03, 0x87, 0x03,
   0x03, 0x03};
"
    image create bitmap triangleDn$w -data "
#define triangleDn10x7_width 10
#define triangleDn10x7_height 7
static unsigned char triangleDn10x6_bits[] = {
   0x03, 0x03, 0x87, 0x03, 0xcf, 0x03, 0xfe, 0x01, 0xfc, 0x00, 0x78, 0x00,
   0x30, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle11x6Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle11x6Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp11x6_width 11
#define triangleUp11x6_height 6
static unsigned char triangleUp11x6_bits[] = {
   0x20, 0x00, 0x70, 0x00, 0xd8, 0x00, 0x8c, 0x01, 0x06, 0x03, 0x03, 0x06};
"
    image create bitmap triangleDn$w -data "
#define triangleDn11x6_width 11
#define triangleDn11x6_height 6
static unsigned char triangleDn11x6_bits[] = {
   0x03, 0x06, 0x06, 0x03, 0x8c, 0x01, 0xd8, 0x00, 0x70, 0x00, 0x20, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::flatAngle15x8Arrows
#------------------------------------------------------------------------------
proc tablelist::flatAngle15x8Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp15x8_width 15
#define triangleUp15x8_height 8
static unsigned char triangleUp15x8_bits[] = {
   0x80, 0x00, 0xc0, 0x01, 0x60, 0x03, 0x30, 0x06, 0x18, 0x0c, 0x0c, 0x18,
   0x06, 0x30, 0x03, 0x60};
"
    image create bitmap triangleDn$w -data "
#define triangleDn15x8_width 15
#define triangleDn15x8_height 8
static unsigned char triangleDn15x8_bits[] = {
   0x03, 0x60, 0x06, 0x30, 0x0c, 0x18, 0x18, 0x0c, 0x30, 0x06, 0x60, 0x03,
   0xc0, 0x01, 0x80, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::photo7x4Arrows
#------------------------------------------------------------------------------
proc tablelist::photo7x4Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhBwAEAIQRAAAAADxZbDxeckNfb0BidF6IoWGWtlabwIexxZq2xYbI65HL7LXd8rri9MPk
9cTj9Mrm9f///////////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAHAAQAAAUS4CcSYikcRRkYypJ8A9IwD+SEADs=
"
    triangleDn$w put "
R0lGODlhBwAEAIQQAAAAADxeclKLq2KauWes03CpxnKrynOy2IO62ZXG4JrH4JrL5pnQ7qbY87Pb
8cTj9P///////////////////////////////////////////////////////////////yH5BAEK
AAAALAAAAAAHAAQAAAUSYDAUBpIogHAwzgO8ROO+70KHADs=
"
}

#------------------------------------------------------------------------------
# tablelist::photo7x7Arrows
#------------------------------------------------------------------------------
proc tablelist::photo7x7Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAA7DAAAOwwHHb6hk
AAAAGnRFWHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAABCSURBVBhXXY4BCgAgCAP9
T//R9/Ryc+ZEHCyb40CB3D1n6OAZuQOKi9klPhUsjNJ6VwUp+tOLopOGNkXncToWw6IPjiowJNyp
gu8AAAAASUVORK5CYII=
"
    triangleDn$w put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwwAADsMBx2+oZAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAP0lE
QVQYV22LgQ0AIAjD9g//yD1ejoBoFpRkISsUPsMzPwkOIcARmJlvKMGIJq9jt+Uem51Wscfe1hkq
8VAdWKBfMCRjQcZZAAAAAElFTkSuQmCC
"
}

#------------------------------------------------------------------------------
# tablelist::photo9x5Arrows
#------------------------------------------------------------------------------
proc tablelist::photo9x5Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhCQAFAIQTAAAAADxeckBidGaJmlabwG6mw4exxZy9z4bI647M7JvS76HV8KjX8a3a8rPc
8rLe87jf9Lzh9MPk9f///////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAJAAUAAAUZ4Cd+wWgGhGCSBKIMY1AkSwMdpPEwTiT9IQA7
"
    triangleDn$w put "
R0lGODlhCQAFAIQSAAAAADxeck90imuUrGKauW2jwWes036xzXOy2IO83YO83o++2JrH4JrK5rPZ
7rPZ77TZ7sTj9P///////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAJAAUAAAUaYECMxbEwzCcgSNJA0ScPSuPEsmw8eC43vhAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::photo11x6Arrows
#------------------------------------------------------------------------------
proc tablelist::photo11x6Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhCwAGAKUjAAAAADJdfDJefDFefjRffDhhfC9njDNrjThtjj5xkUJykWuXs2Ogw2ukxHKp
yHusyZrD2o7M7JfQ7qDE2qfH2arJ2aPQ6aLU76Td+6/h/bDi/rrj+bjm/rrn/8Pm+sLr/8Ps/8ro
+szu////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAALAAYAAAYqwJ9Q
WBgahQTF4ohMPCyQYwDhuHA2k6Hg0JBkOh8P5TcwMCIYTQckClWCADs=
"
    triangleDn$w put "
R0lGODlhCwAGAKUkAAAAADl1ml+DnlaRtWGZu2ievXaet2+gvXekvmKfw32owXu314Kqwoiswoey
yo21zIa+3JC2zZ26y5DB3ZjG34fE5ZHJ55/J4ZrN6KTC1KjN4qLb+azf+rrV5rDi/rrn/7/m+8Ps
/8vu/9Pw////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAALAAYAAAYqQEFg
QCgcEApGQ/IzJBaQCeWi6fyujsrG8wmNruCHhfMRgc8RDOjMzrCDADs=
"
}

#------------------------------------------------------------------------------
# tablelist::photo15x8Arrows
#------------------------------------------------------------------------------
proc tablelist::photo15x8Arrows w {
    foreach dir {Up Dn} {
	image create photo triangle$dir$w
    }

    triangleUp$w put "
R0lGODlhDwAIAKU/AAAAAB1YfjJefy1pjjVmhjJrjzppiD1qiTVtkTpwkTxwkT18oUFsikRuilKP
s16Rr1aStFyUtWeHnGKKo2CWtXGhvV6dwnOy1Ha02Hu01YKovommuI2xxIC314S31JGyx5W1x5S3
zJi2yJG915nE2p/F24fD44/I5o7K65bF4JbN7ZjM6J/P6Z3Q7Z7X9abJ3anN4KfS6q/U6azV66zX
76fa9qzb9and+bLb8Lne8rHg+rLi+7fi+bnk+73l+v///yH5BAEKAD8ALAAAAAAPAAgAAAZJwJ9w
+JMQj8QGYYI8NhSPiqYpZCQontSI0zwgIp2WjUb6HA8FSEZV0/FwJdDQMHBcUK7brufLvUQ/AgEL
FhgmJyssMTMyMCEbQQA7
"
    triangleDn$w put "
R0lGODlhDwAIAKU/AAAAACdjiUBtjkKBpkaGqlWFpVaUuFyav2SVtGGdv2Cew2ehwm2jw26tz3Ok
wXOmw3amwnuow3ioxH6pw3Gv0nSz13iz03611ICsxYOux4mtwomxyI2yyIK00oa41Yy815KvwZm5
zJO+2JjC2Z/D2J7E2obC4o/I5o3J6pTM65jM6J/P6ZzP657X9avH2anP5afS6q7U6azV66fa9qnZ
9Knd+bjV5rrc8bHg+rLi+7fi+b/g8rnk+7zl+sXh8v///yH5BAEKAD8ALAAAAAAPAAgAAAZIQEFg
YEgsGA8JJrPhaEC/AkHRsFw8H9GoRHL9vohDxXRSrWCymO3LdlBQrVqO1/Ox7xBLaobT7e6AERcs
NDeAhxMdL4eMIYxBADs=
"
}

#------------------------------------------------------------------------------
# tablelist::sunken8x7Arrows
#------------------------------------------------------------------------------
proc tablelist::sunken8x7Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp8x7_width 8
#define triangleUp8x7_height 7
static unsigned char triangleUp8x7_bits[] = {
   0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0xff, 0xff};
"
    image create bitmap darkLineUp$w -data "
#define darkLineUp8x7_width 8
#define darkLineUp8x7_height 7
static unsigned char darkLineUp8x7_bits[] = {
   0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x00};
"
    image create bitmap lightLineUp$w -data "
#define lightLineUp8x7_width 8
#define lightLineUp8x7_height 7
static unsigned char lightLineUp8x7_bits[] = {
   0x10, 0x30, 0x20, 0x60, 0x40, 0xc0, 0xff};
"
    image create bitmap triangleDn$w -data "
#define triangleDn8x7_width 8
#define triangleDn8x7_height 7
static unsigned char triangleDn8x7_bits[] = {
   0xff, 0xff, 0x7e, 0x7e, 0x3c, 0x3c, 0x18};
"
    image create bitmap darkLineDn$w -data "
#define darkLineDn8x7_width 8
#define darkLineDn8x7_height 7
static unsigned char darkLineDn8x7_bits[] = {
   0xff, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08};
"
    image create bitmap lightLineDn$w -data "
#define lightLineDn8x7_width 8
#define lightLineDn8x7_height 7
static unsigned char lightLineDn8x7_bits[] = {
   0x00, 0xc0, 0x40, 0x60, 0x20, 0x30, 0x10};
"
}

#------------------------------------------------------------------------------
# tablelist::sunken10x9Arrows
#------------------------------------------------------------------------------
proc tablelist::sunken10x9Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp10x9_width 10
#define triangleUp10x9_height 9
static unsigned char triangleUp10x9_bits[] = {
   0x30, 0x00, 0x78, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfe, 0x01,
   0xfe, 0x01, 0xff, 0x03, 0xff, 0x03};
"
    image create bitmap darkLineUp$w -data "
#define darkLineUp10x9_width 10
#define darkLineUp10x9_height 9
static unsigned char darkLineUp10x9_bits[] = {
   0x10, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x06, 0x00,
   0x02, 0x00, 0x03, 0x00, 0x00, 0x00};
"
    image create bitmap lightLineUp$w -data "
#define lightLineUp10x9_width 10
#define lightLineUp10x9_height 9
static unsigned char lightLineUp10x9_bits[] = {
   0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x80, 0x00, 0x80, 0x01,
   0x00, 0x01, 0x00, 0x03, 0xff, 0x03};
"
    image create bitmap triangleDn$w -data "
#define triangleDn10x9_width 10
#define triangleDn10x9_height 9
static unsigned char triangleDn10x9_bits[] = {
   0xff, 0x03, 0xff, 0x03, 0xfe, 0x01, 0xfe, 0x01, 0xfc, 0x00, 0xfc, 0x00,
   0x78, 0x00, 0x78, 0x00, 0x30, 0x00};
"
    image create bitmap darkLineDn$w -data "
#define darkLineDn10x9_width 10
#define darkLineDn10x9_height 9
static unsigned char darkLineDn10x9_bits[] = {
   0xff, 0x03, 0x03, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0c, 0x00,
   0x08, 0x00, 0x18, 0x00, 0x10, 0x00};
"
    image create bitmap lightLineDn$w -data "
#define lightLineDn10x9_width 10
#define lightLineDn10x9_height 9
static unsigned char lightLineDn10x9_bits[] = {
   0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0xc0, 0x00,
   0x40, 0x00, 0x60, 0x00, 0x20, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::sunken12x11Arrows
#------------------------------------------------------------------------------
proc tablelist::sunken12x11Arrows w {
    image create bitmap triangleUp$w -data "
#define triangleUp12x11_width 12
#define triangleUp12x11_height 11
static unsigned char triangleUp12x11_bits[] = {
   0x60, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf8, 0x01, 0xf8, 0x01, 0xfc, 0x03,
   0xfc, 0x03, 0xfe, 0x07, 0xfe, 0x07, 0xff, 0x0f, 0xff, 0x0f};
"
    image create bitmap darkLineUp$w -data "
#define darkLineUp12x11_width 12
#define darkLineUp12x11_height 11
static unsigned char darkLineUp12x11_bits[] = {
   0x20, 0x00, 0x30, 0x00, 0x10, 0x00, 0x18, 0x00, 0x08, 0x00, 0x0c, 0x00,
   0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00};
"
    image create bitmap lightLineUp$w -data "
#define lightLineUp12x11_width 12
#define lightLineUp12x11_height 11
static unsigned char lightLineUp12x11_bits[] = {
   0x40, 0x00, 0xc0, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x03,
   0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0c, 0xff, 0x0f};
"
    image create bitmap triangleDn$w -data "
#define triangleDn12x11_width 12
#define triangleDn12x11_height 11
static unsigned char triangleDn12x11_bits[] = {
   0xff, 0x0f, 0xff, 0x0f, 0xfe, 0x07, 0xfe, 0x07, 0xfc, 0x03, 0xfc, 0x03,
   0xf8, 0x01, 0xf8, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0x60, 0x00};
"
    image create bitmap darkLineDn$w -data "
#define darkLineDn12x11_width 12
#define darkLineDn12x11_height 11
static unsigned char darkLineDn12x11_bits[] = {
   0xff, 0x0f, 0x03, 0x00, 0x02, 0x00, 0x06, 0x00, 0x04, 0x00, 0x0c, 0x00,
   0x08, 0x00, 0x18, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00};
"
    image create bitmap lightLineDn$w -data "
#define lightLineDn12x11_width 12
#define lightLineDn12x11_height 11
static unsigned char lightLineDn12x11_bits[] = {
   0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x03,
   0x00, 0x01, 0x80, 0x01, 0x80, 0x00, 0xc0, 0x00, 0x40, 0x00};
"
}

#------------------------------------------------------------------------------
# tablelist::createSortRankImgs
#------------------------------------------------------------------------------
proc tablelist::createSortRankImgs win {
    image create bitmap sortRank1$win -data "
#define sortRank1_width 4
#define sortRank1_height 6
static unsigned char sortRank1_bits[] = {
   0x04, 0x06, 0x04, 0x04, 0x04, 0x04};
"
    image create bitmap sortRank2$win -data "
#define sortRank2_width 4
#define sortRank2_height 6
static unsigned char sortRank2_bits[] = {
   0x06, 0x09, 0x08, 0x04, 0x02, 0x0f};
"
    image create bitmap sortRank3$win -data "
#define sortRank3_width 4
#define sortRank3_height 6
static unsigned char sortRank3_bits[] = {
   0x0f, 0x08, 0x06, 0x08, 0x09, 0x06};
"
    image create bitmap sortRank4$win -data "
#define sortRank4_width 4
#define sortRank4_height 6
static unsigned char sortRank4_bits[] = {
   0x04, 0x06, 0x05, 0x0f, 0x04, 0x04};
"
    image create bitmap sortRank5$win -data "
#define sortRank5_width 4
#define sortRank5_height 6
static unsigned char sortRank5_bits[] = {
   0x0f, 0x01, 0x07, 0x08, 0x09, 0x06};
"
    image create bitmap sortRank6$win -data "
#define sortRank6_width 4
#define sortRank6_height 6
static unsigned char sortRank6_bits[] = {
   0x06, 0x01, 0x07, 0x09, 0x09, 0x06};
"
    image create bitmap sortRank7$win -data "
#define sortRank7_width 4
#define sortRank7_height 6
static unsigned char sortRank7_bits[] = {
   0x0f, 0x08, 0x04, 0x04, 0x02, 0x02};
"
    image create bitmap sortRank8$win -data "
#define sortRank8_width 4
#define sortRank8_height 6
static unsigned char sortRank8_bits[] = {
   0x06, 0x09, 0x06, 0x09, 0x09, 0x06};
"
    image create bitmap sortRank9$win -data "
#define sortRank9_width 4
#define sortRank9_height 6
static unsigned char sortRank9_bits[] = {
   0x06, 0x09, 0x09, 0x0e, 0x08, 0x06};
"
}

#------------------------------------------------------------------------------
# tablelist::createCheckbuttonImgs
#------------------------------------------------------------------------------
proc tablelist::createCheckbuttonImgs {} {
    variable checkedImg [image create bitmap tablelist_checkedImg -data "
#define checked_width 9
#define checked_height 9
static unsigned char checked_bits[] = {
   0x00, 0x00, 0x80, 0x00, 0xc0, 0x00, 0xe2, 0x00, 0x76, 0x00, 0x3e, 0x00,
   0x1c, 0x00, 0x08, 0x00, 0x00, 0x00};
"]

    variable uncheckedImg [image create bitmap tablelist_uncheckedImg -data "
#define unchecked_width 9
#define unchecked_height 9
static unsigned char unchecked_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
"]
}

#------------------------------------------------------------------------------
# tablelist::adwaitaTreeImgs
#------------------------------------------------------------------------------
proc tablelist::adwaitaTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel
		  collapsedAct expandedAct collapsedSelAct expandedSelAct} {
	variable adwaita_${mode}Img \
		 [image create photo tablelist_adwaita_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_adwaita_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhEt8bC0ZgAAAFtJREFUKM+d0rENwCAMRNFzBkoH
u2RCdiFD/fQo2MYnuXwCWycVAuhSMSu8Aa2Tgc3MnsqLktQzeLdjiL3juDi6ajezVoETeE/hBMbp
V120gyH6S6o5uzalSv4B4OI73QHvdNAAAAAASUVORK5CYII=
"
	tablelist_adwaita_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhYozpvWLgAAAGNJREFUKM/V0jEKgDAMheE/4mXE
VScv7OA1HATXnue5SMBqinRrIEvIB0kIVIQkOiqjIdgDIzD96D2B5FBSMrMBWArouPueo0ragL2A
1nDHAH+i13EyHCL/gjyBOai7oZ2XuwBMS0yU1CG3NAAAAABJRU5ErkJggg==
"
	tablelist_adwaita_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhQOLqAxUQAAAF9JREFUKM+d0rERACEIRNEPVV1u
PVfN1WNte4mRowIyY/hAmIWLkoRzWT51eiQxvxACDXjLE8fUFPbN8iH2w+WO2IOzt7F3DZpZB3oJ
DvSVvhqhJcyg1TFSydmlKRXyH4WQQgoBtm/BAAAAAElFTkSuQmCC
"
	tablelist_adwaita_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhkKnGOLBQAAAG9JREFUKM/V0jsKgDAQBNAZ8UIW
1mLrQSw9jKWnsLIUrHOnjI0EzQ9Jl4U02XmQJQsUlCQ0KKyKYCupBzD8yF4kjYMADIBO0pQSJM8n
Fzx1I3lk0JqbMcAp5D7TO7O1dpe0+L23iUFIGmP3H1jPyt3BlV+oCWAAJQAAAABJRU5ErkJggg==
"
	tablelist_adwaita_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhI7LklS9AAAAFtJREFUKM+d0kEKwDAIRNGxR+u2
JVcKvVLo/X73oVHjgMtHooxUCKBDxczwBDRPBl5m1isvSlLL4NWOIfaO4+Loqs3M7gocwLsLB/Ds
ftVFKxiiv6Sas2pTquQfhP08Qc94AdgAAAAASUVORK5CYII=
"
	tablelist_adwaita_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhctp+oT4AAAAG1JREFUKM/V0rENgCAQheEf41QW
DqCtw1hZWDmMlQUDULvTsyGoEYih45Jr4H0JlwMKShINhVURbIEeGH5kLeAClOSMMR0wZdDhc++n
StqAPYPW5IwJHEVhmc8GZuAElshdMB/oA2Pi/Ib1fLkL9HJfbH+7HUcAAAAASUVORK5CYII=
"
	tablelist_adwaita_collapsedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhUZtGiF1wAAAFxJREFUKM+d0ssNgCAQhOE/dGgB
xmBhcLDQ8eKJuC8m4fgtsBnYiCQam2nLpEMS6wkhcAGjfOOXnsHWH0PsLcfF0VY7cO7ACTxVOIG7
+lQXWTBEfx1MNcdqU6rkLw9FNonuw3sOAAAAAElFTkSuQmCC
"
	tablelist_adwaita_expandedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7CAAAOwgEVKEqAAAAAB3RJTUUH4AoJDhoT0yVwBgAAAFZJREFUKM/V0jEKwCAQRNFvyPVy
g+RWdmlzgxzwpwkioiJ2DmwxMK/boDKTjcksBHfgAM6B7QO8qamo0X7uf5cuL3EUlbCGq6gGc9xE
LYh69ZBKWOflPkhQ7kQX/0qBAAAAAElFTkSuQmCC
"
    } else {
	tablelist_adwaita_collapsedImg put "
R0lGODlhDgAOAMIGAAAAAHBwcJycnKampsrKytHR0f///////yH5BAEKAAcALAAAAAAOAA4AAAMf
eLrc/qvAJsZcItibNQ/g9nQgAZGi06Wqx7GPdM1KAgA7
"
	tablelist_adwaita_expandedImg put "
R0lGODlhDgAOAMIHAAAAAHBwcKCgoKenp6urq8rKytTU1P///yH5BAEKAAcALAAAAAAOAA4AAAMd
eLrc/jDKyYy4GBtGgv/B4HSg+JCh1JlSQb3wlAAAOw==
"
	tablelist_adwaita_collapsedSelImg put "
R0lGODlhDgAOAKECAAAAAP7+/v///////yH5BAEKAAMALAAAAAAOAA4AAAIcnI+pe8Ip3DMiyFft
zJrxrnBXGIBLNZ7pObVHAQA7
"
	tablelist_adwaita_expandedSelImg put "
R0lGODlhDgAOAKECAAAAAP7+/v///////yH5BAEKAAMALAAAAAAOAA4AAAIanI+py+2PhJxUxIBz
sEnozXgYF4IPCaUqUwAAOw==
"
	tablelist_adwaita_collapsedActImg put "
R0lGODlhDgAOAMIGAAAAADIyMnJycoCAgLOzs729vf///////yH5BAEKAAcALAAAAAAOAA4AAAMf
eLrc/qvAJsZcItibNQ/g9nQgAZGi06Wqx7GPdM1KAgA7
"
	tablelist_adwaita_expandedActImg put "
R0lGODlhDgAOAMIHAAAAADMzM3d3d4GBgYeHh7S0tMHBwf///yH5BAEKAAcALAAAAAAOAA4AAAMd
eLrc/jDKyYy4GBtGgv/B4HSg+JCh1JlSQb3wlAAAOw==
"
	tablelist_adwaita_collapsedSelActImg put "
R0lGODlhDgAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAOAA4AAAIYhI+pe8EZ3DNRvmoX
znAz/1WTOHLahB4FADs=
"
	tablelist_adwaita_expandedSelActImg put "
R0lGODlhDgAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAOAA4AAAIVhI+py+2Pgpw0xDoV
tqu6/HDQSDYFADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::ambianceTreeImgs
#------------------------------------------------------------------------------
proc tablelist::ambianceTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable ambiance_${mode}Img \
		 [image create photo tablelist_ambiance_${mode}Img]
    }

    tablelist_ambiance_collapsedImg put "
R0lGODlhEgAQAKUxAAAAADw7N9/Wxd/Wxt/WyODYyeLZyuHazeTdz+Pd0eTd0uXf0+Xf1efg1OXg
1ujh0+jg1Onj1+nj2Ork2O3m3Ozm3e7p4e/q4e7s5u/s6PHs5PHs5fHs5vHu6fPw6vTw6vTw6/bz
7vbz7/b07vb07/b08Pb08fj28/n49Pr59fr59vv5+Pv6+Pr6+vz6+fz7+v39/f//////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAahwJ9w
SCwWD4KkUnkwFjotmHQKa2UKxENmxXK5XmAva4VpCgWmEwqVSqna61NJMBSERKSSyRTYl0gjJHRn
Hx4dHiAgAYkeHh8fgz8CHJQcGhsBGxuVHJECFxcWAaOkAaAXnhUVFKoVAa2tnhMRErUSAbYRExOe
DxC/vwHAEA0PngoIycrLCAuRBwwG0tPUBg5mQgUJBAPd3gMECVhHS+XYQkEAOw==
"
    tablelist_ambiance_expandedImg put "
R0lGODlhEgAQAKUyAAAAADw7N9/Wxd/Wxt/WyODYyeLZyuHazeTdz+Pd0eTd0uXf0+Xf1efg1OXg
1ujh0+jg1Onj1+nj2Ork2O3m3Ozm3e7p4e/q4e7s5u/s6PHs5PHs5fHs5vHu6fPw6vTw6vTw6/bz
7vbz7/b07vb07/b08Pb08fj18fj28/n49Pr59fr59vv5+Pv6+Pr6+vz6+fz7+v39/f//////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAabwJ9w
SCwWD4KkUnkwFjqumHQac2UKxEOG1Xq9YGBvi4VpCgUmVCqlUq3aa1RJMBSERKSSyXTal0gjJHRn
Hx4dHiCJiR4eHx+DPwIckxwaGxwbl5SQAhcXFgGhogGeF5wVFRSoq6wVnBMRErKzshETE5wPELu8
vQ0PnAoIw8TFCAuQBwwGzM3OBg5mQgUJBAPX2AMECVhHS9/SQkEAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::aquaTreeImgs
#------------------------------------------------------------------------------
proc tablelist::aquaTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable aqua_${mode}Img \
		 [image create photo tablelist_aqua_${mode}Img]
    }

    variable pngSupported
    variable winSys
    scan $::tcl_platform(osVersion) "%d" majorOSVersion
    if {[string compare $winSys "aqua"] == 0 && $majorOSVersion > 10} {
	set osVerPost10 1
    } else {
	set osVerPost10 0
    }

    if {$pngSupported} {
	if {$osVerPost10} {
	    tablelist_aqua_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAhUlEQVQoz2NgGFaAmYGBgaG4uPih
lZXVvePHj98kxxBGqCH/ofxtDAwMub29vfdIMYQJje/FwMBwvbi4uIoSlyCDawwMDFm9vb0HSXUJ
MtBiYGA4UFxcHECJIdcYGBgcent7NxAyhAWL2C8GBobG3t7eNmLDBN0QsmIHZsgjqOZNQzvZAwA+
LCb4qKbYgQAAAABJRU5ErkJggg==
"
	    tablelist_aqua_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAiUlEQVQoz+2SsQkCQRREn3t9aO51
sKmZJtYhXDS5HUwzwtnCVqC5NmB+gZgui9wulwlO8vnMZ2b4/8MfJVaSHsB6ZuZpezMnEoChYjRU
kwBIGoH9F/5q+1ATCZnbVHBTSwqADiCl9IoxvoFdxp1tX5oWmzeSbsAWuNvuW68Tiv5U1GWQdPzd
j/0AfOEdPAaC2LoAAAAASUVORK5CYII=
"
	} else {
	    tablelist_aqua_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAe0lEQVQoz2NgGH6gra3tYVtbmx+5
+hmhhvyH8rcxMDDkVlVV3SPFECY0vhcDA8P1tra2KkpcggyuMTAwZFVVVR0k1SXIQIuBgeFAW1tb
ACWGXGNgYHCoqqraQMgQFixivxgYGBqrqqraiA0TdEPIih2YIY+gmjcN7RQPAIgqI+JZClM5AAAA
AElFTkSuQmCC
"
	    tablelist_aqua_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAfklEQVQoz+2SsQ2DUAxEX/4gpCeb
hCZzRGKB62huI7IJlJGSMajSJAhZiP9Fh5RrLPusO1s2/BFxsv0Cqo2et6TzlkgC2oxRm50EwHYP
XFf4h6QmJ5IWblPgppIpZhFJT6ALXPetU7TOD7YHoAZGSZfS66SQ30PcB9u3437sB9yMGwQuEm+e
AAAAAElFTkSuQmCC
"
	}

	tablelist_aqua_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAR0lEQVQoz2NgGH7g////N////+9I
qSEwsOT///8SlBry/////5/+//+fRakhMHD6////ppQaAgPOA+YSisOEotihPJ0MCgAABqWnCWRA
sV8AAAAASUVORK5CYII=
"
	tablelist_aqua_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAAT0lEQVQoz2NgGAUY4P///zf/4wc3
iTHEkYAhjsS6ZgkOA5aQ4iWJ////f0Iz4NP///8lSA2bLDRDssgN5NNQA05TElOmUENMKY1y56Gb
YAGl/KcJzjuWxQAAAABJRU5ErkJggg==
"
    } else {
	if {$osVerPost10} {
	    tablelist_aqua_collapsedImg put "
R0lGODlhEQAOAMIGAAAAAHNzc3Z2doODg4qKipubm////////yH5BAEKAAcALAAAAAARAA4AAAMf
eLrc/jC+IV0Ipa4bhD7cRVQhJ5XjeXnalX3UJ89OAgA7
"
	    tablelist_aqua_expandedImg put "
R0lGODlhEQAOAMIGAAAAAHNzc3Z2doODg4qKipubm////////yH5BAEKAAcALAAAAAARAA4AAAMf
eLrc/jDKqUa4OIyYsSxdMQmYQB3eSQTEqQRuLM9HAgA7
"
	} else {
	    tablelist_aqua_collapsedImg put "
R0lGODlhEQAOAMIGAAAAAIaGhoiIiJSUlJmZmampqf///////yH5BAEKAAcALAAAAAARAA4AAAMf
eLrc/jC+IV0Ipa4bhD7cRVQhJ5XjeXnalX3UJ89OAgA7
"
	    tablelist_aqua_expandedImg put "
R0lGODlhEQAOAMIGAAAAAIaGhoiIiJSUlJmZmampqf///////yH5BAEKAAcALAAAAAARAA4AAAMf
eLrc/jDKqUa4OIyYsSxdMQmYQB3eSQTEqQRuLM9HAgA7
"
	}

	tablelist_aqua_collapsedSelImg put "
R0lGODlhEQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAARAA4AAAIZhI+py73hVJjxTFrv
jXq3DjlaBXgZiaZLAQA7
"
	tablelist_aqua_expandedSelImg put "
R0lGODlhEQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAARAA4AAAIXhI+py+1vgpyz0Wpv
eBcCDIGhR5ZmUgAAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::arcTreeImgs
#------------------------------------------------------------------------------
proc tablelist::arcTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel
		  collapsedAct expandedAct collapsedSelAct expandedSelAct} {
	variable arc_${mode}Img \
		 [image create photo tablelist_arc_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_arc_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAGxJREFUKFONj0EKgDAMBPcVIl69iV7FF3hR/P9v4kYqSWlKGxhINh1IISIfrIms
/9zCGmAmD9n9gxr5AGxJPnweUQadchyaXD07DBXWRW4yhPswBM4kjdFeKYMOSckHk8LzPNYAC9F/
NSURwQtLqlH7qKJBUAAAAABJRU5ErkJggg==
"
	tablelist_arc_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAHRJREFUKFOdjUsKgDAMBbNwqzs/ZxHXFVG8/21i0iaaaECxMLSZl/IAEX8Ryi/w
aYkpChU6I+/dHDTESiQbmIUkee28hNzK4ezC8mkjButzdj4AOlnKzXzL3OuOxQ9X806ETcpTlOaF
CJuUWAJUkbeE8h2EA9B0S9ShJNYAAAAAAElFTkSuQmCC
"
	tablelist_arc_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAGdJREFUKFON0cEJgDAQRNH0YgfixSIsQgTLsBQbEC82OJmFRMa4xhzeYT/MaQOA
bKRZ7io9Jrpok/apDAs1jb3YNHYjrVQduzE56KRO2u0Vkp1sNEh78OLvyJQhj3ppLj3s+U0jACEC
E06wdZnzTFcAAAAASUVORK5CYII=
"
	tablelist_arc_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAHBJREFUKFOdzsEJgDAQRNHc7ELsQAQ7FCxD8OJFvNjgOiNu2IQBxcML5Ou6JjP7
RcYvePQwxyhMwPdy49HBAavHygJ83oaWf5Vf26Ee9qExtFu8cDhu9qHhuRfq4JtPkJucihzeQG5y
MkIjWkHGd5YueOiwF1W1TAUAAAAASUVORK5CYII=
"
	tablelist_arc_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAHNJREFUKFONz10KgCAQBOA5SheInnvvCkEdIuggPRdBd91m+2EVV1T4wB0dUIjI
g6un6Z9LbAMMdNESXsiJB2D+ymuYe9KgsuyHVs4+2w0V104HNe65GwIbndR55yoNKkoqHt6SPq8N
c49tgJH0X8WSiOAGGZpYKjZmcSEAAAAASUVORK5CYII=
"
	tablelist_arc_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAHRJREFUKFOdjUsKgDAMRLP0DHoDRTycCy+hLtxIwbvG6Sc21YBi4EH7JkOImX9h
yi/4acFkhQJm9Hs3Rw3YwaIDtTCnvC58CrsUrkUYSw4M2ofseuRyuIyRS73saMpPLh/AvCQ8RSxv
wLwk2JKosrzGlO8wnchaUd6BhPzVAAAAAElFTkSuQmCC
"
	tablelist_arc_collapsedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAG5JREFUKFONz8EJgDAQRNF0ZQtevNiIhYggVuLFjmxB8LbOQiKTOBoX3mG/LJhg
ZkkPE+2feBnAZwXuUhlm8Nmg/JZR8dexjLCAz+tvyxgdcEJD7fYI0Q5+1FHLqFg9cmVIRy01iZcR
/F3VIzMLF8edtpTOwib0AAAAAElFTkSuQmCC
"
	tablelist_arc_expandedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAKCAYAAACE2W/HAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAHJJREFUKFOdzsEJgDAQRNEUYCWCVYjgxY692It49CYIHtYZcWUTBhSFF8iXZZPM
7BcZv+DRwRSjMEIbG48Gdlg8Fmbg/zq056ncukE5zKEDhtAu8cLhuNk39fc9UwbfzE9ucipyeAW5
yckIlWgZGd9ZOgFo1rYdzDp3awAAAABJRU5ErkJggg==
"
    } else {
	tablelist_arc_collapsedImg put "
R0lGODlhDgAKAOMKAAAAALGxsbOzs7S0tLm5ucfHx8nJydPT09XV1eXl5f//////////////////
/////yH5BAEKAA8ALAAAAAAOAAoAAAQc8L10pL03GMxlKB33hZhGWoNwPoR6tit8IsMZAQA7
"
	tablelist_arc_expandedImg put "
R0lGODlhDgAKAOMJAAAAALGxsbOzs7S0tLa2tri4uLm5ucPDw8XFxf//////////////////////
/////yH5BAEKAA8ALAAAAAAOAAoAAAQd8MlJq73vXFSHqcZgDcVkCJjwnZg0BGgrEXJtTxEAOw==
"
	tablelist_arc_collapsedSelImg put "
R0lGODlhDgAKAKECAAAAAMzMzP///////yH5BAEKAAAALAAAAAAOAAoAAAIUBBKmu8hvHGRyqmox
1I/TZB3gVAAAOw==
"
	tablelist_arc_expandedSelImg put "
R0lGODlhDgAKAKECAAAAAMzMzP///////yH5BAEKAAAALAAAAAAOAAoAAAIUhI+pC7GOAjxSVXOt
y4+zyYSiUgAAOw==
"
	tablelist_arc_collapsedActImg put "
R0lGODlhDgAKAOMLAAAAAGNjY2ZmZmhoaGlpaXNzc4+Pj5KSkqenp6qqqsbGxv//////////////
/////yH5BAEKAA8ALAAAAAAOAAoAAAQc8D2FpL03HMxlMB33hZhGWsRwPoWwtq96JsQZAQA7
"
	tablelist_arc_expandedActImg put "
R0lGODlhDgAKAOMKAAAAAGNjY2ZmZmhoaG1tbXFxcXJycnNzc4iIiIyMjP//////////////////
/////yH5BAEKAA8ALAAAAAAOAAoAAAQd8MlJq70P3VSHqcdgDcV0CJj3hJg0BGgrEXJtTxEAOw==
"
	tablelist_arc_collapsedSelActImg put "
R0lGODlhDgAKAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAOAAoAAAIUBBKmu8hvHGRyqmox
1I/TZB3gVAAAOw==
"
	tablelist_arc_expandedSelActImg put "
R0lGODlhDgAKAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAOAAoAAAIUhI+pC7GOAjxSVXOt
y4+zyYSiUgAAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::baghiraTreeImgs
#------------------------------------------------------------------------------
proc tablelist::baghiraTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable baghira_${mode}Img \
		 [image create photo tablelist_baghira_${mode}Img]
    }

    tablelist_baghira_collapsedImg put "
R0lGODlhDQAIAIABAAAAAP///yH5BAEKAAEALAAAAAANAAgAAAIQjI8JyQHbzoNxUjajeXr3AgA7
"
    tablelist_baghira_expandedImg put "
R0lGODlhDQAIAIABAAAAAP///yH5BAEKAAEALAAAAAANAAgAAAIOjI+pywcPwYqSwWYqxgUAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor1TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor1_${mode}Img \
		 [image create photo tablelist_bicolor1_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor1_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwYtcCg47AAAACpJREFUGNNjYKAA1BOjiIlUTUyk
2sREqvOYSPUTPg2NpGhoJMVJjVSNBwD8+gSMwdvvHwAAAABJRU5ErkJggg==
"
	tablelist_bicolor1_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwkTNtE5iAAAAC9JREFUGNNjYBh0gJGBgaGeCHWN
yBoYCGhqRLeBAY+mRmxOYsChqZFYf9UPbLACACL9BIS+a6kZAAAAAElFTkSuQmCC
"
    } else {
	tablelist_bicolor1_collapsedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIUjI8IybB83INypmqjhGFzxxkZ
UgAAOw==
"
	tablelist_bicolor1_expandedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIQjI+py+D/EIxpNscMyLyHAgA7
"
    }

    tablelist_bicolor1_collapsedSelImg put "
R0lGODlhDAAKAIAAAP///////yH5BAEKAAEALAAAAAAMAAoAAAIUjI8IybB83INypmqjhGFzxxkZ
UgAAOw==
"
    tablelist_bicolor1_expandedSelImg put "
R0lGODlhDAAKAIAAAP///////yH5BAEKAAEALAAAAAAMAAoAAAIQjI+py+D/EIxpNscMyLyHAgA7
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor2TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor2_${mode}Img \
		 [image create photo tablelist_bicolor2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwwFv3J4nAAAADJJREFUKM9jYKASaCJWIRO5mpnI
tZmJXGczketnJnIDjBiNdeRorCPHqXXkBE4dzVIOAPKWBZkKDbb3AAAAAElFTkSuQmCC
"
	tablelist_bicolor2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEw4I8/VmowAAADZJREFUKM9jYBgygJGBgaGeBPWN
yBoZiNTciG4jAxGaG7E5lYGA5kZcfmTAo7mR1ECrZxg+AAC4iAWFJSdDXQAAAABJRU5ErkJggg==
"
    } else {
	tablelist_bicolor2_collapsedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIXjI9poA3c0IMxTOpuvS/yPVVW
J5KlWAAAOw==
"
	tablelist_bicolor2_expandedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIUjI+pywoPI0AyuspkC3Cb6YWi
WAAAOw==
"
    }

    tablelist_bicolor2_collapsedSelImg put "
R0lGODlhDgAMAIAAAP///////yH5BAEKAAEALAAAAAAOAAwAAAIXjI9poA3c0IMxTOpuvS/yPVVW
J5KlWAAAOw==
"
    tablelist_bicolor2_expandedSelImg put "
R0lGODlhDgAMAIAAAP///////yH5BAEKAAEALAAAAAAOAAwAAAIUjI+pywoPI0AyuspkC3Cb6YWi
WAAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor3TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor3TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor3_${mode}Img \
		 [image create photo tablelist_bicolor3_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor3_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExAQNNjBKgAAADtJREFUKM9jYKABqCdHExM1DGKi
houYqOE1JmqEERM1ApuJGrFGrCGNlBrSSKl3GikN2EZKo7iR7nkHAKniBpTspddsAAAAAElFTkSu
QmCC
"
	tablelist_bicolor3_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExIRcemTPgAAAD5JREFUKM/t0jsOACAIRMHnycne
3J6IgJa6PRN+8OMzADuok0doQlp1QgNSNA5FSLudUICULZYE0s3l7NGPnffUBoaD5FpzAAAAAElF
TkSuQmCC
"
    } else {
	tablelist_bicolor3_collapsedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIdjI+ZoH3AnIJRPmovznTL7jVg
5YBZ0J0opK4tqhYAOw==
"
	tablelist_bicolor3_expandedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIYjI+py+1vgJx0pooXtmy/CgVc
CITmiR4FADs=
"
    }

    tablelist_bicolor3_collapsedSelImg put "
R0lGODlhEQAOAIAAAP///////yH5BAEKAAEALAAAAAARAA4AAAIdjI+ZoH3AnIJRPmovznTL7jVg
5YBZ0J0opK4tqhYAOw==
"
    tablelist_bicolor3_expandedSelImg put "
R0lGODlhEQAOAIAAAP///////yH5BAEKAAEALAAAAAARAA4AAAIYjI+py+1vgJx0pooXtmy/CgVc
CITmiR4FADs=
"
}

#------------------------------------------------------------------------------
# tablelist::bicolor4TreeImgs
#------------------------------------------------------------------------------
proc tablelist::bicolor4TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable bicolor4_${mode}Img \
		 [image create photo tablelist_bicolor4_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_bicolor4_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExUCuhZEJwAAAEdJREFUOMu91IsNACAIQ0HSxU03
dwf1ZIBH6IeZz7NegSIXRF4QKVGkB5EmR6YoMqaRPTiBV8GrZKkytCqKVSWqqv8VmP/zDd6/CJzv
kRcqAAAAAElFTkSuQmCC
"
	tablelist_bicolor4_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExY6uTmvegAAAExJREFUOMvtlNsNACAIA8/JSTd3
ApWHfmjsAD1SCvD1lBpgG3w0MqcI0GxyCgCtYiEJkCdzEgB5F0oQoEhbCAAUrSJOgE7cgv13cI86
Y04IiOwcRtoAAAAASUVORK5CYII=
"
    } else {
	tablelist_bicolor4_collapsedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIojI+pCusL2pshSgotznoj23kV
GIkjeWFoSK1pi5qxDJpGbZ/5/cp5AQA7
"
	tablelist_bicolor4_expandedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIijI+py+0Po3Sg2ovrylyzjj2g
J3YTNxlhqpJsALzyTNdKAQA7
"
    }

    tablelist_bicolor4_collapsedSelImg put "
R0lGODlhFwASAIAAAP///////yH5BAEKAAEALAAAAAAXABIAAAIojI+pCusL2pshSgotznoj23kV
GIkjeWFoSK1pi5qxDJpGbZ/5/cp5AQA7
"
    tablelist_bicolor4_expandedSelImg put "
R0lGODlhFwASAIAAAP///////yH5BAEKAAEALAAAAAAXABIAAAIijI+py+0Po3Sg2ovrylyzjj2g
J3YTNxlhqpJsALzyTNdKAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::blueMentaTreeImgs
#------------------------------------------------------------------------------
proc tablelist::blueMentaTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel
		  collapsedAct expandedAct collapsedSelAct expandedSelAct} {
	variable blueMenta_${mode}Img \
		 [image create photo tablelist_blueMenta_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_blueMenta_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEJJREFUKFNj+P//P1EYwWBgEEeWQMcIBgNDMhBnIksiYwQDovASLsUIBkIhVsW4
FIKwGTEKiTKRKDcS5Ws84fifAQDpge0RK469/gAAAABJRU5ErkJggg==
"
	tablelist_blueMenta_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEtJREFUKFONjNEJACAIBZ3EKRqqvtq1hcwkDPMRBQd5HpKIfAElAkrEeqz0B2zh
rqsyAM0v+ifHHoXQhhOHyHZJEJXbmUcSAWVGaALoU+1uRfEIrwAAAABJRU5ErkJggg==
"
	tablelist_blueMenta_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAENJREFUKFNj+P//P1EYmSODxMbAyJwKIG5A4qNgZA5IIQhgVYzMgSkEAQzFyBxk
hSDgCMQEFRJlIlFuJMrXeMLxPwMAd106nOlvcTEAAAAASUVORK5CYII=
"
	tablelist_blueMenta_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAElJREFUKFNj+P//P1EYqyA2jFUQGwYRykDcjgeD5OEm1gIxNtAAxHATcSmGKwJh
ZIUgDFOMogiEUThQbI9FDKtCrBirICb+zwAAb6M7CAs6hmIAAAAASUVORK5CYII=
"
	tablelist_blueMenta_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEJJREFUKFNj+P//P1EYwWBgEEeWQMcIBgNDMhBnIksiYwQDovASLsUIBkIhVsW4
FIKwGTEKiTKRKDcS5Ws84fifAQDpge0RK469/gAAAABJRU5ErkJggg==
"
	tablelist_blueMenta_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEtJREFUKFONjNEJACAIBZ3EKRqqvtq1hcwkDPMRBQd5HpKIfAElAkrEeqz0B2zh
rqsyAM0v+ifHHoXQhhOHyHZJEJXbmUcSAWVGaALoU+1uRfEIrwAAAABJRU5ErkJggg==
"
	tablelist_blueMenta_collapsedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEJJREFUKFNj+P//P1EYwWBgEEeWQMcIBgNDMhBnIksiYwQDovASLsUIBkIhVsW4
FIKwGTEKiTKRKDcS5Ws84fifAQDpge0RK469/gAAAABJRU5ErkJggg==
"
	tablelist_blueMenta_expandedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEtJREFUKFONjNEJACAIBZ3EKRqqvtq1hcwkDPMRBQd5HpKIfAElAkrEeqz0B2zh
rqsyAM0v+ifHHoXQhhOHyHZJEJXbmUcSAWVGaALoU+1uRfEIrwAAAABJRU5ErkJggg==
"
    } else {
	tablelist_blueMenta_collapsedImg put "
R0lGODlhCgAKAMIFAAAAAC0tLZaWlpycnMnJyf///////////yH5BAEKAAcALAAAAAAKAAoAAAMU
eLrcfkM8GKQbod4cSMPaF37W5CQAOw==
"
	tablelist_blueMenta_expandedImg put "
R0lGODlhCgAKAKEDAAAAAC0tLZCQkP///yH5BAEKAAMALAAAAAAKAAoAAAIPnI+pe+IvUJhTURaY
3qwAADs=
"
	tablelist_blueMenta_collapsedSelImg put "
R0lGODlhCgAKAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAKAAoAAAIQhI+pELHcVotp0mPV
lO6tAgA7
"
	tablelist_blueMenta_expandedSelImg put "
R0lGODlhCgAKAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAKAAoAAAIOhI+pe+EfEIzpMcqy
VgUAOw==
"
	tablelist_blueMenta_collapsedActImg put "
R0lGODlhCgAKAMIFAAAAAC0tLZaWlpycnMnJyf///////////yH5BAEKAAcALAAAAAAKAAoAAAMU
eLrcfkM8GKQbod4cSMPaF37W5CQAOw==
"
	tablelist_blueMenta_expandedActImg put "
R0lGODlhCgAKAKEDAAAAAC0tLZCQkP///yH5BAEKAAMALAAAAAAKAAoAAAIPnI+pe+IvUJhTURaY
3qwAADs=
"
	tablelist_blueMenta_collapsedSelActImg put "
R0lGODlhCgAKAMIFAAAAAC0tLZaWlpycnMnJyf///////////yH5BAEKAAcALAAAAAAKAAoAAAMU
eLrcfkM8GKQbod4cSMPaF37W5CQAOw==
"
	tablelist_blueMenta_expandedSelActImg put "
R0lGODlhCgAKAKEDAAAAAC0tLZCQkP///yH5BAEKAAMALAAAAAAKAAoAAAIPnI+pe+IvUJhTURaY
3qwAADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::classic1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic1TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic1_${mode}Img \
		 [image create photo tablelist_classic1_${mode}Img]
    }

    tablelist_classic1_collapsedImg put "
R0lGODlhDAAKAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAMAAoAAAIgnI8Xy4EhohTOwAhk
HVfkuEHAOFKK9JkWqp0T+DQLUgAAOw==
"
    tablelist_classic1_expandedImg put "
R0lGODlhDAAKAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAMAAoAAAIcnI8Xy4EhohTOwBnr
uFhDAIKUgmVk6ZWj0ixIAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::classic2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic2TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic2_${mode}Img \
		 [image create photo tablelist_classic2_${mode}Img]
    }

    tablelist_classic2_collapsedImg put "
R0lGODlhDgAMAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOAAwAAAInnI8Zy4whopThQAlm
NTdmak1ftA0QgKZZ2QmjwIpaiM3chJdm0yAFADs=
"
    tablelist_classic2_expandedImg put "
R0lGODlhDgAMAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOAAwAAAIinI8Zy4whopThwDmr
uTjqwXUfBJQmIIwdZa1e66rx0zRIAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::classic3TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic3TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic3_${mode}Img \
		 [image create photo tablelist_classic3_${mode}Img]
    }

    tablelist_classic3_collapsedImg put "
R0lGODlhEQAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAARAA4AAAIwnI95we2Rgpi0Cris
xkZWYHGDR4GVSE4mharAC0/tFyKpsMq2lV+7dvoBdbbHI1EAADs=
"
    tablelist_classic3_expandedImg put "
R0lGODlhEQAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAARAA4AAAIrnI95we2Rgpi0Cris
xkbqyg3eN4UjaU7AygIlcn4p+Wb0Bd+4TYfi80gUAAA7
"
}

#------------------------------------------------------------------------------
# tablelist::classic4TreeImgs
#------------------------------------------------------------------------------
proc tablelist::classic4TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable classic4_${mode}Img \
		 [image create photo tablelist_classic4_${mode}Img]
    }

    tablelist_classic4_collapsedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAJGXI6pMe0hopxUMGeq
lvdpAGhdA1WgiGVmWI0qdbZpCbOUW4L6rkd4xAuyfisUhjaJ3WYf24RYM3qKsuNmA70+U4aF98At
AAA7
"
    tablelist_classic4_expandedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAI9XI6pMe0hopxUMGeq
lvft3TXQV4UZSZkjymEnG6kRQNc2HbvjzQM5toLJYD8P0aI7IoHKIdEpdBkW1IO0AAA7
"
}

#------------------------------------------------------------------------------
# tablelist::dustTreeImgs
#------------------------------------------------------------------------------
proc tablelist::dustTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable dust_${mode}Img \
		 [image create photo tablelist_dust_${mode}Img]
    }

    tablelist_dust_collapsedImg put "
R0lGODlhEgAQAKU0AAAAADIyMrConLGpncC6scC7ssG8s8K8tMK9tdDMxtDMx9LOyNrVztvVz9vW
ztvWz9vX0NzW0N3Y0d/a0uDd1uHe1+Lf2OPg2uTh2+Xj3efk3+jl4Ojm4enm4unn4+nn5Orn5evo
5Ovo5evq5ezp5e3q5u3q5+7s6O/t6e7t6vDu6/Hv7PHv7fLw7PLw7vT08vf39fj39fn49vn49///
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAakwJ9w
SCwSCQOBcrkcEIiGxQsWk82ushjspTgMB6zSCaVatVYq1GnkGgwFrE6IVDLZS6RQhyV4pzAZGhsc
ARwbGhkYKX1CAiYUFRYXFwGTFhUUJow/AiISnxITAROgEiKbAh0MEQGtrgEPDx2oHbEPDg8BDbay
qB68ucAevsCwvMNvIRHLzM0RIZsDHhDOzRAebkIHCiAi3t/fHwkIR0lMTAMFREEAOw==
"
    tablelist_dust_expandedImg put "
R0lGODlhEgAQAKU0AAAAADIyMrConLGpncS+tcS/tsbBuMfBucfCucfCutfTzdjUztnUz9vWztvW
z9vX0NzW0N3Y0d/a0t/a0+Dd1uHe1+Lf2OPg2uTh2+Xj3efk3+jl4Ojm4enm4unn4+vo5Ovo5evp
5uvq5ezp5e3q5u3q5+7s6O/t6e7t6vDu6/Hv7PLv7fLw7PHw7fLx7vX08vf39fj39fn49vn49///
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAagwJ9w
SCwSCQOBcrkcEIiGxQsWk82ushjspUAMBy2S6ZRSsVSpk0nkGgwFq85nRCrZSaNPZyV4ozAZGhsc
hBsaGRgofUICJRQVFhcXGJIWFRQliz8CIBGeERITEp8RIJoCHQsQAaytAQ4OHacdsA4NsAy1sace
ur6wHry/vsFvHxDIycoQH5oDHw/Lyg8fbkIHDCEg29zdCwlHSUxMAwVEQQA7
"
}

#------------------------------------------------------------------------------
# tablelist::dustSandTreeImgs
#------------------------------------------------------------------------------
proc tablelist::dustSandTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable dustSand_${mode}Img \
		 [image create photo tablelist_dustSand_${mode}Img]
    }

    tablelist_dustSand_collapsedImg put "
R0lGODlhEgAQAKU1AAAAADIyMpuWjJyXjrSxqbWxqre0rbi1rrm2r8K+tsO+t8TAuMXBusbCu8nF
vcnGvsrHv8vHwMnGwcrIwczIwMzIwc3Jw87LxMzKxc/MxdDMxdDMx9HOx9HOyNLPydPPytPQydPQ
y9TRy9TRzNXTzNXSzdfTztbUzNbUzdfVz9nV0NjW0NnW0drY097c2eDe2eXi3uXj3+jm4+nn5Oro
5f///////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAajwJ9w
SCwSCQOBcrkcEIiGCUwmm81oVmpMchgOXqWSSbVirVSm0ug1GApcm85HNKqLPp2NS+BuVSwXGRoB
GhkXFhUtfEICKQ4PEBEUARQREA8OKYs/AiEMnwwNAQ2gDCGbAhwJCgGtrgEKChyoHLGxCQGrtrNu
tbasv7KoHcGwvx2oHgvLzM0LHpsDJc7UJG1CBxgoINzd3ScYCEQFSUxMAwVEQQA7
"
    tablelist_dustSand_expandedImg put "
R0lGODlhEgAQAKU3AAAAADIyMpuWjJyXjrSxqbWxqre0rbi1rrm2r8K+tsO+t8TAuMXBusbCu8bC
vMnFvcnGvsrHv8vHwMnGwcrIwczIwMzIwc3Jw87LxMzKxc/Mxc/MxtDMxdDMx9HOx9HOyNLPydPP
ytPQydPQy9TRy9TRzNXTzNXSzdfTztbUzNbUzdfVz9nV0NjW0NnW0drY097c2eDe2eXi3uXj3+jm
4+nn5Oro5f///////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAagwJ9w
SCwSCQOBcrkcEIgGioxGq9VsVupschgOYqcTitVytVioUyk2GApgnU+IVKqTQp8OTOB+WS4YGhwb
HBoYFxYvfEICKw8QERIVFhUSERAPK4s/AiMMnwwNDg2gDCObAh4JCgGtrgEKCh6oHrGxCbi2srS6
vbGzbh++vR+oIAvIycoLIJsDJ8vRJm1CBxkqItna2ikZCEQFSUxMAwVEQQA7
"
}

#------------------------------------------------------------------------------
# tablelist::gtkTreeImgs
#------------------------------------------------------------------------------
proc tablelist::gtkTreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable gtk_${mode}Img \
		 [image create photo tablelist_gtk_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_gtk_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAUUlEQVQoz8XTwQ2AQAhE0T17+jVQ
h/XRGIV9L5p4FsxSwAuZgbV+nHNEARzBACOijwFWVR8DVPvYA7WxN6Samd4FHHs3GslorLWxO5p6
k0/IBbP6VlQP0oOsAAAAAElFTkSuQmCC
"
	tablelist_gtk_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAW0lEQVQoz+3SwQmAQAxE0fHqKTVM
HWt7aWwsKB3Ek4IQYXVBEPzXkJdLgL/XmgA0M1PvQkQsANareSOZkrJKUpJMAK3nWIndRUrsKXLC
3H0IOTAzG0b25m8/5Aai703YBhwgYAAAAABJRU5ErkJggg==
"
	tablelist_gtk_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAa0lEQVQoz7XSMQqAMAyF4d9OAZeM
OYyeXg/TMZN0qwdQKyltxjz4CI/AxNmGKKpah2CqWs0sjKW3ZSkFMzsiWPoKolhqhRFs+Sj7Me6+
AlfXRQAigrvvLeQXEhFyzjtwdncUQYb+0bzP7kVuCWMmCi7K2XoAAAAASUVORK5CYII=
"
	tablelist_gtk_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABIAAAAOCAYAAAAi2ky3AAAAXUlEQVQoz2NgGAV0A4wMDAyZAgIC
04jV8OHDhywGBobp6OLMDAwMZ378+PGKg4PDm1xDYAYxEGMYPkOwgUwBAYH/6JiBgSGTnHCDG6ak
pES2ISiGUWoIDIgM7QQJACRKJBMon0pJAAAAAElFTkSuQmCC
"
    } else {
	tablelist_gtk_collapsedImg put "
R0lGODlhEgAOAMIFAAAAABAQECIiIoaGhsPDw////////////yH5BAEKAAcALAAAAAASAA4AAAMi
eLrc/pCFCIOgLpCLVyhbp3wgh5HFMJ1FKX7hG7/mK95MAgA7
"
	tablelist_gtk_expandedImg put "
R0lGODlhEgAOAMIFAAAAABAQECIiIoaGhsPDw////////////yH5BAEKAAcALAAAAAASAA4AAAMg
eLrc/jDKSWu4OAcoSPkfIUgdKFLlWQnDWCnbK8+0kgAAOw==
"
	tablelist_gtk_collapsedActImg put "
R0lGODlhEgAOAKEDAAAAABAQEBgYGP///yH5BAEKAAMALAAAAAASAA4AAAIdnI+pyxjNgoAqSOrs
xMNq7nlYuFFeaV5ch47raxQAOw==
"
	tablelist_gtk_expandedActImg put "
R0lGODlhEgAOAKEDAAAAABAQECIiIv///yH5BAEKAAMALAAAAAASAA4AAAIYnI+py+0PY5i0Bmar
y/fZOEwCaHTkiZIFADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::klearlooksTreeImgs
#------------------------------------------------------------------------------
proc tablelist::klearlooksTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable klearlooks_${mode}Img \
		 [image create photo tablelist_klearlooks_${mode}Img]
    }

    tablelist_klearlooks_collapsedImg put "
R0lGODlhDQAIAIABAAAAAP///yH5BAEKAAEALAAAAAANAAgAAAIPjI8IkL3c1IoSxkcDzjMXADs=
"
    tablelist_klearlooks_expandedImg put "
R0lGODlhDQAIAIABAAAAAP///yH5BAEKAAEALAAAAAANAAgAAAIRjI+pCXCtmpNLwhUoNm57UwAA
Ow==
"
}

#------------------------------------------------------------------------------
# tablelist::mateTreeImgs
#------------------------------------------------------------------------------
proc tablelist::mateTreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable mate_${mode}Img \
		 [image create photo tablelist_mate_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_mate_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAeUlEQVQoz83RLQ7CUBRE4S+vFQQM
Eo/DlB10Y0gEEnwXQMIq2AChFeygSWUNHtOahv4ISDpmMsk9yUwus9Vm6mHU+BVLPMaA0PgKKW5I
pgDwQokjTn01QyfXKLDH5RsUd/IaWzxxRjUE7LDAAXnfhhZ4447s53/4vz4ZeA6wL/7UqwAAAABJ
RU5ErkJggg==
"
	tablelist_mate_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAf0lEQVQoz9XRMQrCYAyG4ccWtdC1
8l/B1at4Cg/iIXqBTr2BOLq4dnEQXJxcnHR3iVBKh64NhDd84UsgYf6xQEKNcqT/xQGvv5CHuMQG
VzwiC5xw6U/IgmesUIW5whrtcGUe/OCOPd7Y4ojn0JD16g437ILdlCMkNMHJkWb26R+bgxLSbl4O
9wAAAABJRU5ErkJggg==
"
	tablelist_mate_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAdElEQVQoz83RsQ2CUBQF0AORhoZO
XcHEbZjDECYxhDlMXMDOERxC6WxsbGgwMQTjp/gJt3mveKe4eSw227ngijbkMB3mGztcUIYAeOCF
Gmfs/wED6FCgmeo2BjnWeKLCfQxWX/sGCY44/erwARluOET7Q7z0AZUOkqtBUcIAAAAASUVORK5C
YII=
"
	tablelist_mate_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAa0lEQVQoz9XRQQqDUAwE0Ke1Z/A2
f+mid/B0nsCFm55I8QBuWnCTDx/BYpcOhGRgYJIJ90eFFsMPTY8lkzrIHHwrCtZSnB0y3vjigwYP
dEe7upjHEFXRx7MbSkx4hsvrSggpVkv/JNfe7NM710YQSDbaCJ8AAAAASUVORK5CYII=
"
    } else {
	tablelist_mate_collapsedImg put "
R0lGODlhDAAOAOMOAAAAAEBAQEdHR0tLS0xMTFRUVFZWVlxcXG9vb3d3d3p6en9/f4aGhpubm///
/////yH5BAEKAA8ALAAAAAAMAA4AAAQe8MlJq70409F0OEUWMAiRXOOiCIY1lqcLZpxm33cEADs=
"
	tablelist_mate_expandedImg put "
R0lGODlhDAAOAIQQAAAAAEVFRUxMTFBQUFFRUVhYWFlZWVpaWl9fX3V1dXp6en19fYSEhImJiZ6e
nqOjo////////////////////////////////////////////////////////////////yH5BAEK
AAAALAAAAAAMAA4AAAUkICCOZGmeaEoOQdsO5YM0NOKYRsIkBUoshJRCoFAdVMikMhUCADs=
"
	tablelist_mate_collapsedActImg put "
R0lGODlhDAAOAOMLAAAAADs7O0BAQEJCQkNDQ0xMTE9PT1FRUVZWVlpaWmxsbP//////////////
/////yH5BAEKAA8ALAAAAAAMAA4AAAQf8MlJq70406C0IEMmJEVgXCNyCGE1lqf1tRen3TgeAQA7
"
	tablelist_mate_expandedActImg put "
R0lGODlhDAAOAOMKAAAAAEVFRUhISElJSUpKSktLS0xMTE5OTlpaWl1dXf//////////////////
/////yH5BAEKAA8ALAAAAAAMAA4AAAQf8MlJq70408B7qElwjAFiBYIhfFdQsBcRDBqs3XhuRQA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::mentaTreeImgs
#------------------------------------------------------------------------------
proc tablelist::mentaTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable menta_${mode}Img \
		 [image create photo tablelist_menta_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_menta_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEJJREFUKFNj+P//P1EYwWBgEEeWQMcIBgNDMhBnIksiYwQDovASLsUIBkIhVsW4
FIKwGTEKiTKRKDcS5Ws84fifAQDpge0RK469/gAAAABJRU5ErkJggg==
"
	tablelist_menta_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAEtJREFUKFONjNEJACAIBZ3EKRqqvtq1hcwkDPMRBQd5HpKIfAElAkrEeqz0B2zh
rqsyAM0v+ifHHoXQhhOHyHZJEJXbmUcSAWVGaALoU+1uRfEIrwAAAABJRU5ErkJggg==
"
    } else {
	tablelist_menta_collapsedImg put "
R0lGODlhCgAKAMIFAAAAAC0tLZaWlpycnMnJyf///////////yH5BAEKAAcALAAAAAAKAAoAAAMU
eLrcfkM8GKQbod4cSMPaF37W5CQAOw==
"
	tablelist_menta_expandedImg put "
R0lGODlhCgAKAKEDAAAAAC0tLZCQkP///yH5BAEKAAMALAAAAAAKAAoAAAIPnI+pe+IvUJhTURaY
3qwAADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::mintTreeImgs
#------------------------------------------------------------------------------
proc tablelist::mintTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable mint_${mode}Img \
		 [image create photo tablelist_mint_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_mint_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAU0lEQVQoz73RQQ2AMAwF0JfdZodg
AhEo44gITBAkYGNXDIxmCwv/2PQ1acvf2XrBjT1qSJXaFKEayBFKL4MyZhytoGsHKDixtICCC+uQ
s35+3Pg8G2gLGrFw1rcAAAAASUVORK5CYII=
"
	tablelist_mint_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAVUlEQVQoz+XRsQmAMBRF0SM6gQOl
dgwLB3OWLGCXMuAWljYKQRTTihd+8/591eOHNAiYK9wRscWKBQO6G3HDhHh9BCTk4tKRP1KWXuWy
lGvlk/5Dw+18fA9T93dmqwAAAABJRU5ErkJggg==
"
	tablelist_mint_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAATUlEQVQoz2NgoCv4////PFI1vPj/
//9yfGqYsIhZ4NOETQMnPk1MOAyCadpHrAaS/MDAwMDwnYGB4QQjI6MTMaF0n1BIkRSslEUcTQAA
5D0vedmcvmEAAAAASUVORK5CYII=
"
	tablelist_mint_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAVUlEQVQoz+WRwQnAIBAEdwPpyTIs
NWXYhV878Dn5JGAkEb+ShfssM3Cw0g9jIEg6JthoO222k6QoqX6A9YYfLRCADJTm8vXBezppDHdS
mYIbaV9ouBPWj0JRP45ECQAAAABJRU5ErkJggg==
"
    } else {
	tablelist_mint_collapsedImg put "
R0lGODlhDAAOAMIHAAAAACEhISgoKCoqKkhISFxcXGRkZP///yH5BAEKAAcALAAAAAAMAA4AAAMd
eLrc7uaxUKQKo8qAteOBQDygSHZbZlHWEbVwmwAAOw==
"
	tablelist_mint_expandedImg put "
R0lGODlhDAAOAKEDAAAAACEhISkpKf///yH5BAEKAAMALAAAAAAMAA4AAAIWnI+py+0aopRIzCCU
jXnZzgTPSJZIAQA7
"
	tablelist_mint_collapsedSelImg put "
R0lGODlhDAAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAMAA4AAAIXhI+pGovRHIBx0Zou
PtpS94FbJpWmUQAAOw==
"
	tablelist_mint_expandedSelImg put "
R0lGODlhDAAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAMAA4AAAIRhI+py+0aopRo0mTZ
1a/7jxQAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::mint2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::mint2TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable mint2_${mode}Img \
		 [image create photo tablelist_mint2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_mint2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADr4AAA6+AepCscAAAAAHdElNRQfgBQkTHSnMxpiBAAAAGnRFWHRTb2Z0
d2FyZQBQYWludC5ORVQgdjMuNS4xMDD0cqEAAABRSURBVChTpZGxCQAgDAR/fkdwMitXiYqFPsRE
Y3HFPRwEhYg8o44eLEDa/QQLUDt53zRYZlS8kGVGbsiyIjNk+Yyezws9hBkMWCKfe4s62gga8dTd
YGVViS0AAAAASUVORK5CYII=
"
	tablelist_mint2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOvgAADr4B6kKxwAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAYklE
QVQoU5XLQQqAMAxE0ZzBW/T+lxDciK49S5rUGiidZrDwFh3yRVV/gyMDRwaODBwZf8Wc5klcpkTU
Sw8Pg4LbRBBREk5Bux0+YwiDdjcNb7ivAodHkQ3tHzgycGTgmFOpl2jLGnIdx90AAAAASUVORK5C
YII=
"
	tablelist_mint2_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOvAAADrwBlbxySQAAAAd0SU1FB+AFCRMdKczGmIEAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAFVJREFUKFOlkDEKwDAMA/N7736If+dZjYcOAlPF6XCEEzkIWQDGtKOC
xN33wRc6SMwMJyFJRREhQ5KKMlOGJG+kQpJf0fh5Vx+hgoLkJCjaUdGO32A9XVwfc0mdLjYAAAAA
SUVORK5CYII=
"
	tablelist_mint2_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOvQAADr0BR/uQrQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAW0lE
QVQoU5XLwQ3AIAxDUbbPjckyRJbIOcg9VG1xsHp4SHzwqKrfaFRoVGhUaFSuY85ZZtbC+zYCPERE
ZeYN9+8AXpfnsBvAFvDR3dsB0HgaAI0KjQqNCo1nNRZ9ViCcGRAOXQAAAABJRU5ErkJggg==
"
    } else {
	tablelist_mint2_collapsedImg put "
R0lGODlhDQAOAMIFAAAAACEhIScnJ2VlZXV1df///////////yH5BAEKAAcALAAAAAANAA4AAAMc
eLrc/odAFsZUQdgZ8n6dB4XaKI4l90HS5b5HAgA7
"
	tablelist_mint2_expandedImg put "
R0lGODlhDQAOAMIHAAAAACIiIiwsLC0tLS8vLzQ0NDc3N////yH5BAEKAAcALAAAAAANAA4AAAMZ
eLrc/jDKSYK9YbSCg3ic9UHcGBlTqq5RAgA7
"
	tablelist_mint2_collapsedSelImg put "
R0lGODlhDQAOAMIFAAAAAIeHh5KSkq6urvX19f///////////yH5BAEKAAcALAAAAAANAA4AAAMd
eLrc/kdAFuQ8YVgYiJ6dtzXh93TmmZ7j017wlAAAOw==
"
	tablelist_mint2_expandedSelImg put "
R0lGODlhDQAOAMIGAAAAAIeHh46OjszMzODg4PX19f///////yH5BAEKAAcALAAAAAANAA4AAAMa
eLrc/jDKKYK9QTRBiieawxVgJAyhOa1sGyUAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::newWaveTreeImgs
#------------------------------------------------------------------------------
proc tablelist::newWaveTreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable newWave_${mode}Img \
		 [image create photo tablelist_newWave_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_newWave_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAABCUlEQVQoz8WSP0vEQBTE561h0SL2
FgFTZHGrlNY2FvJ6K/Ej2F6hvVjZChZWfgCzJ3YBOxftZSFwrRGuEJKT/LVKIQiXs7lpB37Mm3nA
ukXMvA3giogukiT5XBWwoZTaaprmtm3bE621UEq9Oee6sQABAHVd52maXud5ftD3/SszH60EIKK6
qqoPa+29tfamKIoJM0+ZeW/MCZtd151mWfYAYFGW5Xw2mz0LIb5837/UWiul1Itz7vsvgDckADD/
ZXheQURLu/AAQAjRDIAoinbCMJxIKQWAY2PM+1IAEdVBECy01mdSykMA58aYxzElDgl24zh+AnAH
YN8YU49dwQPQAZj+95HWrx8slWOLxRjWjwAAAABJRU5ErkJggg==
"
	tablelist_newWave_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAABBklEQVQoz9VSPUsDQRB9c7dedeSK
LW7/QLgjbHuV3RUiuD/AJtraWdgFUqS1lPwBA4KN3VjaXe0P2NYrrtAELBT2DrFJIITNRyU4MDBv
5s2D+QD+vZExpgcg2MP7YeZPX0EAuO267tw59+EjRFEkhRCPAK68AkQ0BnBSVdWdc67daD4qy/J6
yfFaaK39yvM8SJLkuK7rVwDfKy+K4jSO4ydmftkmsJp9KqXsK6VCAHMAc6VUKKXsA5juWk4AAMzc
EtFIaz0EsACw0FoPiWjEzO3OK6wDY8xz0zT3AKCUumTms31nFBv4Jk3T2TK+OOQPwnVgrX3PsmxA
RG/M/HCIgPDkJn/6yr/4D0fVv4huoQAAAABJRU5ErkJggg==
"
	tablelist_newWave_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAABEElEQVQoz9XRsUoDURAF0DvZl8QQ
iYquy75tLaxsZjv/wMJSEC39AnvBzlIEwc5a/IB0NoKFmGmsRKx3MQGjEkR8u28sRLCRbCrxtsMc
LjPAXydI07QTx/GRtfY6z/O3iQFrbatdw1mTsLMQW5ckiWRZ5qsCNQDoBCi25v172tZ9A71l5rWJ
ABB0qk7F6gyG24s6vdTCOTN3mXm5EkAEDQyVgaFyrkkf6yEeNyKshA3cMPMhM8/+BpjvBoGh4ueA
HOqA6rgG5mufYEytBIBnp+ZioNH9SK8A7IrI3VgABPUBlZd9H/aG/sl5bIpIt8oRDQC8OG2cPJTR
q9MDIjoW6bmqXzAA/KjAKaB7IjLAv8snuPFdR0oRvJ0AAAAASUVORK5CYII=
"
	tablelist_newWave_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAABDklEQVQoz9VSPUsDQRB9b/fuhKAn
gRA5q/yIq+0s7fwJFtYhbUCxs05pK/4IsbhOcBdNbWOVBUlhDu5E93JjFVC5fFSCAwPz5j0ew8wA
/z6YpmkMQK3R1caYvIkIROSypXASK5k3CfKauqxxBeC00QDAUAHHR3H9GfAnWQlw86YjAMNlo2nn
XNlJ9r3SPOy1WGrNepEP79x5+eCFtfZumYECAJKjccFJSUoQsgpCViUp44ITkqNVy1EAYIzxXjDI
ZmyHkfJhpHw2Y9sLBsYYv8pALwrn3PNWJznobbObz6GzqTxaa8/WnTH4hfu3r3IPAAL0N/kD/R04
56a73WSvqPBkrb3exCBo6J3/6St/AbNWYeq4QB0rAAAAAElFTkSuQmCC
"
    } else {
	tablelist_newWave_collapsedImg put "
R0lGODlhEAAOAIQdAAAAAFJSUl5eXl9fX2JiYmZmZmdnZ2lpaWtra2xsbG5ubnBwcHJycnR0dH19
fX9/f5KSkpSUlJqampycnJ2dnaGhoaenp6ysrLm5ucvLy8zMzN3d3ejo6P///////////yH5BAEK
AB8ALAAAAAAQAA4AAAU44CeOZGmeZYSegbCWAsQgr0hYFqU8r4H9mEpBgkJkjpnLgXhabDYaB2/V
4EwUtc8gkRWpuuDwKAQAOw==
"
	tablelist_newWave_expandedImg put "
R0lGODlhEAAOAIQSAAAAAFJSUltbW19fX2xsbHBwcHh4eHl5eX9/f5KSkpSUlJWVlZqamqenp6ys
rLm5ubq6usrKyv///////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAQAA4AAAU04CeOZGmeaKqmSiC8cKCcQ7LcSzKkR+M3BxXB8Xg4CCtDJGJYfRAQCML5
KRSoHwYDy6WGAAA7
"
	tablelist_newWave_collapsedActImg put "
R0lGODlhEAAOAKUgAAAAAEA3NUI6N1A9OFE/OVNAOlNCO1BCPFFDPVRCO1VEPF5EO2JJP29IPU1E
QlBIRFdTU1dVU3lWR21tbZVdSJ9dSJdgS6RbRq1iSqpsUrFoTrRuUrlzVrh4WYWFhYyMjP//////
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAAAALAAAAAAQAA4AAAY8QIBw
SCwaj0UP8hhwLIuDSwPyFBIwmMpi8ixovhrK4YM0bM4bC4J8THA4GQZ3qehIIlWA4JEXKvuAgUNB
ADs=
"
	tablelist_newWave_expandedActImg put "
R0lGODlhEAAOAIQSAAAAAD83NU87NlNGP2FIP29KPk1EQldUU21tbZ1oT6JXRKVYRKNiS6xhSrFo
TrdwU4WFhYyMjP///////////////////////////////////////////////////////yH5BAEK
AB8ALAAAAAAQAA4AAAU04CeOZGmeaKqmUCC8cACdhrLci2KkReM3BdWB4XAwDivC40FYfRCJBML5
GQyon0gEy6WGAAA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::oxygen1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::oxygen1TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable oxygen1_${mode}Img \
		 [image create photo tablelist_oxygen1_${mode}Img]
    }

    tablelist_oxygen1_collapsedImg put "
R0lGODlhDwAGAKECAAAAABQTEv///////yH5BAEKAAAALAAAAAAPAAYAAAINhI95oQ3sVpgwPouq
KwA7
"
    tablelist_oxygen1_expandedImg put "
R0lGODlhDwAGAKECAAAAABQTEv///////yH5BAEKAAAALAAAAAAPAAYAAAIKhI+pyw0BoZtUFQA7
"
}

#------------------------------------------------------------------------------
# tablelist::oxygen2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::oxygen2TreeImgs {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable oxygen2_${mode}Img \
		 [image create photo tablelist_oxygen2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_oxygen2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA8AAAAICAYAAAAm06XyAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AsDFBwlCamtawAAAFVJREFUGNOtzbENQFAYReEv0UgM
YgEVlUQjEttYRfEqu1hBDKCxhuYt8L84za3OPfzAhDUqVXlb7GhwltQ7XDjySZgBL7ao2ONGQh0R
FzwlRRgxR6UPRPkJSYt8DiIAAAAASUVORK5CYII=
"
	tablelist_oxygen2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA8AAAAICAYAAAAm06XyAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AsDFB8qsjvjOQAAAFJJREFUGNPF0CsKgEAABNAXF7yO
aU2CZRG8jcmbmDyU2LV4Dcsm02rQaTMwzIc/0aK/aQldiTnhQMy8xo6hNH3EhgYrpqf1Z5xY3mwP
uUH1ydMXx2UJYO9Vo0sAAAAASUVORK5CYII=
"
	tablelist_oxygen2_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA8AAAAICAYAAAAm06XyAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AsDFB4pMimDwgAAAHZJREFUGNOlkC0Og2AQRN82cJ9P
VKFJECScYR1J0SiOgcTsHRBcArFn6B1auzWIym46ZtTL/MC/Uo9WPYYsd7u8Blb1WDKwfKXfAQNO
YLIir1+TsSInMAId8MjURj0aYAN2YM0c1qvHUz3mzObq8jcwWpEjA38Arr8gUfq42wkAAAAASUVO
RK5CYII=
"
	tablelist_oxygen2_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA8AAAAICAYAAAAm06XyAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AsDFCA0EOr0ZgAAAHJJREFUGNPF0C0OwkAQBtC3BEE4
TQUKR4IhpHeYCiyOI3AF/lQdZ+gt1nOYxawgmFbBqMmXvEm+4W8TuWwil/1XtotctmN2hgWukcu6
whVuWI7hVMEJHQ6449k36TwJ1wMPtBj6JsWUyvOP/YgXLj959hvQPxzKCnzYTQAAAABJRU5ErkJg
gg==
"
    } else {
	tablelist_oxygen2_collapsedImg put "
R0lGODlhDwAIAIABAAAAAP///yH5BAEKAAEALAAAAAAPAAgAAAIQjI8ZAOrcXIJysmoo1jviAgA7
"
	tablelist_oxygen2_expandedImg put "
R0lGODlhDwAIAIABAAAAAP///yH5BAEKAAEALAAAAAAPAAgAAAIRjI+pawDnmHuThRntzfr2fxQA
Ow==
"
	tablelist_oxygen2_collapsedActImg put "
R0lGODlhDwAIAKECAAAAAGDQ/////////yH5BAEKAAAALAAAAAAPAAgAAAIQhI8JEercXIJysmoo
1jviAgA7
"
	tablelist_oxygen2_expandedActImg put "
R0lGODlhDwAIAKECAAAAAGDQ/////////yH5BAEKAAAALAAAAAAPAAgAAAIRhI+paxHnmHuTgRnt
zfr2fxQAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::phaseTreeImgs
#------------------------------------------------------------------------------
proc tablelist::phaseTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable phase_${mode}Img \
		 [image create photo tablelist_phase_${mode}Img]
    }

    tablelist_phase_collapsedImg put "
R0lGODlhDwAKAKECAAAAAMfHx////////yH5BAEKAAAALAAAAAAPAAoAAAIUhI9poQ3BHIJRPmov
lrS6bUHZMhYAOw==
"
    tablelist_phase_expandedImg put "
R0lGODlhDwAKAKECAAAAAMfHx////////yH5BAEKAAAALAAAAAAPAAoAAAIRhI+pyx0P4YqS0WYq
BmH7jxQAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::plain1TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain1TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain1_${mode}Img \
		 [image create photo tablelist_plain1_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain1_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwYtcCg47AAAACpJREFUGNNjYKAA1BOjiIlUTUyk
2sREqvOYSPUTPg2NpGhoJMVJjVSNBwD8+gSMwdvvHwAAAABJRU5ErkJggg==
"
	tablelist_plain1_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwkTNtE5iAAAAC9JREFUGNNjYBh0gJGBgaGeCHWN
yBoYCGhqRLeBAY+mRmxOYsChqZFYf9UPbLACACL9BIS+a6kZAAAAAElFTkSuQmCC
"
    } else {
	tablelist_plain1_collapsedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIUjI8IybB83INypmqjhGFzxxkZ
UgAAOw==
"
	tablelist_plain1_expandedImg put "
R0lGODlhDAAKAIABAH9/f////yH5BAEKAAEALAAAAAAMAAoAAAIQjI+py+D/EIxpNscMyLyHAgA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plain2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain2TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain2_${mode}Img \
		 [image create photo tablelist_plain2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEwwFv3J4nAAAADJJREFUKM9jYKASaCJWIRO5mpnI
tZmJXGczketnJnIDjBiNdeRorCPHqXXkBE4dzVIOAPKWBZkKDbb3AAAAAElFTkSuQmCC
"
	tablelist_plain2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKEw4I8/VmowAAADZJREFUKM9jYBgygJGBgaGeBPWN
yBoZiNTciG4jAxGaG7E5lYGA5kZcfmTAo7mR1ECrZxg+AAC4iAWFJSdDXQAAAABJRU5ErkJggg==
"
    } else {
	tablelist_plain2_collapsedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIXjI9poA3c0IMxTOpuvS/yPVVW
J5KlWAAAOw==
"
	tablelist_plain2_expandedImg put "
R0lGODlhDgAMAIABAH9/f////yH5BAEKAAEALAAAAAAOAAwAAAIUjI+pywoPI0AyuspkC3Cb6YWi
WAAAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plain3TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain3TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain3_${mode}Img \
		 [image create photo tablelist_plain3_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain3_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExAQNNjBKgAAADtJREFUKM9jYKABqCdHExM1DGKi
houYqOE1JmqEERM1ApuJGrFGrCGNlBrSSKl3GikN2EZKo7iR7nkHAKniBpTspddsAAAAAElFTkSu
QmCC
"
	tablelist_plain3_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABEAAAAOCAYAAADJ7fe0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExIRcemTPgAAAD5JREFUKM/t0jsOACAIRMHnycne
3J6IgJa6PRN+8OMzADuok0doQlp1QgNSNA5FSLudUICULZYE0s3l7NGPnffUBoaD5FpzAAAAAElF
TkSuQmCC
"
    } else {
	tablelist_plain3_collapsedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIdjI+ZoH3AnIJRPmovznTL7jVg
5YBZ0J0opK4tqhYAOw==
"
	tablelist_plain3_expandedImg put "
R0lGODlhEQAOAIABAH9/f////yH5BAEKAAEALAAAAAARAA4AAAIYjI+py+1vgJx0pooXtmy/CgVc
CITmiR4FADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plain4TreeImgs
#------------------------------------------------------------------------------
proc tablelist::plain4TreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plain4_${mode}Img \
		 [image create photo tablelist_plain4_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_plain4_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExUCuhZEJwAAAEdJREFUOMu91IsNACAIQ0HSxU03
dwf1ZIBH6IeZz7NegSIXRF4QKVGkB5EmR6YoMqaRPTiBV8GrZKkytCqKVSWqqv8VmP/zDd6/CJzv
kRcqAAAAAElFTkSuQmCC
"
	tablelist_plain4_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABcAAAASCAYAAACw50UTAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AUKExY6uTmvegAAAExJREFUOMvtlNsNACAIA8/JSTd3
ApWHfmjsAD1SCvD1lBpgG3w0MqcI0GxyCgCtYiEJkCdzEgB5F0oQoEhbCAAUrSJOgE7cgv13cI86
Y04IiOwcRtoAAAAASUVORK5CYII=
"
    } else {
	tablelist_plain4_collapsedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIojI+pCusL2pshSgotznoj23kV
GIkjeWFoSK1pi5qxDJpGbZ/5/cp5AQA7
"
	tablelist_plain4_expandedImg put "
R0lGODlhFwASAIABAH9/f////yH5BAEKAAEALAAAAAAXABIAAAIijI+py+0Po3Sg2ovrylyzjj2g
J3YTNxlhqpJsALzyTNdKAQA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::plastikTreeImgs
#------------------------------------------------------------------------------
proc tablelist::plastikTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plastik_${mode}Img \
		 [image create photo tablelist_plastik_${mode}Img]
    }

    tablelist_plastik_collapsedImg put "
R0lGODlhDgAOAMIDAAAAAHZ2drW1tf///////////////////yH5BAEKAAQALAAAAAAOAA4AAAMp
SLrc/vCJQKlwc2gdLgsbsAUNqIlcOQAsO5BfOKrnzGTb692VFf1ARgIAOw==
"
    tablelist_plastik_expandedImg put "
R0lGODlhDgAOAMIDAAAAAHZ2drW1tf///////////////////yH5BAEKAAQALAAAAAAOAA4AAAMn
SLrc/vCJQKlwc2gdLgtbGDRgyJEDoKrD+JnnC7tLJnrMVHVR7zMJADs=
"
}

#------------------------------------------------------------------------------
# tablelist::plastiqueTreeImgs
#------------------------------------------------------------------------------
proc tablelist::plastiqueTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable plastique_${mode}Img \
		 [image create photo tablelist_plastique_${mode}Img]
    }

    tablelist_plastique_collapsedImg put "
R0lGODlhEQAOAOMLAAAAAHp4eH59fa+trfHx8fPz8/X19ff39/n5+fv7+/39/f//////////////
/////yH5BAEKAA8ALAAAAAARAA4AAAQ+8MlJq7042yG6FwMmKGSpCGKiBmqCXgIiBzLyWsIR7Ptx
VwKDMCA0/CiCgjKgLBwnAoJ0SnhKOJ9OSMPtYiIAOw==
"
    tablelist_plastique_expandedImg put "
R0lGODlhEQAOAOMLAAAAAHp4eH59fa+trfHx8fPz8/X19ff39/n5+fv7+/39/f//////////////
/////yH5BAEKAA8ALAAAAAARAA4AAAQ78MlJq7042yG6FwMmKGSpCGKirgl6CUgsI64lHEGeH3Ul
GMCgoUcRFI7IAnEiIDifhKWE8+mENNgsJgIAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::radianceTreeImgs
#------------------------------------------------------------------------------
proc tablelist::radianceTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable radiance_${mode}Img \
		 [image create photo tablelist_radiance_${mode}Img]
    }

    tablelist_radiance_collapsedImg put "
R0lGODlhEgAQAKUoAAAAAEBAQOTe1eTe1uTf1+bh2ejj2ujk3erl3uvn4Ozo4u3p4+7q5O/r5u/s
5+/t6PDt6PPw7PLw7fXz8Pb08ff18vb18/f28vj28fj28vj28/j39Pj39fj49fn49/n5+Pr6+Pv7
+fz8+fz8+vz8+/39/P39/f7+/f//////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAaZwJ9w
SCwWD4KkUnkwFjAj02k6NY0oBeLBQiKVvuBS19IUCkCgkGjEZotCaMFQ4Kl/7oH7p+6RmzkcGxsc
HQEdgYAcfj8CGhoZGhQVARUVF44aiwIUFBMBn6ABnBSaEhESqBIBqamaEA+wsAGxsBCaC7i5Abm4
DJoJCMHCwwgKiwcNBsrLzAYOZUIFCgQD1dYDBApZR0vd0EJBADs=
"
    tablelist_radiance_expandedImg put "
R0lGODlhEgAQAKUoAAAAAEBAQOTe1eTe1uTf1+bh2ejj2ujk3erl3uvn4Ozo4u3p4+7q5O/r5u/s
5+/t6PDt6PPw7PLw7fXz8Pb08ff18vb18/f28vj28fj28vj28/j39Pj39fj49fn49/n5+Pr6+Pv7
+fz8+fz8+vz8+/39/P39/f7+/f//////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAASABAAAAaTwJ9w
SCwWD4KkUnkwFjAj02k6NY0oBeLBQiKVvuBS19IUCkCgkGjEZotCaMFQ4Kl/7vhP3SM3czgbGxwd
hIB/HH0/AhoaGRoUFRcVkYwaiQIUFBMBnJ0BmRSXEhESpaanEpcQD6ytrg8QlwuztLWzDJcJCLu8
vQgKiQcNBsTFxgYOZUIFCgQDz9ADBApZR0vXykJBADs=
"
}

#------------------------------------------------------------------------------
# tablelist::ubuntuTreeImgs
#------------------------------------------------------------------------------
proc tablelist::ubuntuTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable ubuntu_${mode}Img \
		 [image create photo tablelist_ubuntu_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_ubuntu_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAgElEQVQoz73ROwrCUBSE4Q8jATtR
AkoWpZCVuA8xO0gr2LgdF+Cj0CJ1bGyuTUhuECTTzTn/FMMwllaxZ9LyFd64dMGTlk9RoEQ+BMMN
sxAohmCoccUmhNYxGBo8QukDsmkETrHEHXs8++A5Fjji/D12wTle2IWyvTph+5cFf9IH6EoSOPaU
kccAAAAASUVORK5CYII=
"
	tablelist_ubuntu_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAiklEQVQoz9XRIQoCYRAF4M8VXCzC
j2lFTJ7H5C02eA+bd9BgEBeP4R3MBrVZNFn+hZ8/qEnwwYThvZl5vOH/0EGFFfpvdE8surjjgSlO
uGTVwxbHIk4ecEXINgbcsIciIZYYoIx9iVDX9Sb1nGKGOc4YYYemJYtM3NqZxPPNp4QqrDH+NtLh
bz/4Au5zF3nYGscDAAAAAElFTkSuQmCC
"
	tablelist_ubuntu_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAiElEQVQoz72SoQoCURREz11YweIv
uFEQo83id+wvWMT/M4nFbhCxLNjXKMixaHks6xPEaQOHO8xw4S9Sp9/AN3WTC9/Vq3roSikSXwIn
YATs05RILwO7lx0CY6AB6og498FvzYAHMC96KgyACXABFhHRdBXcqke1Vde5a1SfpmvVVe7Oy5+9
wxNzbFn4+q5BGgAAAABJRU5ErkJggg==
"
	tablelist_ubuntu_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAj0lEQVQoz9WRMQ4BARBF30ejICKa
jUg4z15EOMsewC00nEOhlJAoHEDUT7MrCkQl8ZufmXnF/Bn4P0WdAlug/4G7AWUnyUmtgAVwfAHO
gFWSQ5qOugF6wOUJLIBrkhKg9TSYA0OgW9ddYAQsG+ABJzkDFTAG2rVXSU5vk6hrdV+v9Vlqoe7U
yVf3VAe//eAdhJ0u3C54tZ8AAAAASUVORK5CYII=
"
    } else {
	tablelist_ubuntu_collapsedImg put "
R0lGODlhCwAOAKECAAAAAExMTP///////yH5BAEKAAAALAAAAAALAA4AAAIWhI+py8EWYotOUZou
PrrynUmL95RLAQA7
"
	tablelist_ubuntu_expandedImg put "
R0lGODlhCwAOAKECAAAAAExMTP///////yH5BAEKAAAALAAAAAALAA4AAAIThI+pyx0P4Yly0pDo
qor3BoZMAQA7
"
	tablelist_ubuntu_collapsedSelImg put "
R0lGODlhCwAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAALAA4AAAIWhI+py8EWYotOUZou
PrrynUmL95RLAQA7
"
	tablelist_ubuntu_expandedSelImg put "
R0lGODlhCwAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAALAA4AAAIThI+pyx0P4Yly0pDo
qor3BoZMAQA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::ubuntu2TreeImgs
#------------------------------------------------------------------------------
proc tablelist::ubuntu2TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable ubuntu2_${mode}Img \
		 [image create photo tablelist_ubuntu2_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_ubuntu2_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4AsDFAkb/31W1AAAAFhJREFUGNONj7sNgDAMBc/uwhwZ
j5IxKLMLy7BHykdDRGLxO8mF9U7PsnEiiYiZ4d2S+WADsiTaAFcDMAElNnloSVHym1MJWN+ECixP
QgVmSfvvL3qGsAkHUqArtr/xO8MAAAAASUVORK5CYII=
"
	tablelist_ubuntu2_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4AsDFBAHcHyjgwAAAEhJREFUGNO9zLERQEAYBeGPC1Qg
FGlGQwKBAoyCnPTmupJI/pCQDd/uPD6nwYLpxeeEigE9uhAXDmwphoIxohYn9qfLFbN/uQEwZAfr
O7QC9wAAAABJRU5ErkJggg==
"
	tablelist_ubuntu2_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4AsDFAw3sNLOcgAAAF9JREFUGNN9kLENgDAQA89IEKWh
gQkYmH2YgJmoTEGCwgvF1cu+4vSyTS9DPSRNXQBYJI09IAM5Qi2A7aNAqS0popuf7MD69gE4gRlI
v0AcbX8cDFy2r9ZL9VGSUhwBbiXCRsSA6M6gAAAAAElFTkSuQmCC
"
	tablelist_ubuntu2_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAYAAACJxx+AAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4AsDFBELYNHe6QAAAE1JREFUGNO9zCEKgFAABNFZEAwi
iOAFPIPd63sai+FjGosfk1FfnWXhcwEmoH/pByrAoC4+VqBVyT0gyajOQJdkU0+Apn6pexKAUuNP
LsjVKWqydBSbAAAAAElFTkSuQmCC
"
    } else {
	tablelist_ubuntu2_collapsedImg put "
R0lGODlhCAAKAMIFAAAAAD4+PkdHR0hISE9PT////////////yH5BAEKAAcALAAAAAAIAAoAAAMS
eLrcO+4E4cJsNhBmKfcMFDUJADs=
"
	tablelist_ubuntu2_expandedImg put "
R0lGODlhCAAKAMIEAAAAAD4+PkNDQ0tLS////////////////yH5BAEKAAAALAAAAAAIAAoAAAMO
CLrcziHKNaJo477NewIAOw==
"
	tablelist_ubuntu2_collapsedSelImg put "
R0lGODlhCAAKAMIGAAAAAN3d3d7e3ubm5uvr6/Hx8f///////yH5BAEKAAcALAAAAAAIAAoAAAMS
eLrcO+6E4oKhzBqSb5uOEDkJADs=
"
	tablelist_ubuntu2_expandedSelImg put "
R0lGODlhCAAKAKECAAAAAN3d3f///////yH5BAEKAAMALAAAAAAIAAoAAAINnI+pGO0nokhx2YtH
AQA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::ubuntu3TreeImgs
#------------------------------------------------------------------------------
proc tablelist::ubuntu3TreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel} {
	variable ubuntu3_${mode}Img \
		 [image create photo tablelist_ubuntu3_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_ubuntu3_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAWUlE
QVQoU2P4//8/yRiVw8DgDMQSyGLYMCqHgSEGiFcT0ojKgWg6TEgjKgehCa9GVA6qJpwaUTmYmrBq
pIkmkp1HckDg1ADCqByIJrwaQBiVQ04yIg7/ZwAAgQKZuDdqxHAAAAAASUVORK5CYII=
"
	tablelist_ubuntu3_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAXUlE
QVQoU5XLwQ3AIAxDUcZgLMbobkzCVGmSFhCKhQHpH7DykohcB0cWHFlwZNkr2nNY6ShrVWsku8mO
fsngAAMRuIAF+SfCAPwuDBNC4Ddw/CAEFhxZcGTBcZ+kF8WCmsIy4DnwAAAAAElFTkSuQmCC
"
	tablelist_ubuntu3_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAXUlE
QVQoU62SywnAIBAFLSVdWYcVp5TNziGweX5wgw/m4MCAiMXM0qioch6iojm3cwXXoYKILUMVb8Sm
oYoYsWH4OTgasS6MARyJ0tdLP8Q0ABVEywBU/PpGG1h5AHZuQvcmAx5DAAAAAElFTkSuQmCC
"
	tablelist_ubuntu3_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAXUlE
QVQoU5XOgQmAMBAEwZRidfZilZby/koSjDlyKozg8QuWiPhNjo4cHTk6vPZ0fMTtHW3pTO7hhtv+
ey7sAVq0CocAzwjvcAowfFQtlAGmoeJYBpCjI0dHjmtRLiHfREV2rBj7AAAAAElFTkSuQmCC
"
    } else {
	tablelist_ubuntu3_collapsedImg put "
R0lGODlhDQAOAMIFAAAAADw8PFRUVKOjo7y8vP///////////yH5BAEKAAcALAAAAAANAA4AAAMf
eLrcR84NEdkItJ6LNe/RBzZiRgaoeY4SK6kRpM1KAgA7
"
	tablelist_ubuntu3_expandedImg put "
R0lGODlhDQAOAMIFAAAAADY2NlRUVJeXl6+vr////////////yH5BAEKAAcALAAAAAANAA4AAAMd
eLrc/jA+Mqq9RInAOxfM5gVgI36QWKar5L5wlAAAOw==
"
	tablelist_ubuntu3_collapsedSelImg put "
R0lGODlhDQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAANAA4AAAIZhI8JoRrczoNxUmer
vXI3/03R8oykuaBoAQA7
"
	tablelist_ubuntu3_expandedSelImg put "
R0lGODlhDQAOAKEBAAAAAP///////////yH5BAEKAAAALAAAAAANAA4AAAIUhI+py70Bo4RmTmRp
skw67YTi6BQAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::ubuntuMateTreeImgs
#------------------------------------------------------------------------------
proc tablelist::ubuntuMateTreeImgs {} {
    foreach mode {collapsed expanded collapsedSel expandedSel
		  collapsedAct expandedAct collapsedSelAct expandedSelAct} {
	variable ubuntuMate_${mode}Img \
		 [image create photo tablelist_ubuntuMate_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_ubuntuMate_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAADNJREFUGFdj+P//P04MIRgYRNElwOJggoEhBoiT8EkeRleALgnCRrgkcerEaScW
1/5nAAAEbX5FmgjJygAAAABJRU5ErkJggg==
"
	tablelist_ubuntuMate_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAADxJREFUGFdj+P//P06MVRCGsQrCMAgEAHEGGg6ASUoA8WogPgzFILYEWBKqAqYA
LgGXRFIAl0CRxMT/GQDUC3iRKcgrYgAAAABJRU5ErkJggg==
"
	tablelist_ubuntuMate_collapsedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAADRJREFUGFdj+P//P04MY8ggC8IwjFEGxHUwQRhGlgQBFAXokiDgAMRYJXHqxGkn
Ftf+ZwAAuNGwE9a6YwIAAAAASUVORK5CYII=
"
	tablelist_ubuntuMate_expandedSelImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAD5JREFUGFdj+P//P06MVRCGsQrCMIgoA+LJaBgkBpY0AeKHQAwDIDZIDG4sTAFc
AoRhkjAFcAkQRpZEw/8ZACqWsUulTWk4AAAAAElFTkSuQmCC
"
	tablelist_ubuntuMate_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAADNJREFUGFdj+P//P04MIRgYRNElwOJggoEhBoiT8EkeRleALgnCRrgkcerEaScW
1/5nAAAEbX5FmgjJygAAAABJRU5ErkJggg==
"
	tablelist_ubuntuMate_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAADxJREFUGFdj+P//P06MVRCGsQrCMAgEAHEGGg6ASUoA8WogPgzFILYEWBKqAqYA
LgGXRFIAl0CRxMT/GQDUC3iRKcgrYgAAAABJRU5ErkJggg==
"
	tablelist_ubuntuMate_collapsedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAADNJREFUGFdj+P//P04MIRgYRNElwOJggoEhBoiT8EkeRleALgnCRrgkcerEaScW
1/5nAAAEbX5FmgjJygAAAABJRU5ErkJggg==
"
	tablelist_ubuntuMate_expandedSelActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAADxJREFUGFdj+P//P06MVRCGsQrCMAgEAHEGGg6ASUoA8WogPgzFILYEWBKqAqYA
LgGXRFIAl0CRxMT/GQDUC3iRKcgrYgAAAABJRU5ErkJggg==
"
    } else {
	tablelist_ubuntuMate_collapsedImg put "
R0lGODlhBwAIAMIFAAAAADw8PJ2dnaOjo83Nzf///////////yH5BAEKAAcALAAAAAAHAAgAAAMO
eLrcIy7ANUIgVLLXegIAOw==
"
	tablelist_ubuntuMate_expandedImg put "
R0lGODlhBwAIAMIFAAAAADw8PFRUVJeXl6+vr////////////yH5BAEKAAcALAAAAAAHAAgAAAMO
eLrcTiMOokQIgons+koAOw==
"
	tablelist_ubuntuMate_collapsedSelImg put "
R0lGODlhBwAIAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAHAAgAAAIMhG+BqRjvXgMyrmkK
ADs=
"
	tablelist_ubuntuMate_expandedSelImg put "
R0lGODlhBwAIAKEBAAAAAP///////////yH5BAEKAAAALAAAAAAHAAgAAAIKhI+pwW0dEFMUFQA7
"
	tablelist_ubuntuMate_collapsedActImg put "
R0lGODlhBwAIAMIFAAAAADw8PJ2dnaOjo83Nzf///////////yH5BAEKAAcALAAAAAAHAAgAAAMO
eLrcIy7ANUIgVLLXegIAOw==
"
	tablelist_ubuntuMate_expandedActImg put "
R0lGODlhBwAIAMIFAAAAADw8PFRUVJeXl6+vr////////////yH5BAEKAAcALAAAAAAHAAgAAAMO
eLrcTiMOokQIgons+koAOw==
"
	tablelist_ubuntuMate_collapsedSelActImg put "
R0lGODlhBwAIAMIFAAAAADw8PJ2dnaOjo83Nzf///////////yH5BAEKAAcALAAAAAAHAAgAAAMO
eLrcIy7ANUIgVLLXegIAOw==
"
	tablelist_ubuntuMate_expandedSelActImg put "
R0lGODlhBwAIAMIFAAAAADw8PFRUVJeXl6+vr////////////yH5BAEKAAcALAAAAAAHAAgAAAMO
eLrcTiMOokQIgons+koAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs {{treeStyle "vistaAero"}} {
    variable scalingpct
    vistaAeroTreeImgs_$scalingpct $treeStyle
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_100
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_100 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAZElE
QVQoU2P4//8/A1GApgotgZgbwsQCkBRGAHE4EAuDeegATaEoEKcAsTRIAAUgK4SyQSbmA7EqiAMH
6AqhfAkgrgViQRAHDLCYKATE+E0EYhEgJuxGICbK10SHI35AnEIGBgDfPzypQe1LowAAAABJRU5E
rkJggg==
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAASklE
QVQoU2P4//8/A1Fg8Cl0BOJyCBMKsCgEKboCxDfBPBhAUwhWFBERARLEqRCuCJ9CFEX4FIIcDpJA
xpVAjABYPIMdDJRCBgYA0sVCxaUivcEAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAY0lE
QVQoU2P4//8/A1GAdgpljnyfAsSGYA42gKTwExBfB2JnsAA6QFNYAMQvgTgSLIgMkBWC2EA6CYi/
gWiwBAygK4QqTgfi/0CsAZYEAbJMBGLi3AjERPmauHAkCIhTyMAAAJhFf793qI06AAAAAElFTkSu
QmCC
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOCAYAAAAWo42rAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAARklE
QVQoU2P4//8/A1FgkCmUOfK9Eog3QrkQgK4Qqug3EKNKICuEKWq6//s/ToXIinAqRFeET+FGkAQa
xu8ZnGCgFDIwAAAYyHMZpMy2ogAAAABJRU5ErkJggg==
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhCgAOAMIHAAAAAIKCgpCQkJubm6enp6ioqMbGxv///yH5BAEKAAcALAAAAAAKAA4AAAMa
eLrc/szAQwokZzx8hONH0HDemG3WI03skwAAOw==
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhCgAOAMIGAAAAACYmJisrK1hYWIaGhoiIiP///////yH5BAEKAAcALAAAAAAKAA4AAAMY
eLrc/jCeAkV4YtyWNR/gphRBGRBSqkoJADs=
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhCgAOAMIGAAAAABzE9ybG9y/J9z/N+Hvc+v///////yH5BAEKAAcALAAAAAAKAA4AAAMa
eLrc/qzAIwgUZzxMHT9Bw30LpnnWI03skwAAOw==
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhCgAOAMIEAAAAAB3E92HW+YLf+////////////////yH5BAEKAAAALAAAAAAKAA4AAAMX
CLrc/jACAUN4YdyWNR/gpgiWRUloGiUAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_125
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_125 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwQAADsEBuJFr7QAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAfElE
QVQ4T6XSSwqAMAwE0NygYBUP4M4jeBK37l269upx0AgZKdag8NCZNogfUdWwYllTLGs4iEyQfFfC
QWQ2ne+fOFwDGRbo/ZrHAUN2bmCFwa/fONiQXSfYYPR7zjUKbshyCztk6in8uROO2DNB/O2Z0HeK
/xFfFct3Kgd7BgT8X0rnFQAAAABJRU5ErkJggg==
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAX0lE
QVQ4T5WLwQ3AIAzEWIWF+GcUBuwQnSaECqQqOTiI5Ed8clLVa6BkQMmAkgHlxC4bJXgvJiN4jDds
XnxyBCLSHx79g6PIBzRCwTZaBSwqfVxQYXQLlAwoGVDu0dQApYwcjGzIaS0AAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwQAADsEBuJFr7QAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAjElE
QVQ4T5XSzQ1AQBAFYIVI1KAGFTi67tVFFSpQkj5cXDTAcbxJduWNbNg5fNl9wyN+KhFxyw7/ZId/
TKjXa4GWZzkmoLDDBh3P30yIpREOGPgYM0FLcQ1wwsTHExNSKe6HZr0E68znKBO4FHMPWgw8fzaK
S9j77qRXhvJnAv/bA/d38v8RpbLDb1LdInxaO2Da/xgAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAZUlE
QVQ4T5WQsQ2AMAwEMwhTMVI2yg7swQa0FCmMkbAURx+/Ka74s65xEZHfQMmAkgElA0pjO+5dabN3
Y+QLLkWnv7lhWFDPLqloDFLRHNAIBWG0CljU3uOC/MsjoGRAyYAyRsoDbx1o4rZ56f0AAAAASUVO
RK5CYII=
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhDQAQAMIHAAAAAIGBgYuLi5OTk56enqenp8XFxf///yH5BAEKAAcALAAAAAANABAAAAMg
eLrc/tCZuEqh5xJ6z4jdIUDhETzhiCofeWxg+UxYjSUAOw==
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhDQAQAMIGAAAAACYmJjo6OllZWYaGhrGxsf///////yH5BAEKAAcALAAAAAANABAAAAMe
eLrc/jDKVqYIUgwM9e5DyDWe6JQmUwRsS0xwLDsJADs=
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhDQAQAMIHAAAAAB7E9yTG9y/J9zTK9zjL+Hvc+v///yH5BAEKAAcALAAAAAANABAAAAMg
eLrc/tCZuEihh5xB9RGRdwSQOD4iiSpguXUXNWE0lgAAOw==
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhDQAQAMIFAAAAABzE9yvH92HW+YLf+////////////yH5BAEKAAcALAAAAAANABAAAAMe
eLrc/jDKNqYIUhAM9e5EyDWe6JQmMwRsW01wLDcJADs=
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_150
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_150 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAkklE
QVQ4T63Tqw6AMAwF0GocjwSBIdlv8B84LBKD4evHHVS0S3ltLDmB20JDYJD3PotZ/MIsfqED0QCl
rD3RgWhkjazf0eG8uYIJWtm7ogMG8LGGGTrZt+jAA/g8DFmgl9fEdBADOIchKzhZl3SIBnDNwQZF
3Dv6Kvz5BFjp7wAr/StA3j5gyTsx719IYRbf87QDkkXd7AZZ8UwAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAaklE
QVQ4T6WM0QnAIAwF3a4zOIl0z/50mjSBBkSukkeF+/D0XjOzX6BUQKmAUgGlAsoZP4cz6C1Ambzx
5dz0HqAMMu69x0UbmGN5YI2lAYrLA19xaWAXB5WBEZ82nGuYoFRAqYBSAWUdaw84XP55BTs9TwAA
AABJRU5ErkJggg==
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAkklE
QVQ4T6WTuw2AMAxEMwjLsAItJQ0l27AQ81BQQGlsyZF8kSG/4sncmTtFIgQi6sI1a3DNGkAMx7Mz
k/VygODwxZzMbP0/QGjBqnOxuy9ASFCnlNwy7d4DRCzQ51iy2XdSQNgC1dkSEGmBelJCzJjuBBBp
gYbbTlASFkDEAhOu/woabr8HTNdN7PsXWnDNcii8/8FGqvnrvTkAAAAASUVORK5CYII=
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAYAAABSO15qAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAcElE
QVQ4T6WSsQ2AIBQFGcQh7e3ciB1cwziGBcX3k0hCzEn+0+IKDu5VJDP7BUoFlAooFVAqoOyZtnN2
Mt1VUDbuuDh+5DcoKy1e9mLyQB+vhzjwjKUBisMDb3FoYBRHB3J9NODbP4iAUgGlAso4li4fLlnw
8CctEgAAAABJRU5ErkJggg==
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhEAASAOMIAAAAAIaGhouLi5CQkJiYmKGhoaioqMPDw///////////////////////////
/////yH5BAEKAAAALAAAAAAQABIAAAQrEMhJq70426OrMd0EFiEAAkR4AkO3AoL2AkH2xvbUylLq
AiTVLMMpGY+ACAA7
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhEAASAMIGAAAAACYmJisrK1lZWYaGhoiIiP///////yH5BAEKAAcALAAAAAAQABIAAAMj
eLrc/jDKSWepR4Qqxp6dBw7kB4VlhKbPyjZFIM8Bgd14DiUAOw==
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhEAASAMIFAAAAABzE9ybG9yvH93jc+v///////////yH5BAEKAAcALAAAAAAQABIAAAMj
eLrc/jA6IpsYdYmzc+8SCELj6JhBVIZa9XlcxmEyJd/4kQAAOw==
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhEAASAMIFAAAAAB3E92HW+Xvd+4Lf+////////////yH5BAEKAAcALAAAAAAQABIAAAMj
eLrc/jDKSaeoJ4Qaxp4d8UWhKJUmhKbOyjKCJmsXZt/4kwAAOw==
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaAeroTreeImgs_200
#------------------------------------------------------------------------------
proc tablelist::vistaAeroTreeImgs_200 {{treeStyle "vistaAero"}} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_${treeStyle}_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUWORalREAAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAJNJREFUOE+10zsKgDAQBNCt7fyAhY2Qa3gPO1tLGxtPHye4RdgNJpI1
8DBOwiBqyHtvLhnWSoa1dEC0QCvzL3RAtLJBrpXSwVPYwQajXC+hA5TytYcdJrknRwdcyvNQfMAc
78nRQVTK96H4BBfnb3QgSjlzcEEj11J08PeTYti+Uwzbrw/2/ykzPVH2Z99CMqzj6QYGRertj0pe
+AAAAABJRU5ErkJggg==
"
	tablelist_${treeStyle}_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUeBx8d0+MAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAGtJREFUOE+tzMEJwCAQRFG7Sw1biaTPXFLNxoUIi3w9OArv4Ii/uPtx
OKpwVOGowlGF46idq6n0RnDM/uDTvPROcOx60Mziokdz8Eh0DMpRCkrRWXA7ugqG3WiNjwt3/riC
owpHFY4qHDVePsGgC4kbm9dDAAAAAElFTkSuQmCC
"
	tablelist_${treeStyle}_collapsedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUVIS7kj9UAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAJNJREFUOE+tkzEKgDAMRT2Il/EKro4ujt7GC3keBwcdYwIplPxAW5vh
UX0pj4J2IKJwXNmLK3sBMZ7vwczWtwCCgzdzMYud1QJCo5uuq53XAEJiukr4kdXuKQEiRfU5hfd8
TwkQeVTfm8MgbFSdhImZ7MwDhI1qMO6kf4ICiBTNgjFfX4Ox/ykTfqPi734EruyDhg9wSVOrXMoi
bgAAAABJRU5ErkJggg==
"
	tablelist_${treeStyle}_expandedActImg put "
iVBORw0KGgoAAAANSUhEUgAAABUAAAASCAYAAAC0EpUuAAAABGdBTUEAALGPC/xhBQAAAAlwSFlz
AAAOwAAADsABataJCQAAAAd0SU1FB98IEBUbEg+3w00AAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5F
VCB2My41LjEwMPRyoQAAAHJJREFUOE+t0rENgCAURVEGcUh7OzdiB9cwjmFB8cVEEvJzpeD94hQ+
5FYkMwuHowpHFY4qHFU4estxr1WmM4Jj7wuWqn7yPx6OTQtuZ7GQaB/cr4CoD8pRCkrRv+B0dBRU
ovm9OBD3TmfgqMJRhaPG0gNGBmbxSYGdJwAAAABJRU5ErkJggg==
"
    } else {
	tablelist_${treeStyle}_collapsedImg put "
R0lGODlhFQASAOMIAAAAAIaGhouLi5CQkJiYmKGhoaioqMPDw///////////////////////////
/////yH5BAEKAAAALAAAAAAVABIAAAQvEMhJq7046w0Ox4bxWWIxUiJAnFIKDKwLCKcMBKNM5xNc
S6sYwMQChIoSD3LJjAAAOw==
"
	tablelist_${treeStyle}_expandedImg put "
R0lGODlhFQASAMIGAAAAACYmJisrK1lZWYaGhoiIiP///////yH5BAEKAAcALAAAAAAVABIAAAMl
eLrc/jDKSauV5TIRtBJDp4HhOJxiRaLWylLuiwV0HRBeru97AgA7
"
	tablelist_${treeStyle}_collapsedActImg put "
R0lGODlhFQASAMIFAAAAABzE9ybG9yvH93jc+v///////////yH5BAEKAAcALAAAAAAVABIAAAMn
eLrc/jDKeQiFYlwnTt/L94HjeJnmlAYbSoagp6RUR9darFh67y8JADs=
"
	tablelist_${treeStyle}_expandedActImg put "
R0lGODlhFQASAMIFAAAAAB3E92HW+Xvd+4Lf+////////////yH5BAEKAAcALAAAAAAVABIAAAMl
eLrc/jDKSauV4rIQtApDp4GEaJHlhabVyk7uGwlczWVeru96AgA7
"
    }
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs {{treeStyle "vistaClassic"}} {
    variable scalingpct
    vistaClassicTreeImgs_$scalingpct $treeStyle
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_100
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_100 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhCwAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAALAA4AAAIjnI+pm+H/TBC0iiAr
qHhMulHdBJTllYFcKoSoZ60eBDH2UgAAOw==
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhCwAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAALAA4AAAIfnI+pm+H/TBC0iiBt
xWPqmwGiCHZf6Wlcaq0QxMRLAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_125
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_125 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhDgAQAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOABAAAAIrnI+pyxoPYzhB2Hun
qRdgPXCWl1EYaYEVwLaeen5mJ29xaWN1KEnNDxwUAAA7
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhDgAQAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOABAAAAIonI+pyxoPYzhB2Hun
qRjrwXXWF4qkAKQqIJziSL3wJrexTEpSw/dDAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_150
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_150 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhEQASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAARABIAAAI3nI+py60Bo4woiIuz
CFUDzR1W9mWhMWIldg7ptV6tBdS2vXUkqKu86PmhgqaehlWZKFuOpnNQAAA7
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhEQASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAARABIAAAIxnI+py60Bo4woiIuz
CFV7flheBhrieJXDiaoWAMfx1qFpbbv2He50v3NNhiqH8TgoAAA7
"
}

#------------------------------------------------------------------------------
# tablelist::vistaClassicTreeImgs_200
#------------------------------------------------------------------------------
proc tablelist::vistaClassicTreeImgs_200 {{treeStyle "vistaClassic"}} {
    foreach mode {collapsed expanded} {
	variable ${treeStyle}_${mode}Img \
		 [image create photo tablelist_${treeStyle}_${mode}Img]
    }

    tablelist_${treeStyle}_collapsedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAJHnI+pFu0Pmwqi2ovD
xPzqRGHAyH1IeI1AuYlk1qav16q2XZlHePd53cMJdAyOigUyAlawpItJc8qgFuIA1Wmesh1r5PtQ
FAAAOw==
"
    tablelist_${treeStyle}_expandedImg put "
R0lGODlhFwASAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAXABIAAAI+nI+pFu0Pmwqi2ovD
xPzqRHXdh4Ritp0oqK5lBcTyDFTkEdK6neo0z2pZbgzhMGUkDkxCJbPlNAJLkapDUQAAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::win7AeroTreeImgs
#------------------------------------------------------------------------------
proc tablelist::win7AeroTreeImgs {} {
    vistaAeroTreeImgs "win7Aero"
}

#------------------------------------------------------------------------------
# tablelist::win7ClassicTreeImgs
#------------------------------------------------------------------------------
proc tablelist::win7ClassicTreeImgs {} {
    vistaClassicTreeImgs "win7Classic"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs {} {
    variable scalingpct
    win10TreeImgs_$scalingpct
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_100
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_100 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAKCAYAAAC9vt6cAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAExJREFUKFNj+P//P0UYwWBg0AFiB2RJYjCCAdQMxJGkGoLKIcMQTAESDcEuyMAQ
DDVEB5s8MsYUoMQFpGoGYQSDDM0gjGCQlQ7+MwAAiH+aQTbAbFoAAAAASUVORK5CYII=
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABAAAAAKCAYAAAC9vt6cAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAFRJREFUKFNj+P//P0UYqyApGATigbgDh2QHSB6bHAzDFO0H0WgSWMXRMYRAU4zO
x4cRDKgmHx8fEIcozSCMyiHBZhjGFCAQaOgYqyApGKsg8fg/AwClVaMkbFpt/wAAAABJRU5ErkJg
gg==
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhEAAKAMIGAAAAAKampqysrL+/v9LS0tTU1P///////yH5BAEKAAcALAAAAAAQAAoAAAMZ
eLrcS8PJM0KcrV68NGdCUHyURXof+kFkAgA7
"
	tablelist_win10_expandedImg put "
R0lGODlhEAAKAMIHAAAAAEBAQExMTHd3d5+fn6CgoKGhof///yH5BAEKAAcALAAAAAAQAAoAAAMb
eLrc/oyMNsobYSqsHT8fBAZCJi7hqRhq6z4JADs=
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhEAAKAMIGAAAAAE7Q+VjS+Xra+5vh/Jri/P///////yH5BAEKAAcALAAAAAAQAAoAAAMZ
eLrcW8PJM0KcrV68NGdCQHyURXof+kFkAgA7
"
    tablelist_win10_expandedActImg put "
R0lGODlhEAAKAMIGAAAAABzE9yjH+FbS+YDb+4Lc+////////yH5BAEKAAcALAAAAAAQAAoAAAMb
eLrc/oyMNsobYSqsHT8fBAZCJi7hqVhq6zoJADs=
"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_125
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_125 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAABoAAAAMCAYAAAB8xa1IAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAF1JREFUOE+9lMEJwDAMA71QJ+gG3aD7D+JK0EKN9QlYCdxDl8eRTyIzt1BHxAGu
v5uiDkTA7Yh1YYppaYhJSaZjUn68IXKq+xWkJDj+F01HSBeGCKnDFCF12H6GjAdLF1EmW/vAagAA
AABJRU5ErkJggg==
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAABoAAAAMCAYAAAB8xa1IAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAGNJREFUOE+9j4EJwCAMBDNqN3GUjuJosY8Eqf0UqUmFU3MfIoqq/gKVGVCZAdZx
cbLQQI4+lq1iQypOp+E1X6VvzjDPf2FcpqFzvcu9GMONkEfAUwT/xOBSpDC/A5UZUBmPSgPj7VvG
j4QeDgAAAABJRU5ErkJggg==
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhGgAMAMIFAAAAAKamprW1tcTExNLS0v///////////yH5BAEKAAcALAAAAAAaAAwAAAMi
eLrc/ocISJ8Is2p1867dp4UiFQRDaWGqQ7bLCx/yLM1KAgA7
"
	tablelist_win10_expandedImg put "
R0lGODlhGgAMAMIHAAAAAEBAQEFBQWBgYICAgJ+fn6CgoP///yH5BAEKAAcALAAAAAAaAAwAAAMi
eLrc/jDKSct4w9A1wmXdtx0h543gWaKpcLLNCjfEbN9oAgA7
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhGgAMAMIGAAAAAE7Q+WfV+mjV+oHc+5ri/P///////yH5BAEKAAcALAAAAAAaAAwAAAMj
eLrc/qcISJ8Is2p1867X8GnhWAUBYVrY6nRuA8fLTCvSfSQAOw==
"
    tablelist_win10_expandedActImg put "
R0lGODlhGgAMAMIGAAAAABzE9z7M+F/U+oDb+4Hc+////////yH5BAEKAAcALAAAAAAaAAwAAAMi
eLrc/jDKSYl4otAlwmXdtx0h543gWaJpcLLNCjfDbN9oAgA7
"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_150
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_150 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAAB8AAAAQCAYAAADu+KTsAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAIZJREFUSEvNlbENgDAMBD0IDQNQswQLsP8gxi8R5OCvkOMQ6YocSOc0iajqNLgU
WZjPJgqRzTiN/f0tm35jJ77DjaEDRGFBFx86AJdFA1AJEHTxIQNQ2UDQxdMHoNJj63BxsLL/vkBl
w9ackyPkoulhwGVBGERRFAb95gc33Jy7/ZElr5rKBVezH+eTfDdNAAAAAElFTkSuQmCC
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAAB8AAAAQCAYAAADu+KTsAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAJVJREFUSEvFkNkNgCAQRLcvCrAIfqzC9iwNmXiwukPiASvJ43i7YVBJKf0GlV5Q
6UXZiARdqHG37w7rJDJm5sx0bdCgvvWNrP4UjLBduEMfAK96wOc/sE724tMDcFY1U39L2VQCsCp3
+BacD5egGCNkl2Bghf3SLsGAS/uA5sGASoDAnsGAyp08BuZbQaUXVHpBpQ9JFsLONZHqquN4AAAA
AElFTkSuQmCC
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhHwAQAOMIAAAAAKamprOzs8jIyNLS0t7e3uPj4+Tk5P//////////////////////////
/////yH5BAEKAAAALAAAAAAfABAAAAQ3EMhJq7344M0lCUMnUkZghuM4mGCqsqjLrafc0a29CWyh
X7jYbxIcVopGIiw5KdWYk48QCtBAIwA7
"
	tablelist_win10_expandedImg put "
R0lGODlhHwAQAOMJAAAAAEBAQFtbW4mJiZ+fn6CgoLi4uMTExMXFxf//////////////////////
/////yH5BAEKAA8ALAAAAAAfABAAAAQ58MlJq7046807RRnoUUQwXENQjNIRvCeVvgf7zOaEx/Z+
vzmbDigA8oQSHAxp8TGbwafFIK1ar9IIADs=
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhHwAQAMIHAAAAAE7Q+WTV+oje+5ri/K3m/bbo/f///yH5BAEKAAcALAAAAAAfABAAAAM0
eLrc/tDASRUJo2pmgs/bNnhYKJKgSY2fWrGlOwlkIT9wei/53vQ+Hiq46LSIi4sOeZAgEwA7
"
    tablelist_win10_expandedActImg put "
R0lGODlhHwAQAOMJAAAAABzE9zjK+GnW+oDb+4Hc+5rh/Kfl/ajl/f//////////////////////
/////yH5BAEKAA8ALAAAAAAfABAAAAQ58MlJq7046807RRnoUUQwXENQjNIRvCeVvgf7zOaEx/Z+
vzmbDigA8oQSHAxp8TGbwafFIK1ar9IIADs=
"
}

#------------------------------------------------------------------------------
# tablelist::win10TreeImgs_200
#------------------------------------------------------------------------------
proc tablelist::win10TreeImgs_200 {} {
    foreach mode {collapsed expanded collapsedAct expandedAct} {
	variable win10_${mode}Img \
		 [image create photo tablelist_win10_${mode}Img]
    }

    variable pngSupported
    if {$pngSupported} {
	tablelist_win10_collapsedImg put "
iVBORw0KGgoAAAANSUhEUgAAACgAAAASCAYAAAApH5ymAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAJJJREFUSEvV1rENwCAMRFEGykDZfxGHKyyh45fYIpFe8+PiSkZEoPk91LtxnOOm
V+h/pz0s45LfdOJoA4XuOmAUHyh0Vw1j8oFCd5Uwrnyg0F0VjM4HCt1VwEh8oNDdaRiJjxO6Ow2j
82FCdxUwrnyY0F0VjMmHCd1Vwig+TOiuGsdLxskefvJYuPe5lTSSeq8YH+NamKxWvX/LAAAAAElF
TkSuQmCC
"
	tablelist_win10_expandedImg put "
iVBORw0KGgoAAAANSUhEUgAAACgAAAASCAYAAAApH5ymAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41
LjEwMPRyoQAAAJFJREFUSEvNzgEKgCAMhWFv2k272nKItdZvWDRa8Ik9J74iIqlhmAmGmRybUhZ7
MOPNnafaUh+qVuUHRvp8FVpSv71cR4OWn6/CSrbl+uCwpJ9TNPeVYzPxsD9XfuZr55+bAj5X9m6U
awBFiL8XhUMoZNGdKBgqX6qj2UgYdn+XUxhaf5ZTGGaCYSYYZoJhHlI2JrC2jqb+LJ4AAAAASUVO
RK5CYII=
"
    } else {
	tablelist_win10_collapsedImg put "
R0lGODlhKAASAMIHAAAAAKampqenp6ioqNLS0tPT09TU1P///yH5BAEKAAcALAAAAAAoABIAAANB
eLq1/jDKV4KYOEMT+tUgJnRWaEajd67LQH7s6ZLxOne1TAZ5ePO9zC8o3BExN9gRklxKUiUnpKKS
RghR61W7SAAAOw==
"
	tablelist_win10_expandedImg put "
R0lGODlhKAASAMIGAAAAAEBAQEJCQp+fn6CgoKGhof///////yH5BAEKAAcALAAAAAAoABIAAAM/
eLrc/jDKSau9qlCN4QiCJARE5xBBGj5jyplLCzryCjM1ns43va+5HusXFA53KqMIaVNCWk3nMyqt
Wq/YrCUBADs=
"
    }

    tablelist_win10_collapsedActImg put "
R0lGODlhKAASAMIFAAAAAE7Q+VHQ+Zrh/Jri/P///////////yH5BAEKAAcALAAAAAAoABIAAAM9
eLqz/jDKN4KYOMMarP6Z0HlgCYndZa4K2rGsG8CrTJv2/eU6xveSH/A0mg2DI9WRmFpGOCQnhBCV
Tq2LBAA7
"
    tablelist_win10_expandedActImg put "
R0lGODlhKAASAMIEAAAAAB3E94Db+4Hc+////////////////yH5BAEKAAAALAAAAAAoABIAAAM6
CLrc/jDKSau9alCNoQiBBHIdM4AghAZkqaxhA7vOvNi0vL57/sA4Xw0YE6qCxh8qSUkxn9CodFpK
AAA7
"
}

#------------------------------------------------------------------------------
# tablelist::winnativeTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winnativeTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winnative_${mode}Img \
		 [image create photo tablelist_winnative_${mode}Img]
    }

    tablelist_winnative_collapsedImg put "
R0lGODlhDgAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOAA4AAAIlnI+pyxoPYQqiWhGm
BTYjWnGVd1DAeWJa2K2CqH5X+0VRg+dHAQA7
"
    tablelist_winnative_expandedImg put "
R0lGODlhDgAOAKECAAAAAICAgP///////yH5BAEKAAMALAAAAAAOAA4AAAIinI+pyxoPYQqiWhHm
tRnRjWnAOIYeaB7f1qloa0RyQ9dHAQA7
"
}

#------------------------------------------------------------------------------
# tablelist::winxpBlueTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winxpBlueTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winxpBlue_${mode}Img \
		 [image create photo tablelist_winxpBlue_${mode}Img]
    }

    tablelist_winxpBlue_collapsedImg put "
R0lGODlhDgAOAIQeAAAAAHiYtbDC08C3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtjTydvWzNzY
z9/b0uPg2eTh2eXh2urp4+3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+////////yH5BAEK
AB8ALAAAAAAOAA4AAAVJ4CeOZGmeqCkEbBsIZeDNtBfEXQ50XHaTgc1GA9BUJL9RAANoNh9JUeBi
oQAmkEb0E4g4GICFArENJA4FAmFg2K5cLFhqTheFAAA7
"
    tablelist_winxpBlue_expandedImg put "
R0lGODlhDgAOAKUgAAAAAHiYtbDC08C3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtfSx9jTydvW
zNzYz9/b0uPg2eTh2eXh2urp4+zr5u3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+///////
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKAD8ALAAAAAAOAA4AAAZNwJ9w
SCwaj0ijIMBsBgTFAGhKBQWin2zWs7kSA50OZ3yZeIcBDWC9hpyFgQzGUqFEHO9fQPJoMBYKCHkB
CQcFBAQDBnlLTkxQSZGSQkEAOw==
"
}

#------------------------------------------------------------------------------
# tablelist::winxpOliveTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winxpOliveTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winxpOlive_${mode}Img \
		 [image create photo tablelist_winxpOlive_${mode}Img]
    }

    tablelist_winxpOlive_collapsedImg put "
R0lGODlhDgAOAIQdAAAAAI6ZfcC3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtjTydvWzNzYz9/b
0uPg2eTh2eXh2urp4+3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+////////////yH5BAEK
AB8ALAAAAAAOAA4AAAVF4CeOZGme6BmsbGAGXSx3LhlwOMBtWD0GGk0GkKFEfKLABcBkOpCfgKUy
AUgeDGgA0lgAFImDFmEgDAaCAjTaWqXecFIIADs=
"
    tablelist_winxpOlive_expandedImg put "
R0lGODlhDgAOAKUfAAAAAI6ZfcC3psG4p8K4qMO6qsa+rs/Iu9LMv9LMwNbRxtfSx9jTydvWzNzY
z9/b0uPg2eTh2eXh2urp4+zr5u3t5/Hw6/Dw7PLy7vX18ff28/b29Pf39fz8+vz8+///////////
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////yH5BAEKACAALAAAAAAOAA4AAAZJQJBw
SCwaj8hjYMkMGAOfqPTjJAY8WGxHUx0GOJyN2CLpCgMZgFr9MIMCmEuFMoE03IGIg7FQJA54CAYE
AwMCBW5vTUtJjY5EQQA7
"
}

#------------------------------------------------------------------------------
# tablelist::winxpSilverTreeImgs
#------------------------------------------------------------------------------
proc tablelist::winxpSilverTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable winxpSilver_${mode}Img \
		 [image create photo tablelist_winxpSilver_${mode}Img]
    }

    tablelist_winxpSilver_collapsedImg put "
R0lGODlhDgAOAIQXAAAAAJSVosTO2MXP2cbO2svT3NPZ4tXb5Nnf5trg593i6d/l6uDm6+bq7ufr
7+zv8+/y9PLz9vT39/b3+ff4+vn6+v39/f///////////////////////////////////yH5BAEK
AB8ALAAAAAAOAA4AAAVD4CeOZGme6BmsbGAGVyxfLhlYOIBT9RhUFQqAEnH0RIEJYLlkHD8BSQQC
eDQUz0BjkQAgDobsoTAoCwhPaGuVartJIQA7
"
    tablelist_winxpSilver_expandedImg put "
R0lGODlhDgAOAIQYAAAAAJSVosTO2MXP2cbO2svT3NPZ4tXb5Nnf5trg593i6d/l6uDm6+bq7ufr
7+zv8+/x8+/y9PLz9vT39/b3+ff4+vn6+v39/f///////////////////////////////yH5BAEK
AB8ALAAAAAAOAA4AAAVC4CeOZGme6BmsbGAGWCxjLhlceF7VY2BZlaDEwRMFKIBkklH8BCaSCOTR
UDQDjUUigTgYrofCYCwgNJ2tVWrNJoUAADs=
"
}

#------------------------------------------------------------------------------
# tablelist::yuyoTreeImgs
#------------------------------------------------------------------------------
proc tablelist::yuyoTreeImgs {} {
    foreach mode {collapsed expanded} {
	variable yuyo_${mode}Img \
		 [image create photo tablelist_yuyo_${mode}Img]
    }

    tablelist_yuyo_collapsedImg put "
R0lGODlhDwAOAOMKAAAAAIiKhby9ur7AvMDBvsrMyd3e3eHi4OHi4f7+/v//////////////////
/////yH5BAEKAA8ALAAAAAAPAA4AAARA8MlJq72zjM1HqQWSKCSZIN80jORRJgM1lEpAxyptl7g0
E4Fg0KDoPWalHcmIJCmLMpZC8DKGpCYUqMNJYb6PCAA7
"
    tablelist_yuyo_expandedImg put "
R0lGODlhDwAOAOMIAAAAAIiKhb7AvMDBvsrMyd3e3eHi4f7+/v//////////////////////////
/////yH5BAEKAA8ALAAAAAAPAA4AAAQ58MlJq72TiM0FqYRxICR5GN8kjGV5CJTQzrA6t7UkD0Hf
F4jcQ3YjCYnFI2v2ooSWJhSow0lhro8IADs=
"
}

#------------------------------------------------------------------------------
# tablelist::createTreeImgs
#------------------------------------------------------------------------------
proc tablelist::createTreeImgs {treeStyle depth} {
    set baseWidth  [image width  tablelist_${treeStyle}_collapsedImg]
    set baseHeight [image height tablelist_${treeStyle}_collapsedImg]

    #
    # Get the width of the images to create for the specified depth and
    # the destination x coordinate for copying the base images into them
    #
    set width [expr {$depth * $baseWidth}]
    set x [expr {($depth - 1) * $baseWidth}]
    switch -regexp -- $treeStyle {
	^win10$ {
	    variable scalingpct
	    switch $scalingpct {
		100 { set factor -8 }
		125 { set factor -16 }
		150 { set factor -19 }
		200 { set factor -24 }
	    }
	}
	^(vistaAero|win7Aero)$ {
	    variable scalingpct
	    switch $scalingpct {
		100 { set factor  0 }
		125 { set factor -3 }
		150 { set factor -6 }
		200 { set factor -11 }
	    }
	}
	^(vistaClassic|win7Classic)$ {
	    variable scalingpct
	    switch $scalingpct {
		100 { set factor -1 }
		125 { set factor -4 }
		150 { set factor -7 }
		200 { set factor -13 }
	    }
	}
	^ubuntu$					{ set factor -2 }
	^(mate|mint2)$					{ set factor -1 }
	^(blueMenta|menta|mint|newWave|ubuntu2)$	{ set factor  1 }
	^(ubuntu3|ubuntuMate)$				{ set factor  2 }
	^plasti.+$					{ set factor  3 }
	^(adwaita|aqua|arc)$				{ set factor  4 }
	^(oxygen.|phase|winnative|winxp.+)$		{ set factor  5 }
	^(baghira|klearlooks)$				{ set factor  7 }
	default						{ set factor  0 }
    }
    set delta [expr {($depth - 1) * $factor}]
    incr width $delta
    incr x $delta

    foreach mode {indented collapsed expanded} {
	image create photo tablelist_${treeStyle}_${mode}Img$depth \
	    -width $width -height $baseHeight
    }

    foreach mode {collapsed expanded} {
	tablelist_${treeStyle}_${mode}Img$depth copy \
	    tablelist_${treeStyle}_${mode}Img -to $x 0

	foreach modif {Sel Act SelAct} {
	    variable ${treeStyle}_${mode}${modif}Img
	    if {[info exists ${treeStyle}_${mode}${modif}Img]} {
		image create photo \
		    tablelist_${treeStyle}_${mode}${modif}Img$depth \
		    -width $width -height $baseHeight
		tablelist_${treeStyle}_${mode}${modif}Img$depth copy \
		    tablelist_${treeStyle}_${mode}${modif}Img -to $x 0
	    }
	}
    }
}

Added libs/tablelist6.0/scripts/tablelistMove.tcl.



































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
#==============================================================================
# Contains the implementation of the tablelist move and movecolumn subcommands.
#
# Copyright (c) 2003-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#------------------------------------------------------------------------------
# tablelist::moveRow
#
# Processes the 1st form of the tablelist move subcommand.
#------------------------------------------------------------------------------
proc tablelist::moveRow {win source target} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || $data(itemCount) == 0} {
	return ""
    }

    #
    # Adjust the indices to fit within the existing items and check them
    #
    if {$source > $data(lastRow)} {
	set source $data(lastRow)
    } elseif {$source < 0} {
	set source 0
    }
    if {$target > $data(itemCount)} {
	set target $data(itemCount)
    } elseif {$target < 0} {
	set target 0
    }

    set sourceItem [lindex $data(itemList) $source]
    set sourceKey [lindex $sourceItem end]
    if {$target == [nodeRow $win $sourceKey end] || $target == $source} {
	return ""
    }

    set parentKey $data($sourceKey-parent)
    set parentEndRow [nodeRow $win $parentKey end]
    if {($target <= [keyToRow $win $parentKey] || $target > $parentEndRow)} {
	return -code error \
	       "cannot move item with index \"$source\" outside its parent"
    }

    if {$target == $parentEndRow} {
	set targetChildIdx end
    } else {
	set targetKey [lindex $data(keyList) $target]
	if {[string compare $data($targetKey-parent) $parentKey] != 0} {
	    return -code error \
		   "cannot move item with index \"$source\" outside its parent"
	}

	set targetChildIdx \
	    [lsearch -exact $data($parentKey-children) $targetKey]
    }

    return [moveNode $win $source $parentKey $targetChildIdx]
}

#------------------------------------------------------------------------------
# tablelist::moveNode
#
# Processes the 2nd form of the tablelist move subcommand.
#------------------------------------------------------------------------------
proc tablelist::moveNode {win source targetParentKey targetChildIdx \
			 {withDescendants 1}} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) || $data(itemCount) == 0} {
	return ""
    }

    #
    # Adjust the indices to fit within the existing items and check them
    #
    if {$source > $data(lastRow)} {
	set source $data(lastRow)
    } elseif {$source < 0} {
	set source 0
    }
    set target [nodeRow $win $targetParentKey $targetChildIdx]
    if {$target < 0} {
	set target 0
    }

    set sourceItem [lindex $data(itemList) $source]
    set sourceKey [lindex $sourceItem end]
    if {$target == [nodeRow $win $sourceKey end] && $withDescendants} {
	return ""
    }

    set sourceParentKey $data($sourceKey-parent)
    if {[string compare $targetParentKey $sourceParentKey] == 0 &&
	$target == $source && $withDescendants} {
	return ""
    }

    set sourceDescCount [descCount $win $sourceKey]
    if {$target > $source && $target <= $source + $sourceDescCount &&
	$withDescendants} {
	return -code error \
	       "cannot move item with index \"$source\"\
		before one of its descendants"
    }

    set w $data(body)
    if {$data(anchorRow) != $source} {
	$w mark set anchorRowMark [expr {$data(anchorRow) + 1}].0
    }
    if {$data(activeRow) != $source} {
	$w mark set activeRowMark [expr {$data(activeRow) + 1}].0
    }

    #
    # Save some data of the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editRow $data(editRow)
	set editKey $data(editKey)
	saveEditData $win
    }

    #
    # Build the list of column indices of the selected cells
    # within the source line and then delete that line
    #
    set selectedCols {}
    set line [expr {$source + 1}]
    set textIdx $line.0
    variable canElide
    variable elide
    variable pu
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {$data($col-hide) && !$canElide} {
	    continue
	}

	#
	# Check whether the 2nd tab character of the cell is selected
	#
	set textIdx [$w search $elide "\t" $textIdx+1$pu $line.end]
	if {[lsearch -exact [$w tag names $textIdx] select] >= 0} {
	    lappend selectedCols $col
	}

	set textIdx $textIdx+1$pu
    }
    $w delete [expr {$source + 1}].0 [expr {$source + 2}].0

    #
    # Insert the source item before the target one
    #
    set target1 $target
    if {$source < $target} {
	incr target1 -1
    }
    set targetLine [expr {$target1 + 1}]
    $w insert $targetLine.0 "\n"
    set snipStr $data(-snipstring)
    set dispItem [lrange $sourceItem 0 $data(lastCol)]
    if {$data(hasFmtCmds)} {
	set dispItem [formatItem $win $sourceKey $source $dispItem]
    }
    if {[string match "*\t*" $dispItem]} {
	set dispItem [mapTabs $dispItem]
    }
    set col 0
    foreach text $dispItem colTags $data(colTagsList) \
	    {pixels alignment} $data(colList) {
	if {$data($col-hide) && !$canElide} {
	    incr col
	    continue
	}

	#
	# Build the list of tags to be applied to the cell
	#
	set cellFont [getCellFont $win $sourceKey $col]
	set cellTags $colTags
	if {[info exists data($sourceKey,$col-font)]} {
	    lappend cellTags cell-font-$data($sourceKey,$col-font)
	}

	#
	# Append the text and the labels or window (if
	# any) to the target line of the body text widget
	#
	appendComplexElem $win $sourceKey $source $col $text $pixels \
			  $alignment $snipStr $cellFont $cellTags $targetLine

	incr col
    }
    if {[info exists data($sourceKey-font)]} {
	$w tag add row-font-$data($sourceKey-font) $targetLine.0 $targetLine.end
    }
    if {[info exists data($sourceKey-elide)]} {
	$w tag add elidedRow $targetLine.0 $targetLine.end+1$pu
    }
    if {[info exists data($sourceKey-hide)]} {
	$w tag add hiddenRow $targetLine.0 $targetLine.end+1$pu
    }

    set treeCol $data(treeCol)
    set treeStyle $data(-treestyle)
    set indentImg [doCellCget $source $treeCol $win -indent]

    #
    # Update the item list and the key -> row mapping
    #
    set data(itemList) [lreplace $data(itemList) $source $source]
    set data(keyList) [lreplace $data(keyList) $source $source]
    if {$target == $data(itemCount)} {
	lappend data(itemList) $sourceItem	;# this works much faster
	lappend data(keyList) $sourceKey	;# this works much faster
    } else {
	set data(itemList) [linsert $data(itemList) $target1 $sourceItem]
	set data(keyList) [linsert $data(keyList) $target1 $sourceKey]
    }
    if {$source < $target} {
	for {set row $source} {$row < $targetLine} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set data($key-row) $row
	}
    } else {
	for {set row $target} {$row <= $source} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set data($key-row) $row
	}
    }

    #
    # Elide the moved item if the target parent is collapsed or non-viewable
    #
    set depth [depth $win $targetParentKey]
    if {([info exists data($targetParentKey,$treeCol-indent)] && \
	 [string compare $data($targetParentKey,$treeCol-indent) \
	  tablelist_${treeStyle}_collapsedImg$depth] == 0) ||
	[info exists data($targetParentKey-elide)] ||
	[info exists data($targetParentKey-hide)]} {
	doRowConfig $target1 $win -elide 1
    }

    if {$withDescendants} {
	#
	# Update the tree information
	#
	set targetBuddyCount [llength $data($targetParentKey-children)]
	set sourceChildIdx \
	    [lsearch -exact $data($sourceParentKey-children) $sourceKey]
	set data($sourceParentKey-children) \
	    [lreplace $data($sourceParentKey-children) \
	     $sourceChildIdx $sourceChildIdx]
	if {[string first $targetChildIdx "end"] == 0} {
	    set targetChildIdx $targetBuddyCount
	}
	if {$targetChildIdx >= $targetBuddyCount} {
	    lappend data($targetParentKey-children) $sourceKey
	} else {
	    if {[string compare $sourceParentKey $targetParentKey] == 0 &&
		$sourceChildIdx < $targetChildIdx} {
		incr targetChildIdx -1
	    }
	    set data($targetParentKey-children) \
		[linsert $data($targetParentKey-children) \
		 $targetChildIdx $sourceKey]
	}
	set data($sourceKey-parent) $targetParentKey

	#
	# If the list of children of the source's parent has become empty
	# then set the parent's indentation image to the indented one
	#
	if {[llength $data($sourceParentKey-children)] == 0 &&
	    [info exists data($sourceParentKey,$treeCol-indent)]} {
	    collapseSubCmd $win [list $sourceParentKey -partly]
	    set data($sourceParentKey,$treeCol-indent) [strMap \
		{"collapsed" "indented" "expanded" "indented"
		 "Act" "" "Sel" ""} $data($sourceParentKey,$treeCol-indent)]
	    if {[winfo exists $w.ind_$sourceParentKey,$treeCol]} {
		$w.ind_$sourceParentKey,$treeCol configure -image \
		    $data($sourceParentKey,$treeCol-indent)
	    }
	}

	#
	# Mark the target parent item as expanded if it was just indented
	#
	if {[info exists data($targetParentKey,$treeCol-indent)] &&
	    [string compare $data($targetParentKey,$treeCol-indent) \
	     tablelist_${treeStyle}_indentedImg$depth] == 0} {
	    set data($targetParentKey,$treeCol-indent) \
		tablelist_${treeStyle}_expandedImg$depth
	    if {[winfo exists $data(body).ind_$targetParentKey,$treeCol]} {
		$data(body).ind_$targetParentKey,$treeCol configure -image \
		    $data($targetParentKey,$treeCol-indent)
	    }
	}

	#
	# Update the indentation of the moved item
	#
	if {[regexp {^(.+Img)([0-9]+)$} $indentImg dummy base sourceDepth]} {
	    incr depth
	    variable maxIndentDepths
	    if {$depth > $maxIndentDepths($treeStyle)} {
		createTreeImgs $treeStyle $depth
		set maxIndentDepths($treeStyle) $depth
	    }
	    doCellConfig $target1 $treeCol $win -indent $base$depth
	}
    }

    #
    # Update the list variable if present
    #
    if {$data(hasListVar)} {
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
	set var [lreplace $var $source $source]
	set pureSourceItem [lrange $sourceItem 0 $data(lastCol)]
	if {$target == $data(itemCount)} {
	    lappend var $pureSourceItem		;# this works much faster
	} else {
	    set var [linsert $var $target1 $pureSourceItem]
	}
	trace variable var wu $data(listVarTraceCmd)
    }

    #
    # Update anchorRow and activeRow
    #
    if {$data(anchorRow) == $source} {
	set data(anchorRow) $target1
	adjustRowIndex $win data(anchorRow) 1
    } else {
	set anchorTextIdx [$w index anchorRowMark]
	set data(anchorRow) [expr {int($anchorTextIdx) - 1}]
    }
    if {$data(activeRow) == $source} {
	set activeRow $target1
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    } else {
	set activeTextIdx [$w index activeRowMark]
	set data(activeRow) [expr {int($activeTextIdx) - 1}]
    }

    #
    # Invalidate the list of row indices indicating the viewable rows
    #
    set data(viewableRowList) {-1}

    #
    # Select those source elements that were selected before
    #
    foreach col $selectedCols {
	cellSelection $win set $target1 $col $target1 $col
    }

    #
    # Restore the edit window if it was present before
    #
    if {$editCol >= 0} {
	if {$editRow == $source} {
	    doEditCell $win $target1 $editCol 1
	} else {
	    set data(editRow) [keyToRow $win $editKey]
	}
    }

    if {$withDescendants} {
	#
	# Save the source node's list of children and temporarily empty it
	#
	set sourceChildList $data($sourceKey-children)
	set data($sourceKey-children) {}

	#
	# Move the source item's descendants
	#
	if {$source < $target} {
	    set lastDescRow [expr {$source + $sourceDescCount - 1}]
	    set increment -1
	} else {
	    set lastDescRow [expr {$source + $sourceDescCount}]
	    set increment 0
	}
	for {set n 0; set descRow $lastDescRow} {$n < $sourceDescCount} \
	    {incr n; incr descRow $increment} {
	    set indentImg [doCellCget $descRow $treeCol $win -indent]
	    if {[regexp {^(.+Img)([0-9]+)$} $indentImg dummy base descDepth]} {
		incr descDepth [expr {$depth - $sourceDepth}]
		if {$descDepth > $maxIndentDepths($treeStyle)} {
		    for {set d $descDepth} {$d > $maxIndentDepths($treeStyle)} \
			{incr d -1} {
			createTreeImgs $treeStyle $d
		    }
		    set maxIndentDepths($treeStyle) $descDepth
		}
		set descKey [lindex $data(keyList) $descRow]
		set data($descKey,$treeCol-indent) $base$descDepth
	    }

	    moveNode $win $descRow $sourceKey end 0
	}

	#
	# Restore the source node's list of children
	#
	set data($sourceKey-children) $sourceChildList

	#
	# Adjust the columns, restore the stripes in the body text widget,
	# redisplay the line numbers (if any), and update the view
	#
	adjustColumns $win $treeCol 1
	adjustElidedText $win
	redisplayVisibleItems $win
	makeStripes $win
	showLineNumbersWhenIdle $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
    }

    #
    # (Un)hide the newline character that ends the
    # last line if the line itself is (not) hidden
    #
    foreach tag {elidedRow hiddenRow} {
	if {[lsearch -exact [$w tag names end-1l] $tag] >= 0} {
	    $w tag add $tag end-1$pu
	} else {
	    $w tag remove $tag end-1$pu
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::moveCol
#
# Processes the tablelist movecolumn subcommand.
#------------------------------------------------------------------------------
proc tablelist::moveCol {win source target} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs
    if {$data(isDisabled)} {
	return ""
    }

    #
    # Check the indices
    #
    if {$target == $source || $target == $source + 1} {
	return ""
    }

    if {[winfo viewable $win]} {
	purgeWidgets $win
	update idletasks
	if {[destroyed $win]} {
	    return ""
	}
    }

    #
    # Update the column list
    #
    set source3 [expr {3*$source}]
    set source3Plus2 [expr {$source3 + 2}]
    set target1 $target
    if {$source < $target} {
	incr target1 -1
    }
    set target3 [expr {3*$target1}]
    set sourceRange [lrange $data(-columns) $source3 $source3Plus2]
    set data(-columns) [lreplace $data(-columns) $source3 $source3Plus2]
    set data(-columns) [eval linsert {$data(-columns)} $target3 $sourceRange]

    #
    # Save some elements of data and attribs corresponding to source
    #
    array set tmpData [array get data $source-*]
    array set tmpData [array get data hk*,$source-*]
    array set tmpData [array get data k*,$source-*]
    foreach specialCol {activeCol anchorCol editCol -treecolumn treeCol} {
	set tmpData($specialCol) $data($specialCol)
    }
    array set tmpAttribs [array get attribs $source-*]
    array set tmpAttribs [array get attribs k*,$source-*]
    set selCells [curCellSelection $win]
    set tmpRows [extractColFromCellList $selCells $source]

    #
    # Remove source from the list of stretchable columns
    # if it was explicitly specified as stretchable
    #
    if {[string compare $data(-stretch) "all"] != 0} {
	set sourceIsStretchable 0
	set stretchableCols {}
	foreach elem $data(-stretch) {
	    if {[string first $elem "end"] != 0 && $elem == $source} {
		set sourceIsStretchable 1
	    } else {
		lappend stretchableCols $elem
	    }
	}
	set data(-stretch) $stretchableCols
    }

    #
    # Build two lists of column numbers, needed
    # for shifting some elements of the data array
    #
    if {$source < $target} {
	for {set n $source} {$n < $target1} {incr n} {
	    lappend oldCols [expr {$n + 1}]
	    lappend newCols $n
	}
    } else {
	for {set n $source} {$n > $target} {incr n -1} {
	    lappend oldCols [expr {$n - 1}]
	    lappend newCols $n
	}
    }

    #
    # Remove the trace from the array element data(activeCol) because otherwise
    # the procedure moveColData won't work if the selection type is cell
    #
    trace vdelete data(activeCol) w [list tablelist::activeTrace $win]

    #
    # Move the elements of data and attribs corresponding
    # to the columns in oldCols to the elements corresponding
    # to the columns with the same indices in newCols
    #
    foreach oldCol $oldCols newCol $newCols {
	moveColData data data imgs $oldCol $newCol
	moveColAttribs attribs attribs $oldCol $newCol
	set selCells [replaceColInCellList $selCells $oldCol $newCol]
    }

    #
    # Move the elements of data and attribs corresponding
    # to source to the elements corresponding to target1
    #
    moveColData tmpData data imgs $source $target1
    moveColAttribs tmpAttribs attribs $source $target1
    set selCells [deleteColFromCellList $selCells $target1]
    foreach row $tmpRows {
	lappend selCells $row,$target1
    }

    #
    # If the column given by source was explicitly specified as
    # stretchable then add target1 to the list of stretchable columns
    #
    if {[string compare $data(-stretch) "all"] != 0 && $sourceIsStretchable} {
	lappend data(-stretch) $target1
	sortStretchableColList $win
    }

    #
    # Update the item list in the header text widget
    #
    set hdr_newItemList {}
    foreach item $data(hdr_itemList) {
	set sourceText [lindex $item $source]
	set item [lreplace $item $source $source]
	set item [linsert $item $target1 $sourceText]
	lappend hdr_newItemList $item
    }
    set data(hdr_itemList) $hdr_newItemList

    #
    # Update the item list in the body text widget
    #
    set newItemList {}
    foreach item $data(itemList) {
	set sourceText [lindex $item $source]
	set item [lreplace $item $source $source]
	set item [linsert $item $target1 $sourceText]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Set up and adjust the columns, and rebuild
    # the lists of the column fonts and tag names
    #
    setupColumns $win $data(-columns) 0
    makeColFontAndTagLists $win
    makeSortAndArrowColLists $win
    adjustColumns $win {} 0

    #
    # Redisplay the items
    #
    redisplay $win 0 $selCells
    hdr_updateColorsWhenIdle $win
    updateColorsWhenIdle $win

    #
    # Reconfigure the relevant column labels
    #
    foreach col [lappend newCols $target1] {
	reconfigColLabels $win imgs $col
    }

    #
    # Restore the trace set on the array element data(activeCol)
    # and enforce the execution of the activeTrace command
    #
    trace variable data(activeCol) w [list tablelist::activeTrace $win]
    set data(activeCol) $data(activeCol)

    return ""
}

Added libs/tablelist6.0/scripts/tablelistSort.tcl.































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
#==============================================================================
# Contains the implementation of the tablelist::sortByColumn and
# tablelist::addToSortColumns commands, as well as of the tablelist sort,
# sortbycolumn, and sortbycolumnlist subcommands.
#
# Structure of the module:
#   - Public procedures related to sorting
#   - Private procedures implementing the sorting
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Public procedures related to sorting
# ====================================
#

#------------------------------------------------------------------------------
# tablelist::sortByColumn
#
# Sorts the content of the tablelist widget win by its col'th column.  Returns
# the sort order (increasing or decreasing).
#------------------------------------------------------------------------------
proc tablelist::sortByColumn {win col} {
    #
    # Check the arguments
    #
    if {![winfo exists $win]} {
	return -code error "bad window path name \"$win\""
    }
    if {[string compare [winfo class $win] "Tablelist"] != 0} {
	return -code error "window \"$win\" is not a tablelist widget"
    }
    if {[catch {::$win columnindex $col} result] != 0} {
	return -code error $result
    }
    if {$result < 0 || $result >= [::$win columncount]} {
	return -code error "column index \"$col\" out of range"
    }
    set col $result
    if {[::$win columncget $col -showlinenumbers]} {
	return ""
    }

    #
    # Determine the sort order
    #
    if {[set idx [lsearch -exact [::$win sortcolumnlist] $col]] >= 0 &&
	[string compare [lindex [::$win sortorderlist] $idx] "increasing"]
	== 0} {
	set sortOrder decreasing
    } else {
	set sortOrder increasing
    }

    #
    # Sort the widget's content based on the given column
    #
    if {[catch {::$win sortbycolumn $col -$sortOrder} result] == 0} {
	set userData [list $col $sortOrder]
	genVirtualEvent $win <<TablelistColumnSorted>> $userData

	return $sortOrder
    } else {
	return -code error $result
    }
}

#------------------------------------------------------------------------------
# tablelist::addToSortColumns
#
# Adds the col'th column of the tablelist widget win to the latter's list of
# sort columns and sorts the content of the widget by the modified column
# list.  Returns the specified column's sort order (increasing or decreasing).
#------------------------------------------------------------------------------
proc tablelist::addToSortColumns {win col} {
    #
    # Check the arguments
    #
    if {![winfo exists $win]} {
	return -code error "bad window path name \"$win\""
    }
    if {[string compare [winfo class $win] "Tablelist"] != 0} {
	return -code error "window \"$win\" is not a tablelist widget"
    }
    if {[catch {::$win columnindex $col} result] != 0} {
	return -code error $result
    }
    if {$result < 0 || $result >= [::$win columncount]} {
	return -code error "column index \"$col\" out of range"
    }
    set col $result
    if {[::$win columncget $col -showlinenumbers]} {
	return ""
    }

    #
    # Update the lists of sort columns and orders
    #
    set sortColList [::$win sortcolumnlist]
    set sortOrderList [::$win sortorderlist]
    if {[set idx [lsearch -exact $sortColList $col]] >= 0} {
	if {[string compare [lindex $sortOrderList $idx] "increasing"] == 0} {
	    set sortOrder decreasing
	} else {
	    set sortOrder increasing
	}
	set sortOrderList [lreplace $sortOrderList $idx $idx $sortOrder]
    } else {
	lappend sortColList $col
	lappend sortOrderList increasing
	set sortOrder increasing
    }

    #
    # Sort the widget's content according to the
    # modified lists of sort columns and orders
    #
    if {[catch {::$win sortbycolumnlist $sortColList $sortOrderList} result]
	== 0} {
	set userData [list $sortColList $sortOrderList]
	genVirtualEvent $win <<TablelistColumnsSorted>> $userData

	return $sortOrder
    } else {
	return -code error $result
    }
}

#
# Private procedures implementing the sorting
# ===========================================
#

#------------------------------------------------------------------------------
# tablelist::sortItems
#
# Processes the tablelist sort, sortbycolumn, and sortbycolumnlist subcommands.
#------------------------------------------------------------------------------
proc tablelist::sortItems {win parentKey sortColList sortOrderList} {
    variable canElide
    variable snipSides
    upvar ::tablelist::ns${win}::data data

    set sortAllItems [expr {[string compare $parentKey "root"] == 0}]
    if {[winfo viewable $win] && $sortAllItems} {
	purgeWidgets $win
	update idletasks
	if {[destroyed $win]} {
	    return ""
	}
    }

    #
    # Make sure sortOrderList has the same length as sortColList
    #
    set sortColCount [llength $sortColList]
    set sortOrderCount [llength $sortOrderList]
    if {$sortOrderCount < $sortColCount} {
	for {set n $sortOrderCount} {$n < $sortColCount} {incr n} {
	    lappend sortOrderList increasing
	}
    } else {
	set sortOrderList [lrange $sortOrderList 0 [expr {$sortColCount - 1}]]
    }

    #
    # Save the keys corresponding to anchorRow and activeRow,
    # as well as the indices of the selected cells
    #
    foreach type {anchor active} {
	set ${type}Key [lindex $data(keyList) $data(${type}Row)]
    }
    set selCells [curCellSelection $win 1]

    #
    # Save some data of the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editKey $data(editKey)
	saveEditData $win
    }

    #
    # Update the sort info and sort the item list
    #
    set descItemList {}
    if {[llength $sortColList] == 1 && [lindex $sortColList 0] == -1} {
	if {[string length $data(-sortcommand)] == 0} {
	    return -code error "value of the -sortcommand option is empty"
	}

	set order [lindex $sortOrderList 0]

	if {$sortAllItems} {
	    #
	    # Update the sort info
	    #
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set data($col-sortRank) 0
		set data($col-sortOrder) ""
	    }
	    set data(sortColList) {}
	    set data(arrowColList) {}
	    set data(sortOrder) $order
	}

	#
	# Sort the child item list
	#
	sortChildren $win $parentKey [list lsort -$order -command \
	    $data(-sortcommand)] descItemList
    } else {					;# sorting by a column (list)
	#
	# Check the specified column indices
	#
	set sortColCount2 $sortColCount
	foreach col $sortColList {
	    if {$data($col-showlinenumbers)} {
		incr sortColCount2 -1
	    }
	}
	if {$sortColCount2 == 0} {
	    return ""
	}

	if {$sortAllItems} {
	    #
	    # Update the sort info
	    #
	    for {set col 0} {$col < $data(colCount)} {incr col} {
		set data($col-sortRank) 0
		set data($col-sortOrder) ""
	    }
	    set rank 1
	    foreach col $sortColList order $sortOrderList {
		if {$data($col-showlinenumbers)} {
		    continue
		}

		set data($col-sortRank) $rank
		set data($col-sortOrder) $order
		incr rank
	    }
	    makeSortAndArrowColLists $win
	}

	#
	# Sort the child item list based on the specified columns
	#
	for {set idx [expr {$sortColCount - 1}]} {$idx >= 0} {incr idx -1} {
	    set col [lindex $sortColList $idx]
	    if {$data($col-showlinenumbers)} {
		continue
	    }

	    set descItemList {}
	    set order [lindex $sortOrderList $idx]
	    if {[string compare $data($col-sortmode) "command"] == 0} {
		if {![info exists data($col-sortcommand)]} {
		    return -code error "value of the -sortcommand option for\
					column $col is missing or empty"
		}

		sortChildren $win $parentKey [list lsort -$order -index $col \
		    -command $data($col-sortcommand)] descItemList
	    } elseif {[string compare $data($col-sortmode) "asciinocase"]
		== 0} {
		if {$::tcl_version >= 8.5} {
		    sortChildren $win $parentKey [list lsort -$order \
			-index $col -ascii -nocase] descItemList
		} else {
		    sortChildren $win $parentKey [list lsort -$order \
			-index $col -command compareNoCase] descItemList
		}
	    } else {
		sortChildren $win $parentKey [list lsort -$order -index $col \
		    -$data($col-sortmode)] descItemList
	    }
	}
    }

    if {$sortAllItems} {
	#
	# Cancel the execution of all delayed
	# redisplay and redisplayCol commands
	#
	foreach name [array names data *redispId] {
	    after cancel $data($name)
	    unset data($name)
	}

	set canvasWidth $data(arrowWidth)
	if {[llength $data(arrowColList)] > 1} {
	    incr canvasWidth 6
	}
	foreach col $data(arrowColList) {
	    #
	    # Make sure the arrow will fit into the column
	    #
	    set idx [expr {2*$col}]
	    set pixels [lindex $data(colList) $idx]
	    if {$pixels == 0 && $data($col-maxPixels) > 0 &&
		$data($col-reqPixels) > $data($col-maxPixels) &&
		$data($col-maxPixels) < $canvasWidth} {
		set data($col-maxPixels) $canvasWidth
		set data($col-maxwidth) -$canvasWidth
	    }
	    if {$pixels != 0 && $pixels < $canvasWidth} {
		set data(colList) \
		    [lreplace $data(colList) $idx $idx $canvasWidth]
		set idx [expr {3*$col}]
		set data(-columns) \
		    [lreplace $data(-columns) $idx $idx -$canvasWidth]
	    }
	}

	#
	# Adjust the columns; this will also place the
	# canvas widgets into the corresponding labels
	#
	adjustColumns $win allLabels 1
    }

    if {[llength $descItemList] == 0} {
	return ""
    }

    set parentRow [keyToRow $win $parentKey]
    set firstDescRow [expr {$parentRow + 1}]
    set lastDescRow [expr {$parentRow + [descCount $win $parentKey]}]
    set firstDescLine [expr {$firstDescRow + 1}]
    set lastDescLine [expr {$lastDescRow + 1}]

    #
    # Update the line numbers (if any)
    #
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {!$data($col-showlinenumbers)} {
	    continue
	}

	set newDescItemList {}
	set line $firstDescLine
	foreach item $descItemList {
	    set item [lreplace $item $col $col $line]
	    lappend newDescItemList $item
	    set key [lindex $item end]
	    if {![info exists data($key-hide)]} {
		incr line
	    }
	}
	set descItemList $newDescItemList
    }

    set data(itemList) [eval [list lreplace $data(itemList) \
	$firstDescRow $lastDescRow] $descItemList]

    #
    # Replace the content of the list variable if present
    #
    condUpdateListVar $win

    #
    # Delete the items from the body text widget and insert the sorted ones.
    # Interestingly, for a large number of items it is much more efficient
    # to empty each line individually than to invoke a global delete command.
    #
    variable pu
    set w $data(body)
    $w tag remove elidedRow $firstDescLine.0 $lastDescLine.end+1$pu
    $w tag remove hiddenRow $firstDescLine.0 $lastDescLine.end+1$pu
    for {set line $firstDescLine} {$line <= $lastDescLine} {incr line} {
	$w delete $line.0 $line.end
    }
    set snipStr $data(-snipstring)
    set rowTagRefCount $data(rowTagRefCount)
    set cellTagRefCount $data(cellTagRefCount)
    set isSimple [expr {$data(imgCount) == 0 && $data(winCount) == 0 &&
			$data(indentCount) == 0}]
    set padY [expr {[$w cget -spacing1] == 0}]
    set descKeyList {}
    for {set row $firstDescRow; set line $firstDescLine} \
	{$row <= $lastDescRow} {set row $line; incr line} {
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	lappend descKeyList $key
	set data($key-row) $row
	set dispItem [lrange $item 0 $data(lastCol)]
	if {$data(hasFmtCmds)} {
	    set dispItem [formatItem $win $key $row $dispItem]
	}
	if {[string match "*\t*" $dispItem]} {
	    set dispItem [mapTabs $dispItem]
	}

	#
	# Clip the elements if necessary and
	# insert them with the corresponding tags
	#
	if {$rowTagRefCount == 0} {
	    set hasRowFont 0
	} else {
	    set hasRowFont [info exists data($key-font)]
	}
	set col 0
	if {$isSimple} {
	    set insertArgs {}
	    set multilineData {}
	    foreach text $dispItem \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    set snipSide \
			$snipSides($alignment,$data($col-changesnipside))
		    if {$multiline} {
			set list [split $text "\n"]
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $cellFont \
				  $pixels $snipSide $snipStr]
		    } elseif {$data(-displayondemand)} {
			set text ""
		    } else {
			set text [strRange $win $text $cellFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		if {$multiline} {
		    lappend insertArgs "\t\t" $cellTags
		    lappend multilineData $col $text $cellFont $pixels \
					  $alignment
		} else {
		    lappend insertArgs "\t$text\t" $cellTags
		}

		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    if {[llength $insertArgs] != 0} {
		eval [list $w insert $line.0] $insertArgs
	    }

	    #
	    # Embed the message widgets displaying multiline elements
	    #
	    foreach {col text font pixels alignment} $multilineData {
		findTabs $win $w $line $col $col tabIdx1 tabIdx2
		set msgScript [list ::tablelist::displayText $win $key \
			       $col $text $font $pixels $alignment]
		$w window create $tabIdx2 \
			  -align top -pady $padY -create $msgScript
		$w tag add elidedWin $tabIdx2
	    }

	} else {
	    foreach text $dispItem \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Insert the text and the label or window
		# (if any) into the body text widget
		#
		appendComplexElem $win $key $row $col $text $pixels \
				  $alignment $snipStr $cellFont $cellTags $line

		incr col
	    }
	}

	if {$rowTagRefCount != 0} {
	    if {[info exists data($key-font)]} {
		$w tag add row-font-$data($key-font) $line.0 $line.end
	    }
	}

	if {[info exists data($key-elide)]} {
	    $w tag add elidedRow $line.0 $line.end+1$pu
	}
	if {[info exists data($key-hide)]} {
	    $w tag add hiddenRow $line.0 $line.end+1$pu
	}
    }

    set data(keyList) [eval [list lreplace $data(keyList) \
	$firstDescRow $lastDescRow] $descKeyList]

    if {$sortAllItems} {
	#
	# Validate the key -> row mapping
	#
	set data(keyToRowMapValid) 1
	if {[info exists data(mapId)]} {
	    after cancel $data(mapId)
	    unset data(mapId)
	}
    }

    #
    # Invalidate the list of row indices indicating the viewable rows
    #
    set data(viewableRowList) {-1}

    #
    # Select the cells that were selected before
    #
    foreach {key col} $selCells {
	set row [keyToRow $win $key]
	cellSelection $win set $row $col $row $col
    }

    #
    # Disable the body text widget if it was disabled before
    #
    if {$data(isDisabled)} {
	$w tag add disabled 1.0 end
	$w tag configure select -borderwidth 0
    }

    #
    # Update anchorRow and activeRow
    #
    foreach type {anchor active} {
	upvar 0 ${type}Key key2
	if {[string length $key2] != 0} {
	    set data(${type}Row) [keyToRow $win $key2]
	}
    }

    #
    # Bring the "most important" row into view if appropriate
    #
    if {$editCol >= 0} {
	set editRow [keyToRow $win $editKey]
	if {$editRow >= $firstDescRow && $editRow <= $lastDescRow} {
	    doEditCell $win $editRow $editCol 1
	}
    } else {
	set selRows [curSelection $win]
	if {[llength $selRows] == 1} {
	    set selRow [lindex $selRows 0]
	    set selKey [lindex $data(keyList) $selRow]
	    if {$selRow >= $firstDescRow && $selRow <= $lastDescRow &&
		![info exists data($selKey-elide)]} {
		seeRow $win $selRow
	    }
	} elseif {[string compare [focus -lastfor $w] $w] == 0} {
	    set activeKey [lindex $data(keyList) $data(activeRow)]
	    if {$data(activeRow) >= $firstDescRow &&
		$data(activeRow) <= $lastDescRow &&
		![info exists data($activeKey-elide)]} {
		seeRow $win $data(activeRow)
	    }
	}
    }

    #
    # Adjust the elided text and restore the stripes in the body text widget
    #
    adjustElidedText $win
    redisplayVisibleItems $win
    makeStripes $win
    adjustSepsWhenIdle $win
    updateVScrlbarWhenIdle $win

    #
    # Work around a Tk bug on Mac OS X Aqua
    #
    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	foreach col $data(arrowColList) {
	    set canvas [list $data(hdrTxtFrmCanv)$col]
	    after idle [list lower $canvas]
	    after idle [list raise $canvas]
	}
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::sortChildren
#
# Sorts the children of a given parent within the tablelist widget win,
# recursively.
#------------------------------------------------------------------------------
proc tablelist::sortChildren {win parentKey sortCmd itemListName} {
    upvar $itemListName itemList ::tablelist::ns${win}::data data

    set childKeyList $data($parentKey-children)
    if {[llength $childKeyList] == 0} {
	return ""
    }

    #
    # Build and sort the list of child items
    #
    set childItemList {}
    foreach childKey $childKeyList {
	lappend childItemList [lindex $data(itemList) [keyToRow $win $childKey]]
    }
    set childItemList [eval $sortCmd [list $childItemList]]

    #
    # Update the lists and invoke the procedure recursively for the children
    #
    set data($parentKey-children) {}
    foreach item $childItemList {
	lappend itemList $item
	set childKey [lindex $item end]
	lappend data($parentKey-children) $childKey

	sortChildren $win $childKey $sortCmd itemList
    }
}

#------------------------------------------------------------------------------
# tablelist::sortList
#
# Sorts the specified list by the current sort columns of the tablelist widget
# win, using their current sort orders.
#------------------------------------------------------------------------------
proc tablelist::sortList {win list} {
    upvar ::tablelist::ns${win}::data data
    set sortColList $data(sortColList)
    set sortOrderList {}
    foreach col $sortColList {
	lappend sortOrderList $data($col-sortOrder)
    }

    if {[llength $sortColList] == 1 && [lindex $sortColList 0] == -1} {
	if {[string length $data(-sortcommand)] == 0} {
	    return -code error "value of the -sortcommand option is empty"
	}

	#
	# Sort the list
	#
	set order [lindex $sortOrderList 0]
	return [lsort -$order -command $data(-sortcommand) $list]
    } else {
	#
	# Sort the list based on the specified columns
	#
	set sortColCount [llength $sortColList]
	for {set idx [expr {$sortColCount - 1}]} {$idx >= 0} {incr idx -1} {
	    set col [lindex $sortColList $idx]
	    set order [lindex $sortOrderList $idx]

	    if {[string compare $data($col-sortmode) "command"] == 0} {
		if {![info exists data($col-sortcommand)]} {
		    return -code error "value of the -sortcommand option for\
					column $col is missing or empty"
		}

		set list [lsort -$order -index $col -command \
			  $data($col-sortcommand) $list]
	    } elseif {[string compare $data($col-sortmode) "asciinocase"]
		== 0} {
		if {$::tcl_version >= 8.5} {
		    set list [lsort -$order -index $col -ascii -nocase $list]
		} else {
		    set list [lsort -$order -index $col -command \
			      compareNoCase $list]
		}
	    } else {
		set list [lsort -$order -index $col -$data($col-sortmode) $list]
	    }
	}

	return $list
    }
}

#------------------------------------------------------------------------------
# tablelist::compareNoCase
#
# Compares the given strings in a case-insensitive manner.
#------------------------------------------------------------------------------
proc tablelist::compareNoCase {str1 str2} {
    return [string compare [string tolower $str1] [string tolower $str2]]
}

Added libs/tablelist6.0/scripts/tablelistThemes.tcl.









































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
#==============================================================================
# Contains procedures that populate the array themeDefaults with theme-specific
# default values of some tablelist configuration options.
#
# Structure of the module:
#   - Public procedures related to tile themes
#   - Private procedures related to tile themes
#   - Private procedures performing RGB <-> HSV conversions
#   - Private procedures related to global KDE configuration options
#
# Copyright (c) 2005-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Public procedures related to tile themes
# ========================================
#

#------------------------------------------------------------------------------
# tablelist::setThemeDefaults
#
# Populates the array themeDefaults with theme-specific default values of some
# tablelist configuration options and updates the array configSpecs.
#------------------------------------------------------------------------------
proc tablelist::setThemeDefaults {} {
    variable themeDefaults
    if {[catch {[getCurrentTheme]Theme}] != 0} {
	#
	# Fall back to the "default" theme (which is the root of all
	# themes) and then override the options set by the current one
	#
	defaultTheme 
	array set themeDefaults [style configure .]
    }

    if {[string length $themeDefaults(-arrowcolor)] == 0} {
	set themeDefaults(-arrowdisabledcolor) ""
    } else {
	set themeDefaults(-arrowdisabledcolor) $themeDefaults(-labeldisabledFg)
    }

    variable configSpecs
    foreach opt {-background -foreground -disabledforeground -stripebackground
		 -selectbackground -selectforeground -selectborderwidth -font
		 -labelforeground -labelfont -labelborderwidth -labelpady
		 -arrowcolor -arrowdisabledcolor -arrowstyle -treestyle} {
	if {[llength $configSpecs($opt)] < 4} {
	    lappend configSpecs($opt) $themeDefaults($opt)
	} else {
	    lset configSpecs($opt) 3 $themeDefaults($opt)
	}
    }
}

#
# Private procedures related to tile themes
# =========================================
#

#------------------------------------------------------------------------------
# tablelist::altTheme
#------------------------------------------------------------------------------
proc tablelist::altTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#d9d9d9 \
	-labeldeactivatedBg	#d9d9d9 \
	-labeldisabledBg	#d9d9d9 \
	-labelactiveBg		#ececec \
	-labelpressedBg		#ececec \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::aquaTheme
#------------------------------------------------------------------------------
proc tablelist::aquaTheme {} {
    scan $::tcl_platform(osVersion) "%d" majorOSVersion
    if {$majorOSVersion >= 14} {			;# OS X 10.10 or higher
	set labelBg		#f4f4f4
	set labeldeactivatedBg	#ffffff
	set labeldisabledBg	#ffffff
	set labelpressedBg	#e4e4e4
	set arrowColor		#404040
    } elseif {$majorOSVersion >= 11} {			;# OS X 10.7 or higher
	set labelBg		#efefef
	set labeldeactivatedBg	#efefef
	set labeldisabledBg	#efefef
	set labelpressedBg	#cbcbcb
	set arrowColor		#777777
    } else {
	set labelBg		#e9e8e8
	set labeldeactivatedBg	#e9e8e8
	set labeldisabledBg	#e9e8e8
	set labelpressedBg	#d2d2d2
	set arrowColor		#717171
    }

    switch [winfo rgb . systemMenuActive] {
	"13621 29041 52685" -
	"32256 44288 55552" {				;# Blue Cocoa/Carbon
	    if {$majorOSVersion >= 14} {		;# OS X 10.10 or higher
		set stripeBg			#f2f2f2
		set labelselectedBg		#f4f4f4
		set labelselectedpressedBg	#e4e4e4
	    } elseif {$majorOSVersion >= 11} {		;# OS X 10.7 or higher
		set stripeBg			#f0f4f9
		set labelselectedBg		#80b8f0
		set labelselectedpressedBg	#417ddc
	    } else {
		set stripeBg			#edf3fe
		set labelselectedBg		#7ab2e9
		set labelselectedpressedBg	#679ed5
	    }
	}

	"24415 27499 31354" -
	"39680 43776 48384" {				;# Graphite Cocoa/Carbon
	    if {$majorOSVersion >= 14} {		;# OS X 10.10 or higher
		set stripeBg			#f2f2f2
		set labelselectedBg		#f4f4f4
		set labelselectedpressedBg	#e4e4e4
	    } elseif {$majorOSVersion >= 11} {		;# OS X 10.7 or higher
		set stripeBg			#f4f5f7
		set labelselectedBg		#9ba7b5
		set labelselectedpressedBg	#636e88
	    } else {
		set stripeBg			#f0f0f0
		set labelselectedBg		#b6c2cd
		set labelselectedpressedBg	#a7b3be
	    }
	}
    }

    #
    # Get an approximation of alternateSelectedControlColor
    #
    switch [winfo rgb . systemHighlight] {
	"65535 48058 47288"	{ set selectBg #fc2125 }
	"65535 57311 46003"	{ set selectBg #fd8208 }
	"65535 61423 45231"	{ set selectBg #fec309 }
	"49343 63222 44460"	{ set selectBg #56d72b }
	"45746 55246 65535"	{ set selectBg #0950d0 }
	"63478 54484 65535"	{ set selectBg #bf57da }
	"65535 49087 53969"	{ set selectBg #7b0055 }
	"60909 57053 51914"	{ set selectBg #90714c }
	"55512 55512 56539"	{ set selectBg #5c5c60 }

	"51143 53456 56281"	{ set selectBg #738499 }
	"50887 50887 50887"	{ set selectBg #7f7f7f }
	"46516 54741 65535"	{ set selectBg #3875d7 }
	"64506 60908 29556"	{ set selectBg #ffc11f }
	"65535 45487 35978"	{ set selectBg #f34648 }
	"65535 53968 33154"	{ set selectBg #ff8a22 }
	"50114 63994 37263"	{ set selectBg #66c547 }
	"59879 47290 65535"	{ set selectBg #8c4eb8 }

	default {
	    set rgb [winfo rgb . systemHighlight]
	    foreach {h s v} [eval rgb2hsv $rgb] {}

	    set s [expr {$s*4.0/3.0}]
	    if {$s > 1.0} {
		set s 1.0
	    }

	    set v [expr {$v*3.0/4.0}]
	    if {$v > 1.0} {
		set v 1.0
	    }

	    set rgb [hsv2rgb $h $s $v]
	    set selectBg [eval format "#%04x%04x%04x" $rgb]
	}
    }

    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	$stripeBg \
	-selectbackground	$selectBg \
	-selectforeground	white \
	-selectborderwidth	0 \
	-font			{"Lucida Grande" 12} \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labeldeactivatedBg \
	-labeldisabledBg	$labeldisabledBg \
	-labelactiveBg		$labelBg \
	-labelpressedBg		$labelpressedBg \
	-labelselectedBg	$labelselectedBg \
	-labelselectedpressedBg	$labelselectedpressedBg \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelselectedFg	black \
	-labelselectedpressedFg	black \
	-labelfont		{"Lucida Grande" 11} \
	-labelborderwidth	1 \
	-labelpady		1 \
	-arrowcolor		$arrowColor \
	-treestyle		aqua \
    ]

    variable pngSupported
    if {$majorOSVersion >= 14} {			;# OS X 10.10 or higher
	set themeDefaults(-arrowstyle) flatAngle7x4
    } elseif {$pngSupported} {
	set themeDefaults(-arrowstyle) photo7x7
    } else {
	set themeDefaults(-arrowstyle) flat7x7
    }
}

#------------------------------------------------------------------------------
# tablelist::AquativoTheme
#------------------------------------------------------------------------------
proc tablelist::AquativoTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	black \
	-stripebackground	#edf3fe \
	-selectbackground	#000000 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#fafafa \
	-labeldeactivatedBg	#fafafa \
	-labeldisabledBg	#fafafa \
	-labelactiveBg		#fafafa \
	-labelpressedBg		#fafafa \
	-labelforeground	black \
	-labeldisabledFg	black \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		#717171 \
	-arrowstyle		flat7x7 \
	-treestyle		aqua \
    ]
}

#------------------------------------------------------------------------------
# tablelist::aquativoTheme
#------------------------------------------------------------------------------
proc tablelist::aquativoTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#565248 \
	-stripebackground	#edf3fe \
	-selectbackground	#000000 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#fafafa \
	-labeldeactivatedBg	#fafafa \
	-labeldisabledBg	#e3e1dd\
	-labelactiveBg		#c1d2ee \
	-labelpressedBg		#bab5ab \
	-labelforeground	black \
	-labeldisabledFg	#565248 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		#777777 \
	-arrowstyle		flat7x7 \
	-treestyle		aqua \
    ]
}

#------------------------------------------------------------------------------
# tablelist::ArcTheme
#------------------------------------------------------------------------------
proc tablelist::ArcTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		#5c616c \
	-disabledforeground	#a9acb2 \
	-stripebackground	"" \
	-selectbackground	#5294e2 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#f5f6f7 \
	-labeldeactivatedBg	#f5f6f7 \
	-labeldisabledBg	#fbfcfc \
	-labelactiveBg		#f5f6f7 \
	-labelpressedBg		#f5f6f7 \
	-labelforeground	#5c616c \
	-labeldisabledFg	#a9acb2 \
	-labelactiveFg		#5c616c \
	-labelpressedFg		#5c616c \
	-labelfont		TkDefaultFont \
	-labelborderwidth	0 \
	-labelpady		0 \
	-arrowcolor		#5c616c \
	-arrowstyle		flatAngle10x6 \
	-treestyle		arc \
    ]
}

#------------------------------------------------------------------------------
# tablelist::blueTheme
#------------------------------------------------------------------------------
proc tablelist::blueTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		#e6f3ff \
	-foreground		black \
	-disabledforeground	#666666 \
	-stripebackground	"" \
	-selectbackground	#ffff33 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#6699cc \
	-labeldeactivatedBg	#6699cc \
	-labeldisabledBg	#6699cc \
	-labelactiveBg		#6699cc \
	-labelpressedBg		#6699cc \
	-labelforeground	black \
	-labeldisabledFg	#666666 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	1 \
	-labelpady		1 \
	-arrowcolor		#2d2d66 \
	-arrowstyle		flat9x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::clamTheme
#------------------------------------------------------------------------------
proc tablelist::clamTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#999999 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#dcdad5 \
	-labeldeactivatedBg	#dcdad5 \
	-labeldisabledBg	#dcdad5 \
	-labelactiveBg		#eeebe7 \
	-labelpressedBg		#eeebe7 \
	-labelforeground	black \
	-labeldisabledFg	#999999 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		3 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::classicTheme
#------------------------------------------------------------------------------
proc tablelist::classicTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	"" \
	-selectbackground	#c3c3c3 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#d9d9d9 \
	-labeldeactivatedBg	#d9d9d9 \
	-labeldisabledBg	#d9d9d9 \
	-labelactiveBg		#ececec \
	-labelpressedBg		#ececec \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		"" \
	-arrowstyle		sunken10x9 \
	-treestyle		gtk \
    ]

    if {[info exists tile::version] &&
	[string compare $tile::version 0.8] < 0} {
	set themeDefaults(-font)	TkClassicDefaultFont
	set themeDefaults(-labelfont)	TkClassicDefaultFont
    }
}

#------------------------------------------------------------------------------
# tablelist::clearlooksTheme
#------------------------------------------------------------------------------
proc tablelist::clearlooksTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#b5b3ac \
	-stripebackground	"" \
	-selectbackground	#71869e \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#efeae6 \
	-labeldeactivatedBg	#efeae6 \
	-labeldisabledBg	#eee9e4 \
	-labelactiveBg		#f4f2ee \
	-labelpressedBg		#d4cfca \
	-labelforeground	black \
	-labeldisabledFg	#b5b3ac \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	0 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flatAngle9x6 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::defaultTheme
#------------------------------------------------------------------------------
proc tablelist::defaultTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#a3a3a3 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#d9d9d9 \
	-labeldeactivatedBg	#d9d9d9 \
	-labeldisabledBg	#d9d9d9 \
	-labelactiveBg		#ececec \
	-labelpressedBg		#ececec \
	-labelforeground	black \
	-labeldisabledFg	#a3a3a3 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	1 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::keramikTheme
#------------------------------------------------------------------------------
proc tablelist::keramikTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#aaaaaa \
	-stripebackground	"" \
	-selectbackground	#0a5f89 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#e2e4e7 \
	-labeldeactivatedBg	#e2e4e7 \
	-labeldisabledBg	#e2e4e7 \
	-labelactiveBg		#e2e4e7 \
	-labelpressedBg		#c6c8cc \
	-labelforeground	black \
	-labeldisabledFg	#aaaaaa \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	0 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat8x5 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::keramik_altTheme
#------------------------------------------------------------------------------
proc tablelist::keramik_altTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#aaaaaa \
	-stripebackground	"" \
	-selectbackground	#0a5f89 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#e2e4e7 \
	-labeldeactivatedBg	#e2e4e7 \
	-labeldisabledBg	#e2e4e7 \
	-labelactiveBg		#e2e4e7 \
	-labelpressedBg		#c6c8cc \
	-labelforeground	black \
	-labeldisabledFg	#aaaaaa \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	0 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat8x5 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::krocTheme
#------------------------------------------------------------------------------
proc tablelist::krocTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#b2b2b2 \
	-stripebackground	"" \
	-selectbackground	#000000 \
	-selectforeground	#ffffff \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#fcb64f \
	-labeldeactivatedBg	#fcb64f \
	-labeldisabledBg	#fcb64f \
	-labelactiveBg		#694418 \
	-labelpressedBg		#694418 \
	-labelforeground	black \
	-labeldisabledFg	#b2b2b2 \
	-labelactiveFg		#ffe7cb \
	-labelpressedFg		#ffe7cb \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::plastikTheme
#------------------------------------------------------------------------------
proc tablelist::plastikTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#aaaaaa \
	-stripebackground	"" \
	-selectbackground	#657a9e \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#dcdde3 \
	-labeldeactivatedBg	#dcdde3 \
	-labeldisabledBg	#dcdde3 \
	-labelactiveBg		#dcdde3 \
	-labelpressedBg		#b9bcc0 \
	-labelforeground	black \
	-labeldisabledFg	#aaaaaa \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	0 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x4 \
	-treestyle		plastik \
    ]
}

#------------------------------------------------------------------------------
# tablelist::srivTheme
#------------------------------------------------------------------------------
proc tablelist::srivTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		#e6f3ff \
	-foreground		black \
	-disabledforeground	#666666 \
	-stripebackground	"" \
	-selectbackground	#ffff33 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#a0a0a0 \
	-labeldeactivatedBg	#a0a0a0 \
	-labeldisabledBg	#a0a0a0 \
	-labelactiveBg		#a0a0a0 \
	-labelpressedBg		#a0a0a0 \
	-labelforeground	black \
	-labeldisabledFg	#666666 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::srivlgTheme
#------------------------------------------------------------------------------
proc tablelist::srivlgTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		#e6f3ff \
	-foreground		black \
	-disabledforeground	#666666 \
	-stripebackground	"" \
	-selectbackground	#ffff33 \
	-selectforeground	#000000 \
	-selectborderwidth	1 \
	-font			TkTextFont \
	-labelbackground	#6699cc \
	-labeldeactivatedBg	#6699cc \
	-labeldisabledBg	#6699cc \
	-labelactiveBg		#6699cc \
	-labelpressedBg		#6699cc \
	-labelforeground	black \
	-labeldisabledFg	#666666 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::stepTheme
#------------------------------------------------------------------------------
proc tablelist::stepTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#808080 \
	-stripebackground	"" \
	-selectbackground	#fdcd00 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#a0a0a0 \
	-labeldeactivatedBg	#a0a0a0 \
	-labeldisabledBg	#a0a0a0 \
	-labelactiveBg		#aeb2c3 \
	-labelpressedBg		#aeb2c3 \
	-labelforeground	black \
	-labeldisabledFg	#808080 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		black \
	-arrowstyle		flat7x5 \
	-treestyle		gtk \
    ]
}

#------------------------------------------------------------------------------
# tablelist::tileqtTheme
#
# Tested with the following Qt styles:
#
#   Acqua              KDE Classic                Motif Plus     RISC OS
#   B3/KDE             KDE_XP                     MS Windows 9x  SGI
#   Baghira            Keramik                    Oxygen         System-Series
#   CDE                Light Style, 2nd revision  Phase          System++
#   Cleanlooks         Light Style, 3rd revision  Plastik        ThinKeramik
#   GTK+ Style         Lipstik                    Plastique
#   HighColor Classic  Marble                     Platinum
#   HighContrast       Motif                      QtCurve
#
# Supported KDE 1/2/3 color schemes:
#
#   Aqua Blue                     Ice (FreddyK)     Point Reyes Green
#   Aqua Graphite                 KDE 1             Pumpkin
#   Atlas Green                   KDE 2             Redmond 2000
#   BeOS                          Keramik           Redmond 95
#   Blue Slate                    Keramik Emerald   Redmond XP
#   CDE                           Keramik White     Solaris
#   Dark Blue                     Lipstik Noble     Storm
#   Desert Red                    Lipstik Standard  SuSE, old & new
#   Digital CDE                   Lipstik White     SUSE-kdm
#   EveX                          Media Peach       System
#   High Contrast Black Text      Next              Thin Keramik, old & new
#   High Contrast Yellow on Blue  Pale Gray         Thin Keramik II
#   High Contrast White Text      Plastik
#
# Supported KDE 4 color schemes:
#
#   Honeycomb       Oxygen (= Standard)  Steel       Zion (Reversed)
#   Norway          Oxygen Cold          Wonton Soup
#   Obsidian Coast  Oxygen-Molecule 3.0  Zion
#------------------------------------------------------------------------------
proc tablelist::tileqtTheme {} {
    set bg		[tileqt_currentThemeColour -background]
    set fg		[tileqt_currentThemeColour -foreground]
    set tableBg		[tileqt_currentThemeColour -base]
    set tableFg		[tileqt_currentThemeColour -text]
    set tableDisFg	[tileqt_currentThemeColour -disabled -text]
    set selectBg	[tileqt_currentThemeColour -highlight]
    set selectFg	[tileqt_currentThemeColour -highlightedText]
    set labelBg		[tileqt_currentThemeColour -button]
    set labelFg		[tileqt_currentThemeColour -buttonText]
    set labelDisFg	[tileqt_currentThemeColour -disabled -buttonText]
    set style		[string tolower [tileqt_currentThemeName]]
    set pressedBg	$labelBg

    #
    # For most Qt styles the label colors depend on the color scheme:
    #
    switch "$bg $labelBg" {
	"#fafafa #6188d7" {	;# color scheme "Aqua Blue"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #d0d0d0 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #9ec2fa }
		"highcolor"	{ set labelBg #628ada;  set pressedBg #6188d7 }
		"keramik"	{ set labelBg #8fabe4;  set pressedBg #7390cc }
		"phase"		{ set labelBg #6188d7;  set pressedBg #d0d0d0 }
		"plastik"	{ set labelBg #666bd6;  set pressedBg #5c7ec2 }
		"qtcurve"	{ set labelBg #f4f4f4;  set pressedBg #d0d0d0 }
		"thinkeramik"	{ set labelBg #f4f4f4;  set pressedBg #dedede }
	    }
	}

	"#ffffff #89919b" {	;# color scheme "Aqua Graphite"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #d4d4d4 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #c3c7cd }
		"highcolor"	{ set labelBg #8b949e;  set pressedBg #89919b }
		"keramik"	{ set labelBg #acb1b8;  set pressedBg #91979e }
		"phase"		{ set labelBg #89919b;  set pressedBg #d4d4d4 }
		"plastik"	{ set labelBg #8c949d;  set pressedBg #7f868e }
		"qtcurve"	{ set labelBg #f6f6f6;  set pressedBg #d4d4d4 }
		"thinkeramik"	{ set labelBg #f4f4f4;  set pressedBg #e2e2e2 }
	    }
	}

	"#afb49f #afb49f" {	;# color scheme "Atlas Green"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #c1c6af }
		"platinum"			      { set pressedBg #929684 }
		"baghira"	{ set labelBg #e5e8dc;  set pressedBg #dadcd0 }
		"highcolor"	{ set labelBg #b2b6a1;  set pressedBg #afb49f }
		"keramik"	{ set labelBg #c7cabb;  set pressedBg #adb1a1 }
		"phase"		{ set labelBg #a7b49f;  set pressedBg #929684 }
		"plastik"	{ set labelBg #acb19c;  set pressedBg #959987 }
		"qtcurve"	{ set labelBg #adb19e;  set pressedBg #939881 }
		"thinkeramik"	{ set labelBg #c1c4b6;  set pressedBg #a5a999 }
	    }
	}

	"#d9d9d9 #d9d9d9" {	;# color scheme "BeOS"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #eeeeee }
		"platinum"			      { set pressedBg #b4b4b4 }
		"baghira"	{ set labelBg #f2f2f2;  set pressedBg #e9e9e9 }
		"highcolor"	{ set labelBg #dcdcdc;  set pressedBg #d9d9d9 }
		"keramik"	{ set labelBg #e5e5e5;  set pressedBg #cdcdcd }
		"phase"		{ set labelBg #dadada;  set pressedBg #b4b4b4 }
		"plastik"	{ set labelBg #d6d6d6;  set pressedBg #b6b6b6 }
		"qtcurve"	{ set labelBg #d6d6d6;  set pressedBg #b5b5b5 }
		"thinkeramik"	{ set labelBg #dddddd;  set pressedBg #c5c5c5 }
	    }
	}

	"#9db9c8 #9db9c8" {	;# color scheme "Blue Slate"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #adcbdc }
		"platinum"			      { set pressedBg #8299a6 }
		"baghira"	{ set labelBg #ddeff6;  set pressedBg #d0e1ea }
		"highcolor"	{ set labelBg #9fbbcb;  set pressedBg #9db9c8 }
		"keramik"	{ set labelBg #baced9;  set pressedBg #a0b5c1 }
		"phase"		{ set labelBg #9db9c9;  set pressedBg #8299a6 }
		"plastik"	{ set labelBg #99b6c5;  set pressedBg #869fab }
		"qtcurve"	{ set labelBg #9bb7c6;  set pressedBg #7c9cad }
		"thinkeramik"	{ set labelBg #b5c8d2;  set pressedBg #98adb8 }
	    }
	}

	"#999999 #999999" {	;# color scheme "CDE"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #a8a8a8 }
		"platinum"			      { set pressedBg #7f7f7f }
		"baghira"	{ set labelBg #d5d5d5;  set pressedBg #cccccc }
		"highcolor"	{ set labelBg #9b9b9b;  set pressedBg #999999 }
		"keramik"	{ set labelBg #b7b7b7;  set pressedBg #9d9d9d }
		"phase"		{ set labelBg #999999;  set pressedBg #7f7f7f }
		"plastik"	{ set labelBg #979797;  set pressedBg #808080 }
		"qtcurve"	{ set labelBg #979797;  set pressedBg #7f7f7f }
		"thinkeramik"	{ set labelBg #b3b3b3;  set pressedBg #959595 }
	    }
	}

	"#426794 #426794" {	;# color scheme "Dark Blue"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #4871a2 }
		"platinum"			      { set pressedBg #37567b }
		"baghira"	{ set labelBg #8aafdc;  set pressedBg #82a3cc }
		"highcolor"	{ set labelBg #436895;  set pressedBg #426794 }
		"keramik"	{ set labelBg #7994b4;  set pressedBg #5b7799 }
		"phase"		{ set labelBg #426795;  set pressedBg #37567b }
		"plastik"	{ set labelBg #406592;  set pressedBg #36547a }
		"qtcurve"	{ set labelBg #416692;  set pressedBg #3c5676 }
		"thinkeramik"	{ set labelBg #7991af;  set pressedBg #546f91 }
	    }
	}

	"#d6cdbb #d6cdbb" {	;# color scheme "Desert Red"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ebe1ce }
		"platinum"			      { set pressedBg #b2ab9c }
		"baghira"	{ set labelBg #f7f4ec;  set pressedBg #edeae0 }
		"highcolor"	{ set labelBg #d9d0be;  set pressedBg #d6cdbb }
		"keramik"	{ set labelBg #e3dcd0;  set pressedBg #cbc5b7 }
		"phase"		{ set labelBg #d6cdbb;  set pressedBg #b2ab9c }
		"plastik"	{ set labelBg #d3cbb8;  set pressedBg #bab3a3 }
		"qtcurve"	{ set labelBg #d4cbb8;  set pressedBg #b8ac94 }
		"thinkeramik"	{ set labelBg #dbd5ca;  set pressedBg #c2bbae }
	    }
	}

	"#4b7b82 #4b7b82" {	;# color scheme "Digital CDE"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #52878f }
		"platinum"			      { set pressedBg #3e666c }
		"baghira"	{ set labelBg #97c3c9;  set pressedBg #8eb6bc }
		"highcolor"	{ set labelBg #4b7d84;  set pressedBg #4b7b82 }
		"keramik"	{ set labelBg #80a2a7;  set pressedBg #62868c }
		"phase"		{ set labelBg #4b7b82;  set pressedBg #3e666c }
		"plastik"	{ set labelBg #49787f;  set pressedBg #3d666c }
		"qtcurve"	{ set labelBg #4a7980;  set pressedBg #416468 }
		"thinkeramik"	{ set labelBg #7f97a3;  set pressedBg #5a7e83 }
	    }
	}

	"#e6dedc #e4e4e4" {	;# color scheme "EveX"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fdf4f2 }
		"platinum"			      { set pressedBg #bfb8b7 }
		"baghira"	{ set labelBg #f6f5f5;  set pressedBg #ededed }
		"highcolor"	{ set labelBg #e7e7e7;  set pressedBg #e4e4e4 }
		"keramik"	{ set labelBg #ededed;  set pressedBg #d6d6d6 }
		"phase"		{ set labelBg #e7e0dd;  set pressedBg #bfb8b7 }
		"plastik"	{ set labelBg #e2e2e2;  set pressedBg #c0bfbf }
		"qtcurve"	{ set labelBg #e4dcd9;  set pressedBg #c5b7b4 }
		"thinkeramik"	{ set labelBg #e6e1df;  set pressedBg #c7c9c7 }
	    }
	}

	"#ffffff #ffffff" {	;# color scheme "High Contrast Black Text"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #d4d4d4 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f2f2f2 }
		"highcolor"	{ set labelBg #f5f5f5;  set pressedBg #ffffff }
		"keramik"	{ set labelBg #fbfbfb;  set pressedBg #e8e8e8 }
		"phase"		{ set labelBg #f7f7f7;  set pressedBg #d4d4d4 }
		"plastik"	{ set labelBg #f8f8f8;  set pressedBg #d8d8d8 }
		"qtcurve"	{ set labelBg #f6f6f6;  set pressedBg #d6d6d6 }
		"thinkeramik"	{ set labelBg #f4f4f4;  set pressedBg #e2e2e2 }
	    }
	}

	"#0000ff #0000ff" {	;# color scheme "High Contrast Yellow on Blue"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #1919ff }
		"platinum"			      { set pressedBg #0000d4 }
		"baghira"	{ set labelBg #4848ff;  set pressedBg #4646ff }
		"highcolor"	{ set labelBg #0e0ef5;  set pressedBg #0000ff }
		"keramik"	{ set labelBg #4949fb;  set pressedBg #2929e8 }
		"phase"		{ set labelBg #0909f7;  set pressedBg #0000d4 }
		"plastik"	{ set labelBg #0505f8;  set pressedBg #0000d8 }
		"qtcurve"	{ set labelBg #0909f2;  set pressedBg #0f0fc5 }
		"thinkeramik"	{ set labelBg #5151f4;  set pressedBg #2222e2 }
	    }
	}

	"#000000 #000000" {	;# color scheme "High Contrast White Text"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #000000 }
		"platinum"			      { set pressedBg #000000 }
		"baghira"	{ set labelBg #818181;  set pressedBg #7f7f7f }
		"highcolor"	{ set labelBg #000000;  set pressedBg #000000 }
		"keramik"	{ set labelBg #494949;  set pressedBg #292929 }
		"phase"		{ set labelBg #000000;  set pressedBg #000000 }
		"plastik"	{ set labelBg #000000;  set pressedBg #000000 }
		"qtcurve"	{ set labelBg #000000;  set pressedBg #000000 }
		"thinkeramik"	{ set labelBg #4d4d4d;  set pressedBg #222222 }
	    }
	}

	"#f6f6ff #e4eeff" {	;# color scheme "Ice (FreddyK)"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #cdcdd4 }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f2f4f6 }
		"highcolor"	{ set labelBg #e8edf5;  set pressedBg #e4eeff }
		"keramik"	{ set labelBg #edf3fb;  set pressedBg #d6dde8 }
		"phase"		{ set labelBg #f3f3f7;  set pressedBg #cdcdd4 }
		"plastik"	{ set labelBg #e3eaf8;  set pressedBg #c0c9d8 }
		"qtcurve"	{ set labelBg #ebebfc;  set pressedBg #b3b3f0 }
		"thinkeramik"	{ set labelBg #f1f1f4;  set pressedBg #dbdbe2 }
	    }
	}

	"#c0c0c0 #c0c0c0" {	;# color schemes "KDE 1" and "Storm"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #d3d3d3 }
		"platinum"			      { set pressedBg #a0a0a0 }
		"baghira"	{ set labelBg #e9e9e9;  set pressedBg #dedede }
		"highcolor"	{ set labelBg #c2c2c2;  set pressedBg #c0c0c0 }
		"keramik"	{ set labelBg #d3d3d3;  set pressedBg #bababa }
		"phase"		{ set labelBg #c1c1c1;  set pressedBg #a0a0a0 }
		"plastik"	{ set labelBg #bebebe;  set pressedBg #a2a2a2 }
		"qtcurve"	{ set labelBg #bebebe;  set pressedBg #a0a0a0 }
		"thinkeramik"	{ set labelBg #cccccc;  set pressedBg #b2b2b2 }
	    }
	}

	"#dcdcdc #e4e4e4" {	;# color scheme "KDE 2"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #d3d3d3 }
		"platinum"			      { set pressedBg #b7b7b7 }
		"baghira"	{ set labelBg #f3f3f3;  set pressedBg #ededed }
		"highcolor"	{ set labelBg #e7e7e7;  set pressedBg #e4e4e4 }
		"keramik"	{ set labelBg #ededed;  set pressedBg #d6d6d6 }
		"phase"		{ set labelBg #dddddd;  set pressedBg #b7b7b7 }
		"plastik"	{ set labelBg #e2e2e2;  set pressedBg #c0c0c0 }
		"qtcurve"	{ set labelBg #d9d9d9;  set pressedBg #b8b8b8 }
		"thinkeramik"	{ set labelBg #dfdfdf;  set pressedBg #c7c7c7 }
	    }
	}

	"#eae9e8 #e6f0f9" {	;# color scheme "Keramik"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c3c2c1 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #f1f3f5 }
		"highcolor"	{ set labelBg #eaeef2;  set pressedBg #e6f0f9 }
		"keramik"	{ set labelBg #eef4f8;  set pressedBg #d7dfe5 }
		"phase"		{ set labelBg #ebeae9;  set pressedBg #c3c2c1 }
		"plastik"	{ set labelBg #e3ecf3;  set pressedBg #c0c9d2 }
		"qtcurve"	{ set labelBg #e8e6e6;  set pressedBg #c5c3c1 }
		"thinkeramik"	{ set labelBg #e8e8e7;  set pressedBg #d2d1d0 }
	    }
	}

	"#eeeee6 #eeeade" {	;# color scheme "Keramik Emerald"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffffc }
		"platinum"			      { set pressedBg #c6c6bf }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #efefef;  set pressedBg #c6c6bf }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #c9c6bc }
		"qtcurve"	{ set labelBg #ecece3;  set pressedBg #cdcdbb }
		"thinkeramik"	{ set labelBg #ebebe5;  set pressedBg #d5d5cf }
	    }
	}

	"#e9e9e9 #f6f6f6" {	;# color scheme "Keramik White"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c2c2c2 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #f1f1f1 }
		"highcolor"	{ set labelBg #f1f1f1;  set pressedBg #f6f6f6 }
		"keramik"	{ set labelBg #f7f7f7;  set pressedBg #e3e3e3 }
		"phase"		{ set labelBg #eaeaea;  set pressedBg #c2c2c2 }
		"plastik"	{ set labelBg #f1f1f1;  set pressedBg #cfcfcf }
		"qtcurve"	{ set labelBg #e6e6e6;  set pressedBg #c3c3c3 }
		"thinkeramik"	{ set labelBg #e8e8e8;  set pressedBg #d1d1d1 }
	    }
	}

	"#ebe9e9 #f6f4f4" {	;# color scheme "Lipstik Noble"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c3c1c1 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #f1f1f1 }
		"highcolor"	{ set labelBg #f1f0f0;  set pressedBg #f6f4f4 }
		"keramik"	{ set labelBg #f7f6f6;  set pressedBg #e3e1e1 }
		"phase"		{ set labelBg #f5f4f4;  set pressedBg #c3c1c1 }
		"plastik"	{ set labelBg #f2f2f2;  set pressedBg #d3d2d2 }
		"qtcurve"	{ set labelBg #e9e6e6;  set pressedBg #c5c1c1 }
		"thinkeramik"	{ set labelBg #e9e8e8;  set pressedBg #d3d1d1 }
	    }
	}

	"#eeeee6 #eeeade" {	;# color scheme "Lipstik Standard"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffffc }
		"platinum"			      { set pressedBg #c6c6bf }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #eeeade;  set pressedBg #c6c6bf }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #ccc9c0 }
		"qtcurve"	{ set labelBg #ecece3;  set pressedBg #ccccba }
		"thinkeramik"	{ set labelBg #ebebe5;  set pressedBg #d5d5cf }
	    }
	}

	"#eeeff2 #f7faff" {	;# color scheme "Lipstik White"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c6c7c9 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f2f2f3 }
		"highcolor"	{ set labelBg #f1f2f5;  set pressedBg #f1faff }
		"keramik"	{ set labelBg #f8f9fb;  set pressedBg #e3e5e8 }
		"phase"		{ set labelBg #f4f5f7;  set pressedBg #c6c7c9 }
		"plastik"	{ set labelBg #f3f4f7;  set pressedBg #d0d3d8 }
		"qtcurve"	{ set labelBg #ebecf0;  set pressedBg #c4c7ce }
		"thinkeramik"	{ set labelBg #ebecee;  set pressedBg #d5d6d8 }
	    }
	}

	"#f4ddb2 #f4ddb2" {	;# color scheme "Media Peach"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffebc7 }
		"platinum"			      { set pressedBg #cbb894 }
		"baghira"	{ set labelBg #fcfced;  set pressedBg #faf6df }
		"highcolor"	{ set labelBg #f0dbb6;  set pressedBg #f4ddb2 }
		"keramik"	{ set labelBg #f6e8c9;  set pressedBg #e1d0b0 }
		"phase"		{ set labelBg #f4ddb2;  set pressedBg #cbb894 }
		"plastik"	{ set labelBg #ffdbaf;  set pressedBg #d5c19c }
		"qtcurve"	{ set labelBg #f2dbaf;  set pressedBg #e0bd7f }
		"thinkeramik"	{ set labelBg #efe0c3;  set pressedBg #d9c8a7 }
	    }
	}

	"#a8a8a8 #a8a8a8" {	;# color scheme "Next"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #b8b8b8 }
		"platinum"			      { set pressedBg #8c8c8c }
		"baghira"	{ set labelBg #dedede;  set pressedBg #d3d3d3 }
		"highcolor"	{ set labelBg #aaaaaa;  set pressedBg #a8a8a8 }
		"keramik"	{ set labelBg #c2c2c2;  set pressedBg #a8a8a8 }
		"phase"		{ set labelBg #a9a9a9;  set pressedBg #8c8c8c }
		"plastik"	{ set labelBg #a5a5a5;  set pressedBg #898989 }
		"qtcurve"	{ set labelBg #a6a6a6;  set pressedBg #8d8d8d }
		"thinkeramik"	{ set labelBg #bdbdbd;  set pressedBg #a0a0a0 }
	    }
	}

	"#d6d6d6 #d6d6d6" {	;# color scheme "Pale Gray"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ebebeb }
		"platinum"			      { set pressedBg #b2b2b2 }
		"baghira"	{ set labelBg #f2f2f2;  set pressedBg #e8e8e8 }
		"highcolor"	{ set labelBg #d9d9d9;  set pressedBg #d6d6d6 }
		"keramik"	{ set labelBg #e3e3e3;  set pressedBg #cbcbcb }
		"phase"		{ set labelBg #d6d6d6;  set pressedBg #b2b2b2 }
		"plastik"	{ set labelBg #d3d3d3;  set pressedBg #bababa }
		"qtcurve"	{ set labelBg #d4d4d4;  set pressedBg #b1b1b1 }
		"thinkeramik"	{ set labelBg #dbdbdb;  set pressedBg #c2c2c2 }
	    }
	}

	"#efefef #dddfe4" {	;# color scheme "Plastik"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c7c7c7 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #ececee }
		"highcolor"	{ set labelBg #e0e1e7;  set pressedBg #dddfe4 }
		"keramik"	{ set labelBg #e8e9ed;  set pressedBg #d0d2d6 }
		"phase"		{ set labelBg #dee0e5;  set pressedBg #c7c7c7 }
		"plastik"	{ set labelBg #dbdde2;  set pressedBg #babcc0 }
		"qtcurve"	{ set labelBg #ececec;  set pressedBg #c9c9c9 }
		"thinkeramik"	{ set labelBg #ececec;  set pressedBg #d6d6d6 }
	    }
	}

	"#d3c5be #aba09a" {	;# color scheme "Point Reyes Green"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #e8d9d1 }
		"platinum"			      { set pressedBg #afa49e }
		"baghira"	{ set labelBg #f5efed;  set pressedBg #d7d0cd }
		"highcolor"	{ set labelBg #ada29d;  set pressedBg #aba09a }
		"keramik"	{ set labelBg #c4bcb8;  set pressedBg #aba29e }
		"phase"		{ set labelBg #d3c5be;  set pressedBg #afa49e }
		"plastik"	{ set labelBg #ab9f99;  set pressedBg #9b908a }
		"qtcurve"	{ set labelBg #d1c3bc;  set pressedBg #b3a197 }
		"thinkeramik"	{ set labelBg #d9d0cc;  set pressedBg #c0b6b1 }
	    }
	}

	"#eed8ae #eed8ae" {	;# color scheme "Pumpkin"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffe0c0 }
		"platinum"			      { set pressedBg #c6b390 }
		"baghira"	{ set labelBg #fcfbea;  set pressedBg #f9f4dd }
		"highcolor"	{ set labelBg #eed8b1;  set pressedBg #eed8ae }
		"keramik"	{ set labelBg #f3e4c6;  set pressedBg #ddcdad }
		"phase"		{ set labelBg #eed8ae;  set pressedBg #c6b390 }
		"plastik"	{ set labelBg #ebd5ac;  set pressedBg #cfbc96 }
		"qtcurve"	{ set labelBg #ebd6ab;  set pressedBg #d7b980 }
		"thinkeramik"	{ set labelBg #ebdcc0;  set pressedBg #d5c4a4 }
	    }
	}

	"#d4d0c8 #d4d0c8" {	;# color scheme "Redmond 2000"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #e9e5dc }
		"platinum"			      { set pressedBg #b0ada6 }
		"baghira"	{ set labelBg #f3f2ef;  set pressedBg #eae8e4 }
		"highcolor"	{ set labelBg #d7d3cb;  set pressedBg #d4d0c8 }
		"keramik"	{ set labelBg #e1ded9;  set pressedBg #cac7c1 }
		"phase"		{ set labelBg #d5d1c9;  set pressedBg #b0ada6 }
		"plastik"	{ set labelBg #d2cdc5;  set pressedBg #b2afa7 }
		"qtcurve"	{ set labelBg #d2cdc6;  set pressedBg #b4afa4 }
		"thinkeramik"	{ set labelBg #dad7d2;  set pressedBg #c1beb8 }
	    }
	}

	"#c3c3c3 #c3c3c3" {	;# color scheme "Redmond 95"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #d6d6d6 }
		"platinum"			      { set pressedBg #a2a2a2 }
		"baghira"	{ set labelBg #eaeaea;  set pressedBg #dfdfdf }
		"highcolor"	{ set labelBg #c5c5c5;  set pressedBg #c3c3c3 }
		"keramik"	{ set labelBg #d5d5d5;  set pressedBg #bdbdbd }
		"phase"		{ set labelBg #c4c4c4;  set pressedBg #a2a2a2 }
		"plastik"	{ set labelBg #c1c1c1;  set pressedBg #a3a3a3 }
		"qtcurve"	{ set labelBg #c1c1c1;  set pressedBg #a3a3a3 }
		"thinkeramik"	{ set labelBg #cecece;  set pressedBg #b5b5b5 }
	    }
	}

	"#eeeee6 #eeeade" {	;# color scheme "Redmond XP"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffffc }
		"platinum"			      { set pressedBg #c6c6bf }
		"baghira"	{ set labelBg #f6f6f6;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #efefe7;  set pressedBg #c6c6bf }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #c9c6bc }
		"qtcurve"	{ set labelBg #ecece3;  set pressedBg #cdcdbb }
		"thinkeramik"	{ set labelBg #ebebe5;  set pressedBg #d5d5cf }
	    }
	}

	"#aeb2c3 #aeb2c3" {	;# color scheme "Solaris"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #bfc3d6 }
		"platinum"			      { set pressedBg #9194a2 }
		"baghira"	{ set labelBg #e4e7ef;  set pressedBg #d9dbe4 }
		"highcolor"	{ set labelBg #b0b4c5;  set pressedBg #aeb2c3 }
		"keramik"	{ set labelBg #c6c9d5;  set pressedBg #adb0bd }
		"phase"		{ set labelBg #aeb2c3;  set pressedBg #9194a2 }
		"plastik"	{ set labelBg #abafc0;  set pressedBg #969aa9 }
		"qtcurve"	{ set labelBg #acb0c1;  set pressedBg #8d91a5 }
		"thinkeramik"	{ set labelBg #c0c3ce;  set pressedBg #a5a7b5 }
	    }
	}

	"#eeeaee #e6f0f9" {	;# color scheme "SuSE" old
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c6c3c6 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f1f3f5 }
		"highcolor"	{ set labelBg #eaeef2;  set pressedBg #e6f0f9 }
		"keramik"	{ set labelBg #eef4f8;  set pressedBg #d7dfe5 }
		"phase"		{ set labelBg #efecef;  set pressedBg #c6c3c6 }
		"plastik"	{ set labelBg #e3ecf3;  set pressedBg #c0c9d2 }
		"qtcurve"	{ set labelBg #ebe7eb;  set pressedBg #cac1ca }
		"thinkeramik"	{ set labelBg #ebe8eb;  set pressedBg #d5d2d5 }
	    }
	}

	"#eeeeee #f4f4f4" {	;# color scheme "SuSE" new
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c6c6c6 }
		"baghira"	{ set labelBg #f5f5f5;  set pressedBg #f1f1f1 }
		"highcolor"	{ set labelBg #f0f0f0;  set pressedBg #f4f4f4 }
		"keramik"	{ set labelBg #f6f6f6;  set pressedBg #e1e1e1 }
		"phase"		{ set labelBg #efefef;  set pressedBg #c6c6c6 }
		"plastik"	{ set labelBg #f0f0f0;  set pressedBg #cdcdcd }
		"qtcurve"	{ set labelBg #ebebeb;  set pressedBg #c7c7c7 }
		"thinkeramik"	{ set labelBg #ebebeb;  set pressedBg #d5d5d5 }
	    }
	}

	"#eaeaea #eaeaea" {	;# color scheme "SUSE-kdm"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #c3c3c3 }
		"baghira"	{ set labelBg #f4f4f4;  set pressedBg #efefef }
		"highcolor"	{ set labelBg #ececec;  set pressedBg #eaeaea }
		"keramik"	{ set labelBg #f1f1f1;  set pressedBg #dadada }
		"phase"		{ set labelBg #ebebeb;  set pressedBg #c3c3c3 }
		"plastik"	{ set labelBg #e7e7e7;  set pressedBg #c6c6c6 }
		"qtcurve"	{ set labelBg #e7e7e7;  set pressedBg #c4c4c4 }
		"thinkeramik"	{ set labelBg #e8e8e8;  set pressedBg #d2d2d2 }
	    }
	}

	"#d3d3d3 #d3d3d3" {	;# color scheme "System"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #e8e8e8 }
		"platinum"			      { set pressedBg #afafaf }
		"baghira"	{ set labelBg #f0f0f0;  set pressedBg #e6e6e6 }
		"highcolor"	{ set labelBg #d6d6d6;  set pressedBg #d3d3d3 }
		"keramik"	{ set labelBg #e1e1e1;  set pressedBg #c9c9c9 }
		"phase"		{ set labelBg #d2d2d2;  set pressedBg #afafaf }
		"plastik"	{ set labelBg #d0d0d0;  set pressedBg #b9b9b9 }
		"qtcurve"	{ set labelBg #d1d1d1;  set pressedBg #aeaeae }
		"thinkeramik"	{ set labelBg #d9d9d9;  set pressedBg #c0c0c0 }
	    }
	}

	"#e6e6de #f0f0ef" {	;# color scheme "Thin Keramik" old
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fdfdf4 }
		"platinum"			      { set pressedBg #bfbfb8 }
		"baghira"	{ set labelBg #f6f6f5;  set pressedBg #f0f0f0 }
		"highcolor"	{ set labelBg #eeeeee;  set pressedBg #f0f0ef }
		"keramik"	{ set labelBg #f4f4f4;  set pressedBg #dfdfde }
		"phase"		{ set labelBg #e7e7df;  set pressedBg #bfbfb8 }
		"plastik"	{ set labelBg #ededeb;  set pressedBg #cbcbc9 }
		"qtcurve"	{ set labelBg #e3e3db;  set pressedBg #c4c4b6 }
		"thinkeramik"	{ set labelBg #e6e6e1;  set pressedBg #cfcfc9 }
	    }
	}

	"#edede1 #f6f6e9" {	;# color scheme "Thin Keramik" new
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #fffff7 }
		"platinum"			      { set pressedBg #c5c5bb }
		"baghira"	{ set labelBg #f6f6f5;  set pressedBg #f3f3f1 }
		"highcolor"	{ set labelBg #f1f1ec;  set pressedBg #f6f6e9 }
		"keramik"	{ set labelBg #f7f7f0;  set pressedBg #e3e3da }
		"phase"		{ set labelBg #edede1;  set pressedBg #c5c5bb }
		"plastik"	{ set labelBg #f4f4e6;  set pressedBg #ddddd0 }
		"qtcurve"	{ set labelBg #ebebde;  set pressedBg #cbcbb3 }
		"thinkeramik"	{ set labelBg #eaeae3;  set pressedBg #d4d4cb }
	    }
	}

	"#f6f5e8 #eeeade" {	;# color scheme "Thin Keramik II"
	    switch -- $style {
		"light, 3rd revision"		      { set pressedBg #ffffff }
		"platinum"			      { set pressedBg #cdccc1 }
		"baghira"	{ set labelBg #f7f7f7;  set pressedBg #f3f2ee }
		"highcolor"	{ set labelBg #eeeae1;  set pressedBg #eeeade }
		"keramik"	{ set labelBg #f3f1e8;  set pressedBg #dddad1 }
		"phase"		{ set labelBg #f3f2e9;  set pressedBg #cdccc1 }
		"plastik"	{ set labelBg #ebe7dc;  set pressedBg #c9c6bc }
		"qtcurve"	{ set labelBg #f4f2e5;  set pressedBg #dbd8b6 }
		"thinkeramik"	{ set labelBg #f1f1e8;  set pressedBg #dbdad0 }
	    }
	}

	"#d4d7d0 #babdb7" {	;# color scheme "Honeycomb"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #b1b4ae }
		"plastique"	{ set labelBg #b8bbb5;  set pressedBg #c1c4be }
	    }
	}

	"#ebe2d2 #f7f2e8" {	;# color scheme "Norway"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #c8bba3 }
		"plastique"	{ set labelBg #f4f0e6;  set pressedBg #d6cfbf }
	    }
	}

	"#302f2f #403f3e" {	;# color scheme "Obsidian Coast"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #2a2929 }
		"plastique"	{ set labelBg #3f3e3d;  set pressedBg #2b2a2a }
	    }
	}

	"#d6d2d0 #dfdcd9" {	;# color schemes "Oxygen" and "Standard"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #b6aeaa }
		"plastique"	{ set labelBg #dddad7;  set pressedBg #c3bfbe }
	    }
	}

	"#e0dfde #e8e7e6" {	;# c. s. "Oxygen Cold" and "Oxygen-Molecule 3.0"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #bbb9b8 }
		"plastique"	{ set labelBg #e6e5e4;  set pressedBg #cdcccb }
	    }
	}

	"#e0dfd8 #e8e7df" {	;# color scheme "Steel"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #babab4 }
		"plastique"	{ set labelBg #e6e5dd;  set pressedBg #cdccc5 }
	    }
	}

	"#494e58 #525863" {	;# color scheme "Wonton Soup"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #3f444c }
		"plastique"	{ set labelBg #515762;  set pressedBg #424650 }
	    }
	}

	"#fcfcfc #ffffff" {	;# color scheme "Zion"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #dedede }
		"plastique"	{ set labelBg #f9f9f9;  set pressedBg #e5e5e5 }
	    }
	}

	"#101010 #000000" {	;# color scheme "Zion (Reversed)"
	    switch -- $style {
		"cde" -
		"motif"				      { set pressedBg #5e5e5e }
		"plastique"	{ set labelBg #000000;  set pressedBg #0e0e0e }
	    }
	}
    }

    #
    # For some Qt styles the label colors are independent of the color scheme:
    #
    switch -- $style {
	"acqua" {
	    set labelBg #e7e7e7;  set labelFg #000000;  set pressedBg #8fbeec
	}

	"gtk+" {
	    set labelBg #e8e7e6;			set pressedBg $labelBg
	}

	"kde_xp" {
	    set labelBg #ebeadb;  set labelFg #000000;  set pressedBg #faf8f3
	}

	"lipstik" -
	"oxygen" {
	    set labelBg $bg;				set pressedBg $labelBg
	}

	"marble" {
	    set labelBg #cccccc;  set labelFg $fg;      set pressedBg $labelBg
	}

	"riscos" {
	    set labelBg #dddddd;  set labelFg #000000;  set pressedBg $labelBg
	}

	"system" -
	"systemalt" {
	    set labelBg #cbcbcb;  set labelFg #000000;  set pressedBg $labelBg
	}
    }

    #
    # The stripe background color is specified
    # by a global KDE configuration option:
    #
    if {[info exists ::env(KDE_SESSION_VERSION)] &&
	$::env(KDE_SESSION_VERSION) ne ""} {
	set val [getKdeConfigVal "Colors:View" "BackgroundAlternate"]
    } else {
	set val [getKdeConfigVal "General" "alternateBackground"]
    }
    if {$val eq "" || [string index $val 0] eq "#"} {
	set stripeBg $val
    } elseif {[scan $val "%d,%d,%d" r g b] == 3} {
	set stripeBg [format "#%02x%02x%02x" $r $g $b]
    } else {
	set stripeBg ""
    }

    #
    # The arrow color and style depend mainly on the current Qt style:
    #
    switch -- $style {
	"highcontrast" -
	"light, 2nd revision" -
	"light, 3rd revision" -
	"lipstik" -
	"phase" -
	"plastik"	{ set arrowColor $labelFg; set arrowStyle flat7x4 }

	"baghira"	{ set arrowColor $labelFg; set arrowStyle flat7x7 }

	"cleanlooks" -
	"gtk+" -
	"oxygen"	{ set arrowColor $labelFg; set arrowStyle flatAngle9x6 }

	"phase"		{ set arrowColor $labelFg; set arrowStyle flat6x4 }

	"qtcurve"	{ set arrowColor $labelFg; set arrowStyle flatAngle7x5 }

	"keramik" -
	"thinkeramik"	{ set arrowColor $labelFg; set arrowStyle flat8x5 }

	default		{ set arrowColor "";	   set arrowStyle sunken12x11 }
    }

    #
    # The tree style depends on the current Qt style:
    #
    switch -- $style {
	"baghira" -
	"cde" -
	"motif"		{ set treeStyle baghira }
	"gtk+"		{ set treeStyle gtk }
	"oxygen"	{ set treeStyle oxygen2 }
	"phase"		{ set treeStyle phase }
	"plastik"	{ set treeStyle plastik }
	"plastique"	{ set treeStyle plastique }
	"qtcurve"	{ set treeStyle klearlooks }
	default		{ set treeStyle winnative }
    }

    variable themeDefaults
    array set themeDefaults [list \
	-background		$tableBg \
	-foreground		$tableFg \
	-disabledforeground	$tableDisFg \
	-stripebackground	$stripeBg \
	-selectbackground	$selectBg \
	-selectforeground	$selectFg \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labelBg \
	-labeldisabledBg	$labelBg \
	-labelactiveBg		$labelBg \
	-labelpressedBg		$pressedBg \
	-labelforeground	$labelFg \
	-labeldisabledFg	$labelDisFg \
	-labelactiveFg		$labelFg \
	-labelpressedFg		$labelFg \
	-labelfont		TkDefaultFont \
	-labelborderwidth	4 \
	-labelpady		0 \
	-arrowcolor		$arrowColor \
	-arrowstyle		$arrowStyle \
	-treestyle		$treeStyle \
    ]
}

#------------------------------------------------------------------------------
# tablelist::vistaTheme
#------------------------------------------------------------------------------
proc tablelist::vistaTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		SystemWindow \
	-foreground		SystemWindowText \
	-disabledforeground	SystemDisabledText \
	-stripebackground	"" \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelforeground	SystemButtonText \
	-labeldisabledFg	SystemDisabledText \
	-labelactiveFg		SystemButtonText \
	-labelpressedFg		SystemButtonText \
	-labelfont		TkDefaultFont \
    ]

    switch [winfo rgb . SystemHighlight] {
	"13107 39321 65535" {					;# Aero
	    set selectFg	SystemWindowText
	    set labelBd		4
	    set labelPadY	4

	    variable scalingpct
	    if {$::tcl_platform(osVersion) < 6.2} {		;# Win Vista/7
		set labelBg	#ffffff
		set activeBg	#e3f7ff
		set pressedBg	#Bce4f9
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set labelBg	#fcfcfc
		set activeBg	#f4f9ff
		set pressedBg	#f9fafb
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } else {						;# Win 10
		set labelBg	#ffffff
		set activeBg	#d9ebf9
		set pressedBg	#bcdcf4
		set arrowColor	#595959

		switch $scalingpct {
		    100 { set arrowStyle	flatAngle7x4 }
		    125 { set arrowStyle	flatAngle9x5 }
		    150 { set arrowStyle	flatAngle11x6 }
		    200 { set arrowStyle	flatAngle15x8 }
		}
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set selectBg	#d8effb
		set treeStyle	vistaAero
	    } elseif {$::tcl_platform(osVersion) == 6.1} {	;# Win 7
		set selectBg	#cee2fc
		set treeStyle	win7Aero
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set selectBg	#cbe8f6
		set treeStyle	win7Aero
	    } else {						;# Win 10
		set selectBg	#cce8ff
		set treeStyle	win10
	    }
	}

	default {						;# Win Classic
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		SystemButtonFace
	    set activeBg	SystemButtonFace
	    set pressedBg	SystemButtonFace
	    set labelBd		2
	    set labelPadY	0
	    set arrowColor	SystemButtonShadow

	    variable scalingpct
	    switch $scalingpct {
		100 { set arrowStyle	flat7x4 }
		125 { set arrowStyle	flat9x5 }
		150 { set arrowStyle	flat11x6 }
		200 { set arrowStyle	flat15x8 }
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set treeStyle	vistaClassic
	    } else {						;# Win 7/8
		set treeStyle	win7Classic
	    }
	}
    }

    array set themeDefaults [list \
	-selectbackground	$selectBg \
	-selectforeground	$selectFg \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labelBg \
	-labeldisabledBg	$labelBg \
	-labelactiveBg		$activeBg \
	-labelpressedBg		$pressedBg \
	-labelborderwidth	$labelBd \
	-labelpady		$labelPadY \
	-arrowcolor		$arrowColor \
	-arrowstyle		$arrowStyle \
	-treestyle		$treeStyle \
    ]
}

#------------------------------------------------------------------------------
# tablelist::winnativeTheme
#------------------------------------------------------------------------------
proc tablelist::winnativeTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		SystemWindow \
	-foreground		SystemWindowText \
	-disabledforeground	SystemDisabledText \
	-stripebackground	"" \
	-selectbackground	SystemHighlight \
	-selectforeground	SystemHighlightText \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	SystemButtonFace \
	-labeldeactivatedBg	SystemButtonFace \
	-labeldisabledBg	SystemButtonFace \
	-labelactiveBg		SystemButtonFace \
	-labelpressedBg		SystemButtonFace \
	-labelforeground	SystemButtonText \
	-labeldisabledFg	SystemDisabledText \
	-labelactiveFg		SystemButtonText \
	-labelpressedFg		SystemButtonText \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		0 \
	-arrowcolor		"" \
	-arrowstyle		sunken8x7 \
	-treestyle		winnative \
    ]
}

#------------------------------------------------------------------------------
# tablelist::winxpblueTheme
#------------------------------------------------------------------------------
proc tablelist::winxpblueTheme {} {
    variable themeDefaults
    array set themeDefaults [list \
	-background		white \
	-foreground		black \
	-disabledforeground	#565248 \
	-stripebackground	"" \
	-selectbackground	#4a6984 \
	-selectforeground	#ffffff \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelbackground	#ece9d8 \
	-labeldeactivatedBg	#ece9d8 \
	-labeldisabledBg	#e3e1dd \
	-labelactiveBg		#c1d2ee \
	-labelpressedBg		#bab5ab \
	-labelforeground	black \
	-labeldisabledFg	#565248 \
	-labelactiveFg		black \
	-labelpressedFg		black \
	-labelfont		TkDefaultFont \
	-labelborderwidth	2 \
	-labelpady		1 \
	-arrowcolor		#4d6185 \
	-arrowstyle		flat7x4 \
	-treestyle		winxpBlue \
    ]
}

#------------------------------------------------------------------------------
# tablelist::xpnativeTheme
#------------------------------------------------------------------------------
proc tablelist::xpnativeTheme {} {
    variable xpStyle
    variable themeDefaults
    array set themeDefaults [list \
	-background		SystemWindow \
	-foreground		SystemWindowText \
	-disabledforeground	SystemDisabledText \
	-stripebackground	"" \
	-selectborderwidth	0 \
	-font			TkTextFont \
	-labelforeground	SystemButtonText \
	-labeldisabledFg	SystemDisabledText \
	-labelactiveFg		SystemButtonText \
	-labelpressedFg		SystemButtonText \
	-labelfont		TkDefaultFont \
    ]

    switch [winfo rgb . SystemHighlight] {
	"12593 27242 50629" {					;# Win XP Blue
	    set xpStyle		1
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		#ebeadb
	    set activeBg	#faf8f3
	    set pressedBg	#dedfd8
	    set labelBd		4
	    set labelPadY	4
	    set arrowColor	#aca899
	    set arrowStyle	flat9x5
	    set treeStyle	winxpBlue

	    if {[info exists tile::version] &&
		[string compare $tile::version 0.7] < 0} {
		set labelBd 0
	    }
	}

	"37779 41120 28784" {					;# Win XP Olive
	    set xpStyle		1
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		#ebeadb
	    set activeBg	#faf8f3
	    set pressedBg	#dedfd8
	    set labelBd		4
	    set labelPadY	4
	    set arrowColor	#aca899
	    set arrowStyle	flat9x5
	    set treeStyle	winxpOlive

	    if {[info exists tile::version] &&
		[string compare $tile::version 0.7] < 0} {
		set labelBd 0
	    }
	}

	"45746 46260 49087" {					;# Win XP Silver
	    set xpStyle		1
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set labelBg		#f9fafd
	    set activeBg	#fefefe
	    set pressedBg	#ececf3
	    set labelBd		4
	    set labelPadY	4
	    set arrowColor	#aca899
	    set arrowStyle	flat9x5
	    set treeStyle	winxpSilver

	    if {[info exists tile::version] &&
		[string compare $tile::version 0.7] < 0} {
		set labelBd 0
	    }
	}

	"13107 39321 65535" {					;# Aero
	    set selectFg	SystemWindowText
	    set xpStyle		0
	    set labelBd		4
	    set labelPadY	4

	    variable scalingpct
	    if {$::tcl_platform(osVersion) < 6.2} {		;# Win Vista/7
		set labelBg	#ffffff
		set activeBg	#e3f7ff
		set pressedBg	#Bce4f9
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set labelBg	#fcfcfc
		set activeBg	#f4f9ff
		set pressedBg	#f9fafb
		set arrowColor	#569bc0

		switch $scalingpct {
		    100 { set arrowStyle	photo7x4 }
		    125 { set arrowStyle	photo9x5 }
		    150 { set arrowStyle	photo11x6 }
		    200 { set arrowStyle	photo15x8 }
		}
	    } else {						;# Win 10
		set labelBg	#ffffff
		set activeBg	#d9ebf9
		set pressedBg	#bcdcf4
		set arrowColor	#595959

		switch $scalingpct {
		    100 { set arrowStyle	flatAngle7x4 }
		    125 { set arrowStyle	flatAngle9x5 }
		    150 { set arrowStyle	flatAngle11x6 }
		    200 { set arrowStyle	flatAngle15x8 }
		}
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set selectBg	#d8effb
		set treeStyle	vistaAero
	    } elseif {$::tcl_platform(osVersion) == 6.1} {	;# Win 7
		set selectBg	#cee2fc
		set treeStyle	win7Aero
	    } elseif {$::tcl_platform(osVersion) < 10.0} {	;# Win 8
		set selectBg	#cbe8f6
		set treeStyle	win7Aero
	    } else {						;# Win 10
		set selectBg	#cce8ff
		set treeStyle	win10
	    }
	}

	default {						;# Win Classic
	    set selectBg	SystemHighlight
	    set selectFg	SystemHighlightText
	    set xpStyle		0
	    set labelBg		SystemButtonFace
	    set activeBg	SystemButtonFace
	    set pressedBg	SystemButtonFace
	    set labelBd		2
	    set labelPadY	0
	    set arrowColor	SystemButtonShadow

	    variable scalingpct
	    switch $scalingpct {
		100 { set arrowStyle	flat7x4 }
		125 { set arrowStyle	flat9x5 }
		150 { set arrowStyle	flat11x6 }
		200 { set arrowStyle	flat15x8 }
	    }

	    if {$::tcl_platform(osVersion) == 6.0} {		;# Win Vista
		set treeStyle	vistaClassic
	    } else {						;# Win 7/8
		set treeStyle	win7Classic
	    }
	}
    }

    array set themeDefaults [list \
	-selectbackground	$selectBg \
	-selectforeground	$selectFg \
	-labelbackground	$labelBg \
	-labeldeactivatedBg	$labelBg \
	-labeldisabledBg	$labelBg \
	-labelactiveBg		$activeBg \
	-labelpressedBg		$pressedBg \
	-labelborderwidth	$labelBd \
	-labelpady		$labelPadY \
	-arrowcolor		$arrowColor \
	-arrowstyle		$arrowStyle \
	-treestyle		$treeStyle \
    ]
}

#
# Private procedures performing RGB <-> HSV conversions
# =====================================================
#

#------------------------------------------------------------------------------
# tablelist::rgb2hsv
#
# Converts the specified RGB value to HSV.  The arguments are assumed to be
# integers in the interval [0, 65535].  The return value is a list of the form
# {h s v}, where h in [0.0, 360.0) and s, v in [0.0, 1.0].
#------------------------------------------------------------------------------
proc tablelist::rgb2hsv {r g b} {
    set r [expr {$r/65535.0}]
    set g [expr {$g/65535.0}]
    set b [expr {$b/65535.0}]

    #
    # Compute the value component
    #
    set sortedList [lsort -real [list $r $g $b]]
    set v [lindex $sortedList end]
    set dist [expr {$v - [lindex $sortedList 0]}]

    #
    # Compute the saturation component
    #
    if {$v == 0.0} {
	set s 0.0
    } else {
	set s [expr {$dist/$v}]
    }

    #
    # Compute the hue component
    #
    if {$s == 0.0} {
	set h 0.0
    } else {
	set rc [expr {($v - $r)/$dist}]
	set gc [expr {($v - $g)/$dist}]
	set bc [expr {($v - $b)/$dist}]

	if {$v == $r} {
	    set h [expr {$bc - $gc}]
	} elseif {$v == $g} {
	    set h [expr {2 + $rc - $bc}]
	} else {
	    set h [expr {4 + $gc - $rc}]
	}
	set h [expr {$h*60}]
	if {$h < 0.0} {
	    set h [expr {$h + 360.0}]
	} elseif {$h >= 360.0} {
	    set h 0.0
	}
    }

    return [list $h $s $v]
}

#------------------------------------------------------------------------------
# tablelist::hsv2rgb
#
# Converts the specified HSV value to RGB.  The arguments are assumed to fulfil
# the conditions: h in [0.0, 360.0) and s, v in [0.0, 1.0].  The return value
# is a list of the form {r g b}, where r, g, and b are integers in the interval
# [0, 65535].
#------------------------------------------------------------------------------
proc tablelist::hsv2rgb {h s v} {
    set h [expr {$h/60.0}]
    set f [expr {$h - floor($h)}]

    set p1 [expr {round(65535.0*$v*(1 - $s))}]
    set p2 [expr {round(65535.0*$v*(1 - $s*$f))}]
    set p3 [expr {round(65535.0*$v*(1 - $s*(1 - $f)))}]

    set v  [expr {round(65535.0*$v)}]

    switch [expr {int($h)}] {
	0 { return [list $v  $p3 $p1] }
	1 { return [list $p2 $v  $p1] }
	2 { return [list $p1 $v  $p3] }
	3 { return [list $p1 $p2 $v ] }
	4 { return [list $p3 $p1 $v ] }
	5 { return [list $v  $p1 $p2] }
    }
}

#
# Private procedures related to global KDE configuration options
# ==============================================================
#

#------------------------------------------------------------------------------
# tablelist::getKdeConfigVal
#
# Returns the value of the global KDE configuration option identified by the
# given group (section) and key.
#------------------------------------------------------------------------------
proc tablelist::getKdeConfigVal {group key} {
    variable kdeDirList

    if {![info exists kdeDirList]} {
	makeKdeDirList 
    }

    #
    # Search for the entry corresponding to the given group and key in
    # the file "share/config/kdeglobals" within the KDE directories
    #
    foreach dir $kdeDirList {
	set fileName [file join $dir "share/config/kdeglobals"]
	if {[set val [readKdeConfigVal $fileName $group $key]] ne ""} {
	    return $val
	}
    }
    return ""
}

#------------------------------------------------------------------------------
# tablelist::makeKdeDirList
#
# Builds the list of the directories to be considered when searching for global
# KDE configuration options.
#------------------------------------------------------------------------------
proc tablelist::makeKdeDirList {} {
    variable kdeDirList {}

    if {[info exists ::env(KDE_SESSION_VERSION)]} {
	set ver $::env(KDE_SESSION_VERSION)
    } else {
	set ver ""
    }

    if {[info exists ::env(USER)] && $::env(USER) eq "root"} {
	set name "KDEROOTHOME"
    } else {
	set name "KDEHOME"
    }
    if {[info exists ::env($name)] && $::env($name) ne ""} {
	set localKdeDir [file normalize $::env($name)]
    } elseif {[info exists ::env(HOME)] && $::env(HOME) ne ""} {
	set localKdeDir [file normalize [file join $::env(HOME) ".kde$ver"]]
    }
    if {[info exists localKdeDir] && $localKdeDir ne "-"} {
	lappend kdeDirList $localKdeDir
    }

    if {[info exists ::env(KDEDIRS)] && $::env(KDEDIRS) ne ""} {
	foreach dir [split $::env(KDEDIRS) ":"] {
	    if {$dir ne ""} {
		lappend kdeDirList $dir
	    }
	}
    } elseif {[info exists ::env(KDEDIR)] && $::env(KDEDIR) ne ""} {
	lappend kdeDirList $::env(KDEDIR)
    }

    set prefix [exec kde$ver-config --expandvars --prefix]
    lappend kdeDirList $prefix

    set execPrefix [exec kde$ver-config --expandvars --exec-prefix]
    if {$execPrefix ne $prefix} {
	lappend kdeDirList $execPrefix
    }
}

#------------------------------------------------------------------------------
# tablelist::readKdeConfigVal
#
# Reads the value of the global KDE configuration option identified by the
# given group (section) and key from the specified file.  Note that the
# procedure performs a case-sensitive search and only works as expected for
# "simple" group and key names.
#------------------------------------------------------------------------------
proc tablelist::readKdeConfigVal {fileName group key} {
    if {[catch {open $fileName r} chan] != 0} {
	return ""
    }

    #
    # Search for the specified group
    #
    set groupFound 0
    while {[gets $chan line] >= 0} {
	set line [string trim $line]
	if {$line eq "\[$group\]"} {
	    set groupFound 1
	    break
	}
    }
    if {!$groupFound} {
	close $chan
	return ""
    }

    #
    # Search for the specified key within the group
    #
    set pattern "^$key\\s*=\\s*(.+)$"
    set keyFound 0
    while {[gets $chan line] >= 0} {
	set line [string trim $line]
	if {[string index $line 0] eq "\["} {
	    break
	}

	if {[regexp $pattern $line dummy val]} {
	    set keyFound 1
	    break
	}
    }

    close $chan
    return [expr {$keyFound ? $val : ""}]
}

Added libs/tablelist6.0/scripts/tablelistUtil.tcl.



































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
#==============================================================================
# Contains private utility procedures for tablelist widgets.
#
# Structure of the module:
#   - Namespace initialization
#   - Public utility procedure
#   - Private utility procedures
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Namespace initialization
# ========================
#

namespace eval tablelist {
    #
    # alignment -> anchor mapping
    #
    variable anchors
    array set anchors {
	left	w
	right	e
	center	center
    }

    #
    # <alignment, changeSnipSide> -> snipSide mapping
    #
    variable snipSides
    array set snipSides {
	left,0		r
	left,1		l
	right,0		l
	right,1		r
	center,0	r
	center,1	l
    }

    #
    # <incrArrowType, sortOrder> -> direction mapping
    #
    variable directions
    array set directions {
	up,increasing	Up
	up,decreasing	Dn
	down,increasing	Dn
	down,decreasing	Up
    }
}

#
# Public utility procedure
# ========================
#

#------------------------------------------------------------------------------
# tablelist::getCurrentTheme
#
# Returns the current tile theme.
#------------------------------------------------------------------------------
proc tablelist::getCurrentTheme {} {
    if {[info exists ttk::currentTheme]} {
	return $ttk::currentTheme
    } elseif {[info exists tile::currentTheme]} {
	return $tile::currentTheme
    } else {
	return ""
    }
}

#
# Private utility procedures
# ==========================
#

#------------------------------------------------------------------------------
# tablelist::destroyed
#
# Checks whether the tablelist widget win got destroyed by some custom script.
#------------------------------------------------------------------------------
proc tablelist::destroyed win {
    #
    # A bit safer than using "winfo exists", because the widget might have
    # been destroyed and its name reused for a new non-tablelist widget:
    #
    return [expr {![array exists ::tablelist::ns${win}::data]}]
}

#------------------------------------------------------------------------------
# tablelist::rowIndex
#
# Checks the row index idx and returns either its numerical value or an error.
# endIsSize must be a boolean value: if true, end refers to the number of items
# in the tablelist, i.e., to the item just after the last one; if false, end
# refers to 1 less than the number of items, i.e., to the last item in the
# tablelist.  checkRange must be a boolean value: if true, it is additionally
# checked whether the numerical value corresponding to idx is within the
# allowed range.
#------------------------------------------------------------------------------
proc tablelist::rowIndex {win idx endIsSize {checkRange 0}} {
    upvar ::tablelist::ns${win}::data data

    if {[isInteger $idx]} {
	set index [expr {int($idx)}]
    } elseif {[string first $idx "end"] == 0} {
	if {$endIsSize} {
	    set index $data(itemCount)
	} else {
	    set index $data(lastRow)
	}
    } elseif {[string first $idx "last"] == 0} {
	set index $data(lastRow)
    } elseif {[string first $idx "top"] == 0} {
	displayItems $win
	set textIdx [$data(body) index @0,0]
	set index [expr {int($textIdx) - 1}]
    } elseif {[string first $idx "bottom"] == 0} {
	displayItems $win
	set textIdx [$data(body) index @0,$data(btmY)]
	set index [expr {int($textIdx) - 1}]
	if {$index > $data(lastRow)} {
	    set index $data(lastRow)
	}
    } elseif {[string first $idx "active"] == 0 && [string length $idx] >= 2} {
	set index $data(activeRow)
    } elseif {[string first $idx "anchor"] == 0 && [string length $idx] >= 2} {
	set index $data(anchorRow)
    } elseif {[scan $idx "@%d,%d%n" x y count] == 3 &&
	      $count == [string length $idx]} {
	displayItems $win
	incr x -[winfo x $data(body)]
	incr y -[winfo y $data(body)]
	set textIdx [$data(body) index @$x,$y]
	set index [expr {int($textIdx) - 1}]
	if {$index > $data(lastRow)} {
	    set index $data(lastRow)
	}
    } elseif {[scan $idx "k%d%n" num count] == 2 &&
	      $count == [string length $idx]} {
	set index [keyToRow $win k$num]
    } else {
	set idxIsEmpty [expr {[string length $idx] == 0}]
	for {set row 0} {$row < $data(itemCount)} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set hasName [info exists data($key-name)]
	    if {($hasName && [string compare $idx $data($key-name)] == 0) ||
		(!$hasName && $idxIsEmpty)} {
		set index $row
		break
	    }
	}
	if {$row == $data(itemCount)} {
	    return -code error \
		   "bad row index \"$idx\": must be active, anchor, end, last,\
		    top, bottom, @x,y, a number, a full key, or a name"
	}
    }

    if {$checkRange && ($index < 0 || $index > $data(lastRow))} {
	return -code error "row index \"$idx\" out of range"
    } else {
	return $index
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_rowIndex
#
# Checks the header row index idx and returns either its numerical value or an
# error.  endIsSize must be a boolean value: if true, end refers to the number
# of header items in the tablelist, i.e., to the header item just after the
# last one; if false, end refers to 1 less than the number of header items,
# i.e., to the last header item in the tablelist.  checkRange must be a boolean
# value: if true, it is additionally checked whether the numerical value
# corresponding to idx is within the allowed range.
#------------------------------------------------------------------------------
proc tablelist::hdr_rowIndex {win idx endIsSize {checkRange 0}} {
    upvar ::tablelist::ns${win}::data data

    if {[isInteger $idx]} {
	set index [expr {int($idx)}]
    } elseif {[string first $idx "end"] == 0} {
	if {$endIsSize} {
	    set index $data(hdr_itemCount)
	} else {
	    set index $data(hdr_lastRow)
	}
    } elseif {[string first $idx "last"] == 0} {
	set index $data(hdr_lastRow)
    } elseif {[scan $idx "@%d,%d%n" x y count] == 3 &&
	      $count == [string length $idx]} {
	incr x -[winfo x $data(hdr)]
	incr y -[winfo y $data(hdr)]
	if {!$data(-showlabels)} {
	    incr y
	}
	set textIdx [$data(hdrTxt) index @$x,$y]
	set index [expr {int($textIdx) - 2}]
	if {$index < 0} {
	    set index 0
	}
	if {$index > $data(hdr_lastRow)} {
	    set index $data(hdr_lastRow)
	}
    } elseif {[scan $idx "hk%d%n" num count] == 2 &&
	      $count == [string length $idx]} {
	set index [hdr_keyToRow $win hk$num]
    } else {
	set idxIsEmpty [expr {[string length $idx] == 0}]
	for {set row 0} {$row < $data(hdr_itemCount)} {incr row} {
	    set key [lindex $data(hdr_keyList) $row]
	    set hasName [info exists data($key-name)]
	    if {($hasName && [string compare $idx $data($key-name)] == 0) ||
		(!$hasName && $idxIsEmpty)} {
		set index $row
		break
	    }
	}
	if {$row == $data(hdr_itemCount)} {
	    return -code error \
		   "bad header row index \"$idx\": must be end, last, @x,y,\
		    a number, a full header key, or a name"
	}
    }

    if {$checkRange && ($index < 0 || $index > $data(hdr_lastRow))} {
	return -code error "header row index \"$idx\" out of range"
    } else {
	return $index
    }
}

#------------------------------------------------------------------------------
# tablelist::colIndex
#
# Checks the column index idx and returns either its numerical value or an
# error.  checkRange must be a boolean value: if true, it is additionally
# checked whether the numerical value corresponding to idx is within the
# allowed range.
#------------------------------------------------------------------------------
proc tablelist::colIndex {win idx checkRange {decrX 1}} {
    upvar ::tablelist::ns${win}::data data

    if {[isInteger $idx]} {
	set index [expr {int($idx)}]
    } elseif {[string first $idx "end"] == 0 ||
	      [string first $idx "last"] == 0} {
	set index $data(lastCol)
    } elseif {[string first $idx "left"] == 0} {
	return [colIndex $win @0,0 $checkRange 0]
    } elseif {[string first $idx "right"] == 0} {
	return [colIndex $win @$data(rightX),0 $checkRange 0]
    } elseif {[string first $idx "active"] == 0 && [string length $idx] >= 2} {
	set index $data(activeCol)
    } elseif {[string first $idx "anchor"] == 0 && [string length $idx] >= 2} {
	set index $data(anchorCol)
    } elseif {[scan $idx "@%d,%d%n" x y count] == 3 &&
	      $count == [string length $idx]} {
	synchronize $win
	displayItems $win
	if {$decrX} {
	    incr x -[winfo x $data(body)]
	    if {$x > $data(rightX)} {
		set x $data(rightX)
	    } elseif {$x < 0} {
		set x 0
	    }
	}
	incr x [winfo rootx $data(body)]

	#
	# Get the (scheduled) root X coordinate of $data(hdrTxtFrm)
	#
	set  baseX [winfo rootx $data(hdrTxt)]
	incr baseX [lindex [$data(hdrTxt) bbox 1.0] 0]

	set lastVisibleCol -1
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    if {$data($col-elide) || $data($col-hide)} {
		continue
	    }

	    set lastVisibleCol $col
	    set w $data(hdrTxtFrmLbl)$col
	    set wX [expr {$baseX + [lindex [place configure $w -x] 4]}]
	    if {$x >= $wX && $x < $wX + [winfo width $w]} {
		return $col
	    }
	}
	set index $lastVisibleCol
    } else {
	set idxIsEmpty [expr {[string length $idx] == 0}]
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    set hasName [info exists data($col-name)]
	    if {($hasName && [string compare $idx $data($col-name)] == 0) ||
		(!$hasName && $idxIsEmpty)} {
		set index $col
		break
	    }
	}
	if {$col == $data(colCount)} {
	    return -code error \
		   "bad column index \"$idx\": must be active, anchor,\
		    end, last, left, right, @x,y, a number, or a name"
	}
    }

    if {$checkRange && ($index < 0 || $index > $data(lastCol))} {
	return -code error "column index \"$idx\" out of range"
    } else {
	return $index
    }
}

#------------------------------------------------------------------------------
# tablelist::cellIndex
#
# Checks the cell index idx and returns either a list of the form {row col} or
# an error.  checkRange must be a boolean value: if true, it is additionally
# checked whether the two numerical values corresponding to idx are within the
# respective allowed ranges.
#------------------------------------------------------------------------------
proc tablelist::cellIndex {win idx checkRange} {
    upvar ::tablelist::ns${win}::data data

    set lst [split $idx ","]
    if {[llength $lst] == 2 &&
	[catch {rowIndex $win [lindex $lst 0] 0} row] == 0 &&
	[catch {colIndex $win [lindex $lst 1] 0} col] == 0} {
	# nothing
    } elseif {[string first $idx "end"] == 0 ||
	      [string first $idx "last"] == 0} {
	set row [rowIndex $win $idx 0]
	set col [colIndex $win $idx 0]
    } elseif {[string first $idx "active"] == 0 && [string length $idx] >= 2} {
	set row $data(activeRow)
	set col $data(activeCol)
    } elseif {[string first $idx "anchor"] == 0 && [string length $idx] >= 2} {
	set row $data(anchorRow)
	set col $data(anchorCol)
    } elseif {[string compare [string index $idx 0] "@"] == 0 &&
	      [catch {rowIndex $win $idx 0} row] == 0 &&
	      [catch {colIndex $win $idx 0} col] == 0} {
	# nothing
    } else {
	return -code error \
	       "bad cell index \"$idx\": must be active, anchor, end, last,\
	        @x,y, or row,col, where row must be active, anchor, end, last,\
		top, bottom, a number, a full key, or a name, and col must be\
		active, anchor, end, last, left, right, a number, or a name"
    }

    if {$checkRange && ($row < 0 || $row > $data(lastRow) ||
	$col < 0 || $col > $data(lastCol))} {
	return -code error "cell index \"$idx\" out of range"
    } else {
	return [list $row $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_cellIndex
#
# Checks the header cell index idx and returns either a list of the form {row
# col} or an error.  checkRange must be a boolean value: if true, it is
# additionally checked whether the two numerical values corresponding to idx
# are within the respective allowed ranges.
#------------------------------------------------------------------------------
proc tablelist::hdr_cellIndex {win idx checkRange} {
    upvar ::tablelist::ns${win}::data data

    set lst [split $idx ","]
    if {[llength $lst] == 2 &&
	[catch {hdr_rowIndex $win [lindex $lst 0] 0} row] == 0 &&
	[catch {colIndex $win [lindex $lst 1] 0} col] == 0} {
	# nothing
    } elseif {[string first $idx "end"] == 0 ||
	      [string first $idx "last"] == 0} {
	set row [hdr_rowIndex $win $idx 0]
	set col [colIndex $win $idx 0]
    } elseif {[string compare [string index $idx 0] "@"] == 0 &&
	      [catch {hdr_rowIndex $win $idx 0} row] == 0 &&
	      [catch {colIndex $win $idx 0} col] == 0} {
	# nothing
    } else {
	return -code error \
	       "bad header cell index \"$idx\": must be end, last, @x,y, or\
	        row,col, where row must be end, last, a number, a full header\
		key, or a name, and col must be active, anchor, end, last,\
		left, right, a number, or a name"
    }

    if {$checkRange && ($row < 0 || $row > $data(hdr_lastRow) ||
	$col < 0 || $col > $data(lastCol))} {
	return -code error "header cell index \"$idx\" out of range"
    } else {
	return [list $row $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustRowIndex
#
# Sets the row index specified by $rowName to the index of the nearest
# (viewable) row.
#------------------------------------------------------------------------------
proc tablelist::adjustRowIndex {win rowName {forceViewable 0}} {
    upvar ::tablelist::ns${win}::data data $rowName row

    #
    # Don't operate on row directly, because $rowName might
    # be data(activeRow), in which case any temporary changes
    # made on row would trigger the activeTrace procedure
    #
    set _row $row
    if {$_row > $data(lastRow)} {
	set _row $data(lastRow)
    }
    if {$_row < 0} {
	set _row 0
    }

    if {$forceViewable} {
	set _rowSav $_row
	for {} {$_row < $data(itemCount)} {incr _row} {
	    set key [lindex $data(keyList) $_row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set row $_row
		return ""
	    }
	}
	for {set _row [expr {$_rowSav - 1}]} {$_row >= 0} {incr _row -1} {
	    set key [lindex $data(keyList) $_row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		set row $_row
		return ""
	    }
	}
	set row 0
    } else {
	set row $_row
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustColIndex
#
# Sets the column index specified by $colName to the index of the nearest
# (viewable) column.
#------------------------------------------------------------------------------
proc tablelist::adjustColIndex {win colName {forceViewable 0}} {
    upvar ::tablelist::ns${win}::data data $colName col

    #
    # Don't operate on col directly, because $colName might
    # be data(activeCol), in which case any temporary changes
    # made on col would trigger the activeTrace procedure
    #
    set _col $col
    if {$_col > $data(lastCol)} {
	set _col $data(lastCol)
    }
    if {$_col < 0} {
	set _col 0
    }

    if {$forceViewable} {
	set _colSav $_col
	for {} {$_col < $data(colCount)} {incr _col} {
	    if {!$data($_col-hide)} {
		set col $_col
		return ""
	    }
	}
	for {set _col [expr {$_colSav - 1}]} {$_col >= 0} {incr _col -1} {
	    if {!$data($_col-hide)} {
		set col $_col
		return ""
	    }
	}
	set _col 0
    } else {
	set col $_col
    }
}

#------------------------------------------------------------------------------
# tablelist::nodeIndexToKey
#
# Checks the node index idx and returns either the corresponding full key or
# "root", or an error.
#------------------------------------------------------------------------------
proc tablelist::nodeIndexToKey {win idx} {
    if {[string first $idx "root"] == 0} {
	return "root"
    } elseif {[catch {rowIndex $win $idx 0} row] == 0} {
	upvar ::tablelist::ns${win}::data data
	if {$row < 0 || $row > $data(lastRow)} {
	    return -code error "node index \"$idx\" out of range"
	} else {
	    return [lindex $data(keyList) $row]
	}
    } else {
	return -code error \
	       "bad node index \"$idx\": must be root, active, anchor, end,\
		last, top, bottom, @x,y, a number, a full key, or a name"
    }
}

#------------------------------------------------------------------------------
# tablelist::depth
#
# Returns the number of steps from the node with the given full key to the root
# node of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::depth {win key} {
    upvar ::tablelist::ns${win}::data data

    set depth 0
    while {[string compare $key "root"] != 0} {
	incr depth
	set key $data($key-parent)
    }

    return $depth
}

#------------------------------------------------------------------------------
# tablelist::topLevelKey
#
# Returns the full key of the top-level item of the tablelist widget win having
# the item with the given key as descendant.
#------------------------------------------------------------------------------
proc tablelist::topLevelKey {win key} {
    upvar ::tablelist::ns${win}::data data

    set parentKey $data($key-parent)
    while {[string compare $parentKey "root"] != 0} {
	set key $data($key-parent)
	set parentKey $data($key-parent)
    }

    return $key
}

#------------------------------------------------------------------------------
# tablelist::descCount
#
# Returns the number of descendants of the node with the given full key of the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::descCount {win key} {
    upvar ::tablelist::ns${win}::data data

    if {[string compare $key "root"] == 0} {
	return $data(itemCount)
    } else {
	set count [llength $data($key-children)]
	foreach child $data($key-children) {
	    incr count [descCount $win $child]
	}
	return $count
    }
}

#------------------------------------------------------------------------------
# tablelist::nodeRow
#
# Returns the row of the child item identified by childIdx of the node given by
# parentKey within the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::nodeRow {win parentKey childIdx} {
    upvar ::tablelist::ns${win}::data data

    if {[isInteger $childIdx]} {
	if {$childIdx < [llength $data($parentKey-children)]} {
	    set childKey [lindex $data($parentKey-children) $childIdx]
	    return [keyToRow $win $childKey]
	} else {
	    return [expr {[keyToRow $win $parentKey] +
			  [descCount $win $parentKey] + 1}]
	}
    } elseif {[string first $childIdx "end"] == 0} {
	return [expr {[keyToRow $win $parentKey] +
		      [descCount $win $parentKey] + 1}]
    } elseif {[string first $childIdx "last"] == 0} {
	set childKey [lindex $data($parentKey-children) end]
	return [keyToRow $win $childKey]
    } else {
	return -code error \
	       "bad child index \"$childIdx\": must be end, last, or a number"
    }
}

#------------------------------------------------------------------------------
# tablelist::keyToRow
#
# Returns the row corresponding to the given full key within the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::keyToRow {win key} {
    upvar ::tablelist::ns${win}::data data
    if {[string compare $key "root"] == 0} {
	return -1
    } elseif {$data(keyToRowMapValid) && [info exists data($key-row)]} {
	return $data($key-row)
    } else {
	if {$::tcl_version >= 8.4} {
	    #
	    # Speed up the search by starting at the last found position
	    #
	    set row [lsearch -exact -start $data(searchStartIdx) \
		     $data(keyList) $key]
	    if {$row < 0 && $data(searchStartIdx) != 0} {
		set row [lsearch -exact $data(keyList) $key]
	    }
	    if {$row >= 0} {
		set data(searchStartIdx) $row
	    }

	    return $row
	} else {
	    return [lsearch -exact $data(keyList) $key]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_keyToRow
#
# Returns the header row corresponding to the given full header key within the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::hdr_keyToRow {win key} {
    upvar ::tablelist::ns${win}::data data
    return [lsearch -exact $data(hdr_keyList) $key]
}

#------------------------------------------------------------------------------
# tablelist::updateKeyToRowMap
#
# Updates the key -> row map associated with the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::updateKeyToRowMap win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(mapId)]} {
	after cancel $data(mapId)
	unset data(mapId)
    }

    set row 0
    foreach key $data(keyList) {
	set data($key-row) $row
	incr row
    }

    set data(keyToRowMapValid) 1
}

#------------------------------------------------------------------------------
# tablelist::findTabs
#
# Searches for the first and last occurrences of the tab character in the cell
# range specified by firstCol and lastCol in the given line of the text widget
# descendant w of the tablelist widget win.  Assigns the index of the first tab
# to $idx1Name and the index of the last tab to $idx2Name.  It is assumed that
# both columns are non-hidden (but there may be hidden ones between them).
#------------------------------------------------------------------------------
proc tablelist::findTabs {win w line firstCol lastCol idx1Name idx2Name} {
    upvar ::tablelist::ns${win}::data data $idx1Name idx1 $idx2Name idx2

    if {$::tk_version >= 8.5} {
	set idxList [$w search -all -elide "\t" $line.0 $line.end]
	if {[llength $idxList] == 0} {
	    return 0
	}

	set idx1 [lindex $idxList [expr {2*$firstCol}]]
	set idx2 [lindex $idxList [expr {2*$lastCol + 1}]]
	return 1
    } else {
	variable canElide
	variable elide
	variable pu
	set endIdx $line.end

	set idx $line.1
	for {set col 0} {$col < $firstCol} {incr col} {
	    if {!$data($col-hide) || $canElide} {
		set idx [$w search $elide "\t" $idx $endIdx]+2$pu
		if {[string compare $idx "+2$pu"] == 0} {
		    return 0
		}
	    }
	}
	set idx1 [$w index $idx-1$pu]

	for {} {$col < $lastCol} {incr col} {
	    if {!$data($col-hide) || $canElide} {
		set idx [$w search $elide "\t" $idx $endIdx]+2$pu
		if {[string compare $idx "+2$pu"] == 0} {
		    return 0
		}
	    }
	}
	set idx2 [$w search $elide "\t" $idx $endIdx]
	if {[string length $idx2] == 0} {
	    return 0
	}

	return 1
    }
}

#------------------------------------------------------------------------------
# tablelist::sortStretchableColList
#
# Replaces the column indices different from end in the list of the stretchable
# columns of the tablelist widget win with their numerical equivalents and
# sorts the resulting list.
#------------------------------------------------------------------------------
proc tablelist::sortStretchableColList win {
    upvar ::tablelist::ns${win}::data data
    if {[llength $data(-stretch)] == 0 ||
	[string compare $data(-stretch) "all"] == 0} {
	return ""
    }

    set containsEnd 0
    foreach elem $data(-stretch) {
	if {[string first $elem "end"] == 0 ||
	    [string first $elem "last"] == 0} {
	    set containsEnd 1
	} else {
	    set tmp([colIndex $win $elem 0]) ""
	}
    }

    set data(-stretch) [lsort -integer [array names tmp]]
    if {$containsEnd} {
	lappend data(-stretch) end
    }
}

#------------------------------------------------------------------------------
# tablelist::deleteColData
#
# Cleans up the data associated with the col'th column of the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::deleteColData {win col} {
    upvar ::tablelist::ns${win}::data data
    if {$data(editCol) == $col} {
	set data(editCol) -1
	set data(editRow) -1
    }

    #
    # Remove the elements with names of the form $col-*
    #
    if {[info exists data($col-redispId)]} {
	after cancel $data($col-redispId)
    }
    foreach name [array names data $col-*] {
	unset data($name)
    }

    #
    # Remove the elements with names of the form hk*,$col-*
    #
    foreach name [array names data hk*,$col-*] {
	unset data($name)
    }

    #
    # Remove the elements with names of the form k*,$col-*
    #
    foreach name [array names data k*,$col-*] {
	unset data($name)
	if {[string match "k*,$col-font" $name]} {
	    incr data(cellTagRefCount) -1
	} elseif {[string match "k*,$col-image" $name]} {
	    incr data(imgCount) -1
	} elseif {[string match "k*,$col-window" $name]} {
	    incr data(winCount) -1
	} elseif {[string match "k*,$col-indent" $name]} {
	    incr data(indentCount) -1
	}
    }

    #
    # Remove col from the list of stretchable columns if explicitly specified
    #
    if {[string compare $data(-stretch) "all"] != 0} {
	set stretchableCols {}
	foreach elem $data(-stretch) {
	    if {$elem != $col} {
		lappend stretchableCols $elem
	    }
	}
	set data(-stretch) $stretchableCols
    }
}

#------------------------------------------------------------------------------
# tablelist::deleteColAttribs
#
# Cleans up the attributes associated with the col'th column of the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::deleteColAttribs {win col} {
    upvar ::tablelist::ns${win}::attribs attribs

    #
    # Remove the elements with names of the form $col-*
    #
    foreach name [array names attribs $col-*] {
	unset attribs($name)
    }

    #
    # Remove the elements with names of the form hk*,$col-*
    #
    foreach name [array names attribs hk*,$col-*] {
	unset attribs($name)
    }

    #
    # Remove the elements with names of the form k*,$col-*
    #
    foreach name [array names attribs k*,$col-*] {
	unset attribs($name)
    }
}

#------------------------------------------------------------------------------
# tablelist::moveColData
#
# Moves the elements of oldArrName corresponding to oldCol to those of
# newArrName corresponding to newCol.
#------------------------------------------------------------------------------
proc tablelist::moveColData {oldArrName newArrName imgArrName oldCol newCol} {
    upvar $oldArrName oldArr $newArrName newArr $imgArrName imgArr

    foreach specialCol {editCol -treecolumn treeCol} {
	if {$oldArr($specialCol) == $oldCol} {
	    set newArr($specialCol) $newCol
	}
    }

    set callerProc [lindex [info level -1] 0]
    if {[string compare $callerProc "moveCol"] == 0} {
	foreach specialCol {activeCol anchorCol} {
	    if {$oldArr($specialCol) == $oldCol} {
		set newArr($specialCol) $newCol
	    }
	}
    }

    if {$newCol < $newArr(colCount)} {
	foreach l [getSublabels $newArr(hdrTxtFrmLbl)$newCol] {
	    destroy $l
	}
	set newArr(fmtCmdFlagList) \
	    [lreplace $newArr(fmtCmdFlagList) $newCol $newCol 0]
    }

    #
    # Move the elements of oldArr with names of the form $oldCol-*
    # to those of newArr with names of the form $newCol-*
    #
    foreach newName [array names newArr $newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr $oldCol-*] {
	regsub "$oldCol-" $oldName "$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)

	set tail [lindex [split $newName "-"] 1]
	switch $tail {
	    formatcommand {
		if {$newCol < $newArr(colCount)} {
		    set newArr(fmtCmdFlagList) \
			[lreplace $newArr(fmtCmdFlagList) $newCol $newCol 1]
		}
	    }
	    labelimage {
		set imgArr($newCol-$tail) $newArr($newName)
		unset newArr($newName)
	    }
	}
    }

    #
    # Move the elements of oldArr with names of the form hk*,$oldCol-*
    # to those of newArr with names of the form hk*,$newCol-*
    #
    foreach newName [array names newArr hk*,$newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr hk*,$oldCol-*] {
	regsub -- ",$oldCol-" $oldName ",$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }

    #
    # Move the elements of oldArr with names of the form k*,$oldCol-*
    # to those of newArr with names of the form k*,$newCol-*
    #
    foreach newName [array names newArr k*,$newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr k*,$oldCol-*] {
	regsub -- ",$oldCol-" $oldName ",$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }

    #
    # Replace oldCol with newCol in the list of
    # stretchable columns if explicitly specified
    #
    if {[info exists oldArr(-stretch)] &&
	[string compare $oldArr(-stretch) "all"] != 0} {
	set stretchableCols {}
	foreach elem $oldArr(-stretch) {
	    if {$elem == $oldCol} {
		lappend stretchableCols $newCol
	    } else {
		lappend stretchableCols $elem
	    }
	}
	set newArr(-stretch) $stretchableCols
    }
}

#------------------------------------------------------------------------------
# tablelist::moveColAttribs
#
# Moves the elements of oldArrName corresponding to oldCol to those of
# newArrName corresponding to newCol.
#------------------------------------------------------------------------------
proc tablelist::moveColAttribs {oldArrName newArrName oldCol newCol} {
    upvar $oldArrName oldArr $newArrName newArr

    #
    # Move the elements of oldArr with names of the form $oldCol-*
    # to those of newArr with names of the form $newCol-*
    #
    foreach newName [array names newArr $newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr $oldCol-*] {
	regsub "$oldCol-" $oldName "$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }

    #
    # Move the elements of oldArr with names of the form hk*,$oldCol-*
    # to those of newArr with names of the form hk*,$newCol-*
    #
    foreach newName [array names newArr hk*,$newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr hk*,$oldCol-*] {
	regsub -- ",$oldCol-" $oldName ",$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }

    #
    # Move the elements of oldArr with names of the form k*,$oldCol-*
    # to those of newArr with names of the form k*,$newCol-*
    #
    foreach newName [array names newArr k*,$newCol-*] {
	unset newArr($newName)
    }
    foreach oldName [array names oldArr k*,$oldCol-*] {
	regsub -- ",$oldCol-" $oldName ",$newCol-" newName
	set newArr($newName) $oldArr($oldName)
	unset oldArr($oldName)
    }
}

#------------------------------------------------------------------------------
# tablelist::deleteColFromCellList
#
# Returns the list obtained from a given list of cell indices by removing the
# elements whose column component equals a given column number.
#------------------------------------------------------------------------------
proc tablelist::deleteColFromCellList {cellList col} {
    set newCellList {}
    foreach cellIdx $cellList {
	scan $cellIdx "%d,%d" cellRow cellCol
	if {$cellCol != $col} {
	    lappend newCellList $cellIdx
	}
    }

    return $newCellList
}

#------------------------------------------------------------------------------
# tablelist::extractColFromCellList
#
# Returns the list of row indices obtained from those elements of a given list
# of cell indices whose column component equals a given column number.
#------------------------------------------------------------------------------
proc tablelist::extractColFromCellList {cellList col} {
    set rowList {}
    foreach cellIdx $cellList {
	scan $cellIdx "%d,%d" cellRow cellCol
	if {$cellCol == $col} {
	    lappend rowList $cellRow
	}
    }

    return $rowList
}

#------------------------------------------------------------------------------
# tablelist::replaceColInCellList
#
# Returns the list obtained from a given list of cell indices by replacing the
# occurrences of oldCol in the column components with newCol.
#------------------------------------------------------------------------------
proc tablelist::replaceColInCellList {cellList oldCol newCol} {
    set cellList [deleteColFromCellList $cellList $newCol]
    set newCellList {}
    foreach cellIdx $cellList {
	scan $cellIdx "%d,%d" cellRow cellCol
	if {$cellCol == $oldCol} {
	    lappend newCellList $cellRow,$newCol
	} else {
	    lappend newCellList $cellIdx
	}
    }

    return $newCellList
}

#------------------------------------------------------------------------------
# tablelist::condUpdateListVar
#
# Updates the list variable of the tablelist widget win if present.
#------------------------------------------------------------------------------
proc tablelist::condUpdateListVar win {
    upvar ::tablelist::ns${win}::data data
    if {$data(hasListVar)} {
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
	set var {}
	foreach item $data(itemList) {
	    lappend var [lrange $item 0 $data(lastCol)]
	}
	trace variable var wu $data(listVarTraceCmd)
    }
}

#------------------------------------------------------------------------------
# tablelist::reconfigColLabels
#
# Reconfigures the labels of the col'th column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::reconfigColLabels {win imgArrName col} {
    upvar ::tablelist::ns${win}::data data $imgArrName imgArr

    set optList {-labelalign -labelborderwidth -labelfont
		 -labelforeground -labelpady -labelrelief}
    variable usingTile
    if {!$usingTile} {
	lappend optList -labelbackground -labelheight
    }

    foreach opt $optList {
	if {[info exists data($col$opt)]} {
	    doColConfig $col $win $opt $data($col$opt)
	} else {
	    doColConfig $col $win $opt ""
	}
    }

    if {[info exists imgArr($col-labelimage)]} {
	doColConfig $col $win -labelimage $imgArr($col-labelimage)
    }
}

#------------------------------------------------------------------------------
# tablelist::charsToPixels
#
# Returns the width in pixels of the string consisting of a given number of "0"
# characters.
#------------------------------------------------------------------------------
proc tablelist::charsToPixels {win font charCount} {
    return [expr {[font measure $font -displayof $win "0"] * $charCount}]
}

#------------------------------------------------------------------------------
# tablelist::strRange
#
# Gets the largest initial (for snipSide = r) or final (for snipSide = l) range
# of characters from str whose width, when displayed in the given font, is no
# greater than pixels decremented by the width of snipStr.  Returns a string
# obtained from this substring by appending (for snipSide = r) or prepending
# (for snipSide = l) (part of) snipStr to it.
#------------------------------------------------------------------------------
proc tablelist::strRange {win str font pixels snipSide snipStr} {
    if {$pixels < 0} {
	return ""
    }

    if {[string length $snipSide] == 0} {
	return $str
    }


    set width [font measure $font -displayof $win $str]
    if {$width <= $pixels} {
	return $str
    }

    set snipWidth [font measure $font -displayof $win $snipStr]
    if {$pixels <= $snipWidth} {
	set str $snipStr
	set snipStr ""
    } else {
	incr pixels -$snipWidth
    }

    if {[string compare $snipSide "r"] == 0} {
	set idx [expr {[string length $str]*$pixels/$width - 1}]
	set subStr [string range $str 0 $idx]
	set width [font measure $font -displayof $win $subStr]
	if {$width < $pixels} {
	    while 1 {
		incr idx
		set subStr [string range $str 0 $idx]
		set width [font measure $font -displayof $win $subStr]
		if {$width > $pixels} {
		    incr idx -1
		    set subStr [string range $str 0 $idx]
		    return $subStr$snipStr
		} elseif {$width == $pixels} {
		    return $subStr$snipStr
		}
	    }
	} elseif {$width == $pixels} {
	    return $subStr$snipStr
	} else {
	    while 1 {
		incr idx -1
		set subStr [string range $str 0 $idx]
		set width [font measure $font -displayof $win $subStr]
		if {$width <= $pixels} {
		    return $subStr$snipStr
		}
	    }
	}

    } else {
	set idx [expr {[string length $str]*($width - $pixels)/$width}]
	set subStr [string range $str $idx end]
	set width [font measure $font -displayof $win $subStr]
	if {$width < $pixels} {
	    while 1 {
		incr idx -1
		set subStr [string range $str $idx end]
		set width [font measure $font -displayof $win $subStr]
		if {$width > $pixels} {
		    incr idx
		    set subStr [string range $str $idx end]
		    return $snipStr$subStr
		} elseif {$width == $pixels} {
		    return $snipStr$subStr
		}
	    }
	} elseif {$width == $pixels} {
	    return $snipStr$subStr
	} else {
	    while 1 {
		incr idx
		set subStr [string range $str $idx end]
		set width [font measure $font -displayof $win $subStr]
		if {$width <= $pixels} {
		    return $snipStr$subStr
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustItem
#
# Returns the list obtained by adjusting the list specified by item to the
# length expLen.
#------------------------------------------------------------------------------
proc tablelist::adjustItem {item expLen} {
    set len [llength $item]
    if {$len == $expLen} {
	return $item
    } elseif {$len > $expLen} {
	return [lrange $item 0 [expr {$expLen - 1}]]
    } else {
	for {set n $len} {$n < $expLen} {incr n} {
	    lappend item ""
	}
	return $item
    }
}

#------------------------------------------------------------------------------
# tablelist::formatElem
#
# Returns the string obtained by formatting the last argument.
#------------------------------------------------------------------------------
proc tablelist::formatElem {win key row col text} {
    upvar ::tablelist::ns${win}::data data
    array set data [list fmtKey $key fmtRow $row fmtCol $col]

    return [uplevel #0 $data($col-formatcommand) [list $text]]
}

#------------------------------------------------------------------------------
# tablelist::formatItem
#
# Returns the list obtained by formatting the elements of the last argument.
#------------------------------------------------------------------------------
proc tablelist::formatItem {win key row item} {
    upvar ::tablelist::ns${win}::data data
    array set data [list fmtKey $key fmtRow $row]
    set formattedItem {}
    set col 0
    foreach text $item fmtCmdFlag $data(fmtCmdFlagList) {
	if {$fmtCmdFlag} {
	    set data(fmtCol) $col
	    set text [uplevel #0 $data($col-formatcommand) [list $text]]
	}
	lappend formattedItem $text
	incr col
    }

    return $formattedItem
}

#------------------------------------------------------------------------------
# tablelist::hasChars
#
# Checks whether at least one element of the given list is a nonempty string.
#------------------------------------------------------------------------------
proc tablelist::hasChars list {
    foreach str $list {
	if {[string length $str] != 0} {
	    return 1
	}
    }

    return 0
}

#------------------------------------------------------------------------------
# tablelist::getListWidth
#
# Returns the max. number of pixels that the elements of the given list would
# use in the specified font when displayed in the window win.
#------------------------------------------------------------------------------
proc tablelist::getListWidth {win list font} {
    set width 0
    foreach str $list {
	set strWidth [font measure $font -displayof $win $str]
	if {$strWidth > $width} {
	    set width $strWidth
	}
    }

    return $width
}

#------------------------------------------------------------------------------
# tablelist::joinList
#
# Returns the string formed by joining together with "\n" the strings obtained
# by applying strRange to the elements of the given list, with the specified
# arguments.
#------------------------------------------------------------------------------
proc tablelist::joinList {win list font pixels snipSide snipStr} {
    set list2 {}
    foreach str $list {
	lappend list2 [strRange $win $str $font $pixels $snipSide $snipStr]
    }

    return [join $list2 "\n"]
}

#------------------------------------------------------------------------------
# tablelist::displayIndent
#
# Displays an indentation image in a label widget to be embedded into the
# specified cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::displayIndent {win key col width} {
    upvar ::tablelist::ns${win}::data data
    set w $data(body).ind_$key,$col

    if {![winfo exists $w]} {
	#
	# Create a label widget and replace the binding tag Label with
	# $data(bodyTag) and TablelistBody in the list of its binding tags
	#
	tk::label $w -anchor w -borderwidth 0 -height 0 -highlightthickness 0 \
		     -image $data($key,$col-indent) -padx 0 -pady 0 \
		     -relief flat -takefocus 0 -width $width
	bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]
    }

    updateColorsWhenIdle $win
    return $w
}

#------------------------------------------------------------------------------
# tablelist::displayImage
#
# Displays an image in a label widget to be embedded into the specified cell of
# the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::displayImage {win key col anchor width} {
    upvar ::tablelist::ns${win}::data data
    set inBody [string match "k*" $key]
    if {$inBody} {
	set w $data(body).img_$key,$col
    } else {
	set w $data(hdrTxt).img_$key,$col
    }

    if {![winfo exists $w]} {
	#
	# Create a label widget and replace the binding tag
	# Label with either $data(bodyTag) and TablelistBody
	# or data(headerTag) in the list of its binding tags
	#
	tk::label $w -anchor $anchor -borderwidth 0 -height 0 \
		     -highlightthickness 0 -image $data($key,$col-image) \
		     -padx 0 -pady 0 -relief flat -takefocus 0 -width $width
	if {$inBody} {
	    bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) \
			 TablelistBody]
	} else {
	    bindtags $w [lreplace [bindtags $w] 1 1 $data(headerTag) \
			 TablelistHeader]
	}
    }

    if {$inBody} {
	updateColorsWhenIdle $win
    } else {
	hdr_updateColorsWhenIdle $win
    }
    return $w
}

#------------------------------------------------------------------------------
# tablelist::displayText
#
# Displays the given text in a message widget to be embedded into the specified
# cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::displayText {win key col text font pixels alignment} {
    upvar ::tablelist::ns${win}::data data
    set inBody [string match "k*" $key]
    if {$inBody} {
	set w $data(body).msg_$key,$col
    } else {
	set w $data(hdrTxt).msg_$key,$col
    }

    if {![winfo exists $w]} {
	#
	# Create a message widget and replace the binding tag
	# Message with either $data(bodyTag) and TablelistBody
	# or data(headerTag) in the list of its binding tags
	#
	message $w -borderwidth 0 -highlightthickness 0 -padx 0 -pady 0 \
		   -relief flat -takefocus 0
	if {$inBody} {
	    bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) \
			 TablelistBody]
	} else {
	    bindtags $w [lreplace [bindtags $w] 1 1 $data(headerTag) \
			 TablelistHeader]
	}
    }

    variable anchors
    set width $pixels
    if {$pixels == 0} {
	set width 1000000
    }
    $w configure -anchor $anchors($alignment) -font $font \
		 -justify $alignment -text $text -width $width

    if {$inBody} {
	updateColorsWhenIdle $win
    } else {
	hdr_updateColorsWhenIdle $win
    }
    return $w
}

#------------------------------------------------------------------------------
# tablelist::getAuxData
#
# Gets the name, type, and width of the image or window associated with the
# specified cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getAuxData {win key col auxTypeName auxWidthName {pixels 0}} {
    upvar ::tablelist::ns${win}::data data \
	  $auxTypeName auxType $auxWidthName auxWidth

    if {[info exists data($key,$col-window)]} {
	if {$pixels != 0 && [info exists data($key,$col-stretchwindow)]} {
	    set auxType 3				;# dynamic-width window
	    set auxWidth [expr {$pixels + $data($col-delta)}]
	} else {
	    set auxType 2				;# static-width window
	    set auxWidth $data($key,$col-reqWidth)
	}

	if {[string match "k*" $key]} {
	    return $data(body).frm_$key,$col
	} else {
	    return $data(hdrTxt).frm_$key,$col
	}
    } elseif {[info exists data($key,$col-image)]} {
	set auxType 1					;# image
	set auxWidth [image width $data($key,$col-image)]
	return [list ::tablelist::displayImage $win $key $col w 0]
    } else {
	set auxType 0					;# none
	set auxWidth 0
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::getIndentData
#
# Gets the creation script and width of the label displaying the indentation
# image associated with the specified cell of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getIndentData {win key col indentWidthName} {
    upvar ::tablelist::ns${win}::data data $indentWidthName indentWidth

    if {[info exists data($key,$col-indent)]} {
	set indentWidth [image width $data($key,$col-indent)]
	return [list ::tablelist::displayIndent $win $key $col 0]
    } else {
	set indentWidth 0
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::getMaxTextWidth
#
# Returns the number of pixels available for displaying the text of a static-
# width tablelist cell.
#------------------------------------------------------------------------------
proc tablelist::getMaxTextWidth {pixels auxWidth indentWidth} {
    if {$indentWidth != 0} {
	incr pixels -$indentWidth
	if {$pixels <= 0} {
	    set pixels 1
	}
    }

    if {$auxWidth == 0} {
	return $pixels
    } else {
	set lessPixels [expr {$pixels - $auxWidth - 5}]
	if {$lessPixels > 0} {
	    return $lessPixels
	} else {
	    return 1
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustElem
#
# Prepares the text specified by $textName and the auxiliary object width
# specified by $auxWidthName for insertion into a cell of the tablelist widget
# win.
#------------------------------------------------------------------------------
proc tablelist::adjustElem {win textName auxWidthName indentWidthName font
			    pixels snipSide snipStr} {
    upvar $textName text $auxWidthName auxWidth $indentWidthName indentWidth

    if {$pixels == 0} {				;# convention: dynamic width
	if {$auxWidth != 0 && [string length $text] != 0} {
	    incr auxWidth 3
	}
    } elseif {$indentWidth >= $pixels} {
	set indentWidth $pixels
	set text ""				;# can't display the text
	set auxWidth 0				;# can't display the aux. object
    } else {
	incr pixels -$indentWidth
	if {$auxWidth == 0} {			;# no image or window
	    set text [strRange $win $text $font $pixels $snipSide $snipStr]
	} elseif {[string length $text] == 0} {	;# aux. object w/o text
	    if {$auxWidth > $pixels} {
		set auxWidth $pixels
	    }
	} else {				;# both aux. object and text
	    if {$auxWidth + 5 <= $pixels} {
		incr auxWidth 3
		incr pixels -[expr {$auxWidth + 2}]
		set text [strRange $win $text $font $pixels $snipSide $snipStr]
	    } elseif {$auxWidth <= $pixels} {
		set text ""			;# can't display the text
	    } else {
		set auxWidth $pixels
		set text ""			;# can't display the text
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustMlElem
#
# Prepares the list specified by $listName and the auxiliary object width
# specified by $auxWidthName for insertion into a multiline cell of the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::adjustMlElem {win listName auxWidthName indentWidthName font
			      pixels snipSide snipStr} {
    upvar $listName list $auxWidthName auxWidth $indentWidthName indentWidth

    set list2 {}
    if {$pixels == 0} {				;# convention: dynamic width
	if {$auxWidth != 0 && [hasChars $list]} {
	    incr auxWidth 3
	}
    } elseif {$indentWidth >= $pixels} {
	set indentWidth $pixels
	foreach str $list {
	    lappend list2 ""
	}
	set list $list2				;# can't display the text
	set auxWidth 0				;# can't display the aux. object
    } else {
	incr pixels -$indentWidth
	if {$auxWidth == 0} {			;# no image or window
	    foreach str $list {
		lappend list2 \
		    [strRange $win $str $font $pixels $snipSide $snipStr]
	    }
	    set list $list2
	} elseif {![hasChars $list]} {		;# aux. object w/o text
	    if {$auxWidth > $pixels} {
		set auxWidth $pixels
	    }
	} else {				;# both aux. object and text
	    if {$auxWidth + 5 <= $pixels} {
		incr auxWidth 3
		incr pixels -[expr {$auxWidth + 2}]
		foreach str $list {
		    lappend list2 \
			[strRange $win $str $font $pixels $snipSide $snipStr]
		}
		set list $list2
	    } elseif {$auxWidth <= $pixels} {
		foreach str $list {
		    lappend list2 ""
		}
		set list $list2			;# can't display the text
	    } else {
		set auxWidth $pixels
		foreach str $list {
		    lappend list2 ""
		}
		set list $list2			;# can't display the text
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::getElemWidth
#
# Returns the number of pixels that the given text together with the aux.
# object (image or window) of the specified width would use when displayed in a
# cell of a dynamic-width column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getElemWidth {win text auxWidth indentWidth cellFont} {
    if {[string match "*\n*" $text]} {
	set list [split $text "\n"]
	if {$auxWidth != 0 && [hasChars $list]} {
	    incr auxWidth 5
	}
	return [expr {[getListWidth $win $list $cellFont] +
		      $auxWidth + $indentWidth}]
    } else {
	if {$auxWidth != 0 && [string length $text] != 0} {
	    incr auxWidth 5
	}
	return [expr {[font measure $cellFont -displayof $win $text] +
		      $auxWidth + $indentWidth}]
    }
}

#------------------------------------------------------------------------------
# tablelist::insertOrUpdateIndent
#
# Sets the width of the indentation label embedded into the text widget w at
# the given index to the specified value, after inserting the label if needed.
# Returns 1 if the label had to be inserted and 0 otherwise.
#------------------------------------------------------------------------------
proc tablelist::insertOrUpdateIndent {w index indent indentWidth} {
    if {[catch {$w window cget $index -create} script] == 0 &&
	[string match "::tablelist::displayIndent *" $script]} {
	if {$indentWidth != [lindex $script end]} {
	    set padY [expr {[$w cget -spacing1] == 0}]
	    set script [lreplace $script end end $indentWidth]
	    $w window configure $index -pady $padY -create $script

	    set path [lindex [$w dump -window $index] 1]
	    if {[string length $path] != 0} {
		$path configure -width $indentWidth
	    }
	}
	return 0
    } else {
	set padY [expr {[$w cget -spacing1] == 0}]
	set indent [lreplace $indent end end $indentWidth]
	$w window create $index -pady $padY -create $indent
	$w tag add elidedWin $index
	return 1
    }
}

#------------------------------------------------------------------------------
# tablelist::insertElem
#
# Inserts the given text and auxiliary object (image or window) into the text
# widget w, just before the character position specified by index.  The object
# will follow the text if alignment is "right", and will precede it otherwise.
#------------------------------------------------------------------------------
proc tablelist::insertElem {w index text aux auxType alignment valignment} {
    set index [$w index $index]

    if {$auxType == 0} {				;# no image or window
	$w insert $index $text
    } elseif {[string compare $alignment "right"] == 0} {
	set padY [expr {[$w cget -spacing1] == 0}]
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 e]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor ne -relwidth "" -relx 1.0
	    } else {						;# dynamic width
		place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
	$w insert $index $text
    } else {
	$w insert $index $text
	set padY [expr {[$w cget -spacing1] == 0}]
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 w]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor nw -relwidth "" -relx 0.0
	    } else {						;# dynamic width
		place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::insertMlElem
#
# Inserts the given message widget and auxiliary object (image or window) into
# the text widget w, just before the character position specified by index.
# The object will follow the message widget if alignment is "right", and will
# precede it otherwise.
#------------------------------------------------------------------------------
proc tablelist::insertMlElem {w index msgScript aux auxType alignment
			      valignment} {
    set index [$w index $index]
    set padY [expr {[$w cget -spacing1] == 0}]

    if {$auxType == 0} {				;# no image or window
	$w window create $index -align top -pady $padY -create $msgScript
	$w tag add elidedWin $index
    } elseif {[string compare $alignment "right"] == 0} {
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 e]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor ne -relwidth "" -relx 1.0
	    } else {						;# dynamic width
		place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
	$w window create $index -align top -pady $padY -create $msgScript
	$w tag add elidedWin $index
    } else {
	$w window create $index -align top -pady $padY -create $msgScript
	$w tag add elidedWin $index
	if {$auxType == 1} {					;# image
	    set aux [lreplace $aux 4 4 w]
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -create $aux
	    $w tag add elidedWin $index
	} else {						;# window
	    if {$auxType == 2} {				;# static width
		place $aux.w -anchor nw -relwidth "" -relx 0.0
	    } else {						;# dynamic width
		place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
	    }
	    $w window create $index -align $valignment -padx 1 -pady $padY \
				    -window $aux
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateCell
#
# Updates the content of the text widget w starting at index1 and ending just
# before index2 by keeping the auxiliary object (image or window) (if any) and
# replacing only the text between the two character positions.
#------------------------------------------------------------------------------
proc tablelist::updateCell {w index1 index2 text aux auxType auxWidth
			    indent indentWidth alignment valignment} {
    set tagNames [$w tag names $index2]
    if {[lsearch -exact $tagNames select] >= 0} {		;# selected
	$w tag add select $index1 $index2
    }

    variable pu
    if {$indentWidth != 0} {
	if {[insertOrUpdateIndent $w $index1 $indent $indentWidth]} {
	    set index2 $index2+1$pu
	}
	set index1 $index1+1$pu
    }

    if {$auxWidth == 0} {				;# no image or window
	#
	# Work around a Tk peculiarity on Windows, related to deleting
	# an embedded window while resizing a text widget interactively
	#
	set path [lindex [$w dump -window $index1] 1]
	if {[string length $path] != 0 &&
	    [string compare [winfo class $path] "Message"] == 0} {
	    $path configure -text ""
	    $w window configure $index1 -window ""
	}

	if {$::tk_version >= 8.5} {
	    $w replace $index1 $index2 $text
	} else {
	    $w delete $index1 $index2
	    $w insert $index1 $text
	}
    } else {
	#
	# Check whether the image label or the frame containing a
	# window is mapped at the first or last position of the cell
	#
	if {$auxType == 1} {					;# image
	    if {[setImgLabelWidth $w $index1 $auxWidth]} {
		set auxFound 1
		set fromIdx $index1+1$pu
		set toIdx $index2
	    } elseif {[setImgLabelWidth $w $index2-1$pu $auxWidth]} {
		set auxFound 1
		set fromIdx $index1
		set toIdx $index2-1$pu
	    } else {
		set auxFound 0
		set fromIdx $index1
		set toIdx $index2
	    }
	} else {						;# window
	    if {[$aux cget -width] != $auxWidth} {
		$aux configure -width $auxWidth
	    }

	    if {[string compare [lindex [$w dump -window $index1] 1] \
		 $aux] == 0} {
		set auxFound 1
		set fromIdx $index1+1$pu
		set toIdx $index2
	    } elseif {[string compare \
		       [lindex [$w dump -window $index2-1$pu] 1] $aux] == 0} {
		set auxFound 1
		set fromIdx $index1
		set toIdx $index2-1$pu
	    } else {
		set auxFound 0
		set fromIdx $index1
		set toIdx $index2
	    }
	}

	#
	# Work around a Tk peculiarity on Windows, related to deleting
	# an embedded window while resizing a text widget interactively
	#
	set path [lindex [$w dump -window $fromIdx] 1]
	if {[string length $path] != 0 &&
	    [string compare [winfo class $path] "Message"] == 0} {
	    $path configure -text ""
	    $w window configure $fromIdx -window ""
	}

	$w delete $fromIdx $toIdx

	if {$auxFound} {
	    #
	    # Adjust the aux. window and insert the text
	    #
	    if {[string compare $alignment "right"] == 0} {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w $index1 e
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor ne -relwidth "" -relx 1.0
		    } else {					;# dynamic width
			place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
		    }
		}
		set index $index1
	    } else {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w $index1 w
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor nw -relwidth "" -relx 0.0
		    } else {					;# dynamic width
			place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
		    }
		}
		set index $index1+1$pu
	    }
	    if {[string compare $valignment [$w window cget $index1 -align]]
		!= 0} {
		$w window configure $index1 -align $valignment
	    }
	    $w insert $index $text
	} else {
	    #
	    # Insert the text and the aux. window
	    #
	    if {$auxType == 1} {				;# image
		set aux [lreplace $aux end end $auxWidth]
	    } else {						;# window
		if {[$aux cget -width] != $auxWidth} {
		    $aux configure -width $auxWidth
		}
	    }
	    insertElem $w $index1 $text $aux $auxType $alignment $valignment
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateMlCell
#
# Updates the content of the text widget w starting at index1 and ending just
# before index2 by keeping the auxiliary object (image or window) (if any) and
# replacing only the multiline text between the two character positions.
#------------------------------------------------------------------------------
proc tablelist::updateMlCell {w index1 index2 msgScript aux auxType auxWidth
			      indent indentWidth alignment valignment} {
    set tagNames [$w tag names $index2]
    if {[lsearch -exact $tagNames select] >= 0} {		;# selected
	$w tag add select $index1 $index2
    }

    variable pu
    if {$indentWidth != 0} {
	if {[insertOrUpdateIndent $w $index1 $indent $indentWidth]} {
	    set index2 $index2+1$pu
	}
	set index1 $index1+1$pu
    }

    if {$auxWidth == 0} {				;# no image or window
	set areEqual [$w compare $index1 == $index2]
	$w delete $index1+1$pu $index2
	set padY [expr {[$w cget -spacing1] == 0}]
	if {[catch {$w window cget $index1 -create} script] == 0 &&
	    [string match "::tablelist::displayText*" $script]} {
	    $w window configure $index1 \
		      -align top -pady $padY -create $msgScript

	    set path [lindex [$w dump -window $index1] 1]
	    if {[string length $path] != 0 &&
		[string compare [winfo class $path] "Message"] == 0} {
		eval $msgScript
	    }
	} else {
	    if {!$areEqual} {
		$w delete $index1
	    }
	    $w window create $index1 -align top -pady $padY -create $msgScript
	    $w tag add elidedWin $index1
	}
    } else {
	#
	# Check whether the image label or the frame containing a
	# window is mapped at the first or last position of the cell
	#
	$w mark set index2Mark $index2
	if {$auxType == 1} {					;# image
	    if {[setImgLabelWidth $w $index1 $auxWidth]} {
		set auxFound 1
		if {[string compare $alignment "right"] == 0} {
		    $w delete $index1+1$pu $index2
		}
	    } elseif {[setImgLabelWidth $w $index2-1$pu $auxWidth]} {
		set auxFound 1
		if {[string compare $alignment "right"] != 0} {
		    $w delete $index1 $index2-1$pu
		}
	    } else {
		set auxFound 0
		$w delete $index1 $index2
	    }
	} else {						;# window
	    if {[$aux cget -width] != $auxWidth} {
		$aux configure -width $auxWidth
	    }

	    if {[string compare [lindex [$w dump -window $index1] 1] \
		 $aux] == 0} {
		set auxFound 1
		if {[string compare $alignment "right"] == 0} {
		    $w delete $index1+1$pu $index2
		}
	    } elseif {[string compare \
		       [lindex [$w dump -window $index2-1$pu] 1] $aux] == 0} {
		set auxFound 1
		if {[string compare $alignment "right"] != 0} {
		    $w delete $index1 $index2-1$pu
		}
	    } else {
		set auxFound 0
		$w delete $index1 $index2
	    }
	}

	if {$auxFound} {
	    #
	    # Adjust the aux. window and insert the message widget
	    #
	    if {[string compare $alignment "right"] == 0} {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w index2Mark-1$pu e
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor ne -relwidth "" -relx 1.0
		    } else {					;# dynamic width
			place $aux.w -anchor ne -relwidth 1.0 -relx 1.0
		    }
		}
		set auxIdx index2Mark-1$pu
		set msgIdx index2Mark-2$pu
	    } else {
		if {$auxType == 1} {				;# image
		    setImgLabelAnchor $w $index1 w
		} else {					;# window
		    if {$auxType == 2} {			;# static width
			place $aux.w -anchor nw -relwidth "" -relx 0.0
		    } else {					;# dynamic width
			place $aux.w -anchor nw -relwidth 1.0 -relx 0.0
		    }
		}
		set auxIdx $index1
		set msgIdx $index1+1$pu
	    }
	    if {[string compare $valignment [$w window cget $auxIdx -align]]
		!= 0} {
		$w window configure $auxIdx -align $valignment
	    }

	    set padY [expr {[$w cget -spacing1] == 0}]
	    if {[catch {$w window cget $msgIdx -create} script] == 0 &&
		[string match "::tablelist::displayText*" $script]} {
		$w window configure $msgIdx \
			  -align top -pady $padY -create $msgScript

		set path [lindex [$w dump -window $msgIdx] 1]
		if {[string length $path] != 0 &&
		    [string compare [winfo class $path] "Message"] == 0} {
		    eval $msgScript
		}
	    } elseif {[string compare $alignment "right"] == 0} {
		$w window create index2Mark-1$pu \
			  -align top -pady $padY -create $msgScript
		$w tag add elidedWin index2Mark-1$pu
		$w delete $index1 index2Mark-2$pu
	    } else {
		$w window create $index1+1$pu \
			  -align top -pady $padY -create $msgScript
		$w tag add elidedWin $index1+1$pu
		$w delete $index1+2$pu index2Mark
	    }
	} else {
	    #
	    # Insert the message and aux. windows
	    #
	    if {$auxType == 1} {				;# image
		set aux [lreplace $aux end end $auxWidth]
	    } else {						;# window
		if {[$aux cget -width] != $auxWidth} {
		    $aux configure -width $auxWidth
		}
	    }
	    insertMlElem $w $index1 $msgScript $aux $auxType $alignment \
			 $valignment
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::setImgLabelWidth
#
# Sets the width of the image label embedded into the text widget w at the
# given index to the specified value.
#------------------------------------------------------------------------------
proc tablelist::setImgLabelWidth {w index width} {
    if {[catch {$w window cget $index -create} script] == 0 &&
	[string match "::tablelist::displayImage *" $script]} {
	if {$width != [lindex $script end]} {
	    set padY [expr {[$w cget -spacing1] == 0}]
	    set script [lreplace $script end end $width]
	    $w window configure $index -pady $padY -create $script

	    set path [lindex [$w dump -window $index] 1]
	    if {[string length $path] != 0} {
		$path configure -width $width
	    }
	}

	return 1
    } else {
	return 0
    }
}

#------------------------------------------------------------------------------
# tablelist::setImgLabelAnchor
#
# Sets the anchor of the image label embedded into the text widget w at the
# given index to the specified value.
#------------------------------------------------------------------------------
proc tablelist::setImgLabelAnchor {w index anchor} {
    set script [$w window cget $index -create]
    if {[string compare $anchor [lindex $script 4]] != 0} {
	set padY [expr {[$w cget -spacing1] == 0}]
	set script [lreplace $script 4 4 $anchor]
	$w window configure $index -pady $padY -create $script

	set path [lindex [$w dump -window $index] 1]
	if {[string length $path] != 0} {
	    $path configure -anchor $anchor
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::appendComplexElem
#
# Adjusts the given text and the width of the auxiliary object (image or
# window) corresponding to the specified cell of the tablelist widget win, and
# inserts the text and the auxiliary object (if any) just before the newline
# character at the end of the specified line of the tablelist's body.
#------------------------------------------------------------------------------
proc tablelist::appendComplexElem {win key row col text pixels alignment
				   snipStr cellFont cellTags line} {
    #
    # Adjust the cell text and the image or window width
    #
    set multiline [string match "*\n*" $text]
    upvar ::tablelist::ns${win}::data data
    if {$pixels == 0} {				;# convention: dynamic width
	if {$data($col-maxPixels) > 0} {
	    if {$data($col-reqPixels) > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
	    }
	}
    }
    set aux [getAuxData $win $key $col auxType auxWidth $pixels]
    set indent [getIndentData $win $key $col indentWidth]
    set maxTextWidth $pixels
    if {$pixels != 0} {
	incr pixels $data($col-delta)
	set maxTextWidth [getMaxTextWidth $pixels $auxWidth $indentWidth]

	if {$data($col-wrap) && !$multiline} {
	    if {[font measure $cellFont -displayof $win $text] >
		$maxTextWidth} {
		set multiline 1
	    }
	}
    }
    variable snipSides
    set snipSide $snipSides($alignment,$data($col-changesnipside))
    if {$multiline} {
	set list [split $text "\n"]
	if {$data($col-wrap)} {
	    set snipSide ""
	}
	adjustMlElem $win list auxWidth indentWidth $cellFont $pixels \
		     $snipSide $snipStr
	set msgScript [list ::tablelist::displayText $win $key $col \
		       [join $list "\n"] $cellFont $maxTextWidth $alignment]
    } else {
	adjustElem $win text auxWidth indentWidth $cellFont $pixels \
		   $snipSide $snipStr
    }

    #
    # Insert the text and the auxiliary object (if any) just before the newline
    #
    set inBody [string match "k*" $key]
    set w [expr {$inBody ? $data(body) : $data(hdrTxt)}]
    set idx [$w index $line.end]
    variable pu
    if {$auxWidth == 0} {				;# no image or window
	if {$multiline} {
	    $w insert $line.end "\t\t" $cellTags
	    set padY [expr {[$w cget -spacing1] == 0}]
	    $w window create $line.end-1$pu \
		      -align top -pady $padY -create $msgScript
	    $w tag add elidedWin $line.end-1$pu
	} else {
	    $w insert $line.end "\t$text\t" $cellTags
	}
    } else {
	$w insert $line.end "\t\t" $cellTags
	if {$auxType == 1} {					;# image
	    #
	    # Update the creation script for the image label
	    #
	    set aux [lreplace $aux end end $auxWidth]
	} else {						;# window
	    #
	    # Create a frame and evaluate the script that
	    # creates a child window within the frame
	    #
	    tk::frame $aux -borderwidth 0 -class TablelistWindow -container 0 \
			   -height $data($key,$col-reqHeight) \
			   -highlightthickness 0 -relief flat \
			   -takefocus 0 -width $auxWidth
	    catch {$aux configure -padx 0 -pady 0}
	    if {$inBody} {
		bindtags $aux [linsert [bindtags $aux] 1 \
			       $data(bodyTag) TablelistBody]
	    } else {
		bindtags $aux [linsert [bindtags $aux] 1 \
			       $data(headerTag) TablelistHeader]
	    }
	    uplevel #0 $data($key,$col-window) [list $win $row $col $aux.w]
	}
	if {$multiline} {
	    insertMlElem $w $line.end-1$pu $msgScript $aux $auxType \
			 $alignment [getVAlignment $win $key $col]
	} else {
	    insertElem $w $line.end-1$pu $text $aux $auxType \
		       $alignment [getVAlignment $win $key $col]
	}
    }

    #
    # Insert the indentation image, if any
    #
    if {$indentWidth != 0} {
	variable pu
	insertOrUpdateIndent $w $idx+1$pu $indent $indentWidth
    }
}

#------------------------------------------------------------------------------
# tablelist::makeColFontAndTagLists
#
# Builds the lists data(colFontList) of the column fonts and data(colTagsList)
# of the column tag names for the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeColFontAndTagLists win {
    upvar ::tablelist::ns${win}::data data
    set widgetFont $data(-font)
    set data(colFontList) {}
    set data(colTagsList) {}
    set data(hasColTags) 0
    set viewable [winfo viewable $win]
    variable canElide

    for {set col 0} {$col < $data(colCount)} {incr col} {
	set tagNames {}

	if {[info exists data($col-font)]} {
	    lappend data(colFontList) $data($col-font)
	    lappend tagNames col-font-$data($col-font)
	    set data(hasColTags) 1
	} else {
	    lappend data(colFontList) $widgetFont
	}

	if {$viewable && $data($col-hide) && $canElide} {
	    lappend tagNames hiddenCol
	    set data(hasColTags) 1
	}

	lappend data(colTagsList) $tagNames
    }
}

#------------------------------------------------------------------------------
# tablelist::makeSortAndArrowColLists
#
# Builds the lists data(sortColList) of the sort columns and data(arrowColList)
# of the arrow columns for the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeSortAndArrowColLists win {
    upvar ::tablelist::ns${win}::data data
    set data(sortColList) {}
    set data(arrowColList) {}

    #
    # Build a list of {col sortRank} pairs and sort it based on sortRank
    #
    set pairList {}
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {$data($col-sortRank) > 0} {
	    lappend pairList [list $col $data($col-sortRank)]
	}
    }
    set pairList [lsort -integer -index 1 $pairList]

    #
    # Build data(sortColList) and data(arrowColList), and update
    # the sort ranks to have values from 1 to [llength $pairList]
    #
    set sortRank 1
    foreach pair $pairList {
	set col [lindex $pair 0]
	lappend data(sortColList) $col
	set data($col-sortRank) $sortRank
	if {$sortRank < 10 && $data(-showarrow) && $data($col-showarrow)} {
	    lappend data(arrowColList) $col
	    configCanvas $win $col
	    raiseArrow $win $col
	}
	incr sortRank
    }

    #
    # Special handling for the "aqua" theme if Cocoa is being used:
    # Deselect all header labels and select that of the main sort column
    #
    variable specialAquaHandling
    if {$specialAquaHandling &&
	[string compare [getCurrentTheme] "aqua"] == 0} {
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    configLabel $data(hdrTxtFrmLbl)$col -selected 0
	}

	if {[llength $data(sortColList)] != 0} {
	    set col [lindex $data(sortColList) 0]
	    configLabel $data(hdrTxtFrmLbl)$col -selected 1
	    raise $data(hdrTxtFrmLbl)$col
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::setupColumns
#
# Updates the value of the -colums configuration option for the tablelist
# widget win by using the width, title, and alignment specifications given in
# the columns argument, and creates the corresponding label (and separator)
# widgets if createLabels is true.
#------------------------------------------------------------------------------
proc tablelist::setupColumns {win columns createLabels} {
    variable usingTile
    variable configSpecs
    variable configOpts
    variable alignments
    upvar ::tablelist::ns${win}::data data

    set argCount [llength $columns]
    set colConfigVals {}

    #
    # Check the syntax of columns before performing any changes
    #
    for {set n 0} {$n < $argCount} {incr n} {
	#
	# Get the column width
	#
	set width [lindex $columns $n]
	set width [format "%d" $width]	;# integer check with error message

	#
	# Get the column title
	#
	if {[incr n] == $argCount} {
	    return -code error "column title missing"
	}
	set title [lindex $columns $n]

	#
	# Get the column alignment
	#
	set alignment left
	if {[incr n] < $argCount} {
	    set next [lindex $columns $n]
	    if {[isInteger $next]} {
		incr n -1
	    } else {
		set alignment [mwutil::fullOpt "alignment" $next $alignments]
	    }
	}

	#
	# Append the properly formatted values of width,
	# title, and alignment to the list colConfigVals
	#
	lappend colConfigVals $width $title $alignment
    }

    #
    # Save the value of colConfigVals in data(-columns)
    #
    set data(-columns) $colConfigVals

    #
    # Delete the labels, canvases, and separators if requested
    #
    if {$createLabels} {
	foreach w [winfo children $data(hdrTxtFrm)] {
	    destroy $w
	}
	foreach w [winfo children $win] {
	    if {[regexp {^(vsep[0-9]+|hsep2)$} [winfo name $w]]} {
		destroy $w
	    }
	}
	set data(fmtCmdFlagList) {}
	set data(hiddenColCount) 0
    }

    #
    # Build the list data(colList), and create
    # the labels and canvases if requested
    #
    regexp {^(flat|flatAngle|sunken|photo)([0-9]+)x([0-9]+)$} \
	   $data(-arrowstyle) dummy arrowRelief arrowWidth arrowHeight
    set widgetFont $data(-font)
    set oldColCount $data(colCount)
    set data(colList) {}
    set data(colCount) 0
    set data(lastCol) -1
    set col 0
    foreach {width title alignment} $data(-columns) {
	#
	# Append the width in pixels and the
	# alignment to the list data(colList)
	#
	if {$width > 0} {		;# convention: width in characters
	    set pixels [charsToPixels $win $widgetFont $width]
	    set data($col-lastStaticWidth) $pixels
	} elseif {$width < 0} {		;# convention: width in pixels
	    set pixels [expr {(-1)*$width}]
	    set data($col-lastStaticWidth) $pixels
	} else {			;# convention: dynamic width
	    set pixels 0
	}
	lappend data(colList) $pixels $alignment
	incr data(colCount)
	set data(lastCol) $col

	if {$createLabels} {
	    set data($col-elide) 0
	    foreach {name val} {delta 0  lastStaticWidth 0  maxPixels 0
				sortOrder ""  sortRank 0  isSnipped 0
				changesnipside 0  changetitlesnipside 0
				editable 0  editwindow entry  hide 0
				maxwidth 0  resizable 1  showarrow 1
				showlinenumbers 0  sortmode ascii
				valign center  wrap 0} {
		if {![info exists data($col-$name)]} {
		    set data($col-$name) $val
		}
	    }
	    lappend data(fmtCmdFlagList) [info exists data($col-formatcommand)]
	    incr data(hiddenColCount) $data($col-hide)

	    #
	    # Create the label
	    #
	    set w $data(hdrTxtFrmLbl)$col
	    if {$usingTile} {
		ttk::label $w -style TablelistHeader.TLabel -image "" \
			      -padding {1 1 1 1} -takefocus 0 -text "" \
			      -textvariable "" -underline -1 -wraplength 0
	    } else {
		tk::label $w -bitmap "" -highlightthickness 0 -image "" \
			     -takefocus 0 -text "" -textvariable "" \
			     -underline -1 -wraplength 0
	    }

	    #
	    # Apply to it the current configuration options
	    #
	    foreach opt $configOpts {
		set optGrp [lindex $configSpecs($opt) 2]
		if {[string compare $optGrp "l"] == 0} {
		    set optTail [string range $opt 6 end]
		    if {[info exists data($col$opt)]} {
			configLabel $w -$optTail $data($col$opt)
		    } else {
			configLabel $w -$optTail $data($opt)
		    }
		} elseif {[string compare $optGrp "c"] == 0} {
		    configLabel $w $opt $data($opt)
		}
	    }
	    catch {configLabel $w -state $data(-state)}

	    #
	    # Replace the binding tag (T)Label with $data(labelTag) and
	    # TablelistLabel in the list of binding tags of the label
	    #
	    bindtags $w [lreplace [bindtags $w] 1 1 \
			 $data(labelTag) TablelistLabel]

	    #
	    # Create a canvas containing the sort arrows
	    #
	    set w $data(hdrTxtFrmCanv)$col
	    canvas $w -borderwidth 0 -highlightthickness 0 \
		      -relief flat -takefocus 0
	    createArrows $w $arrowWidth $arrowHeight $arrowRelief

	    #
	    # Apply to it the current configuration options
	    #
	    foreach opt $configOpts {
		if {[string compare [lindex $configSpecs($opt) 2] "c"] == 0} {
		    $w configure $opt $data($opt)
		}
	    }

	    #
	    # Replace the binding tag Canvas with $data(labelTag) and
	    # TablelistArrow in the list of binding tags of the canvas
	    #
	    bindtags $w [lreplace [bindtags $w] 1 1 \
			 $data(labelTag) TablelistArrow]

	    if {[info exists data($col-labelimage)]} {
		doColConfig $col $win -labelimage $data($col-labelimage)
	    }
	}

	#
	# Configure the edit window if present
	#
	if {$col == $data(editCol) &&
	    [string compare [winfo class $data(bodyFrmEd)] "Mentry"] != 0} {
	    catch {$data(bodyFrmEd) configure -justify $alignment}
	}

	incr col
    }
    set data(hasFmtCmds) [expr {[lsearch -exact $data(fmtCmdFlagList) 1] >= 0}]

    #
    # Clean up the images, data, and attributes
    # associated with the deleted columns
    #
    set imgNames [image names]
    for {set col $data(colCount)} {$col < $oldColCount} {incr col} {
	set w $data(hdrTxtFrmCanv)$col
	foreach shape {triangleUp darkLineUp lightLineUp
		       triangleDn darkLineDn lightLineDn} {
	    if {[lsearch -exact $imgNames $shape$w] >= 0} {
		image delete $shape$w
	    }
	}

	deleteColData $win $col
	deleteColAttribs $win $col
    }

    #
    # Update data(-treecolumn) and data(treeCol) if needed
    #
    if {$createLabels} {
	set treeCol $data(-treecolumn)
	adjustColIndex $win treeCol
	set data(treeCol) $treeCol
	if {$data(colCount) != 0} {
	    set data(-treecolumn) $treeCol
	}
    }

    #
    # Create the separators if needed
    #
    if {$createLabels && $data(-showseparators)} {
	createSeps $win
    }
}

#------------------------------------------------------------------------------
# tablelist::createSeps
#
# Creates and manages the separators in the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::createSeps win {
    upvar ::tablelist::ns${win}::data data
    variable usingTile
    set sepX [getSepX]

    for {set col 0} {$col < $data(colCount)} {incr col} {
	#
	# Create the col'th separator and attach it to
	# the right edge of the col'th header label
	#
	set w $data(vsep)$col
	if {$usingTile} {
	    ttk::separator $w -style Seps$win.TSeparator \
			      -cursor $data(-cursor) -orient vertical \
			      -takefocus 0
	} else {
	    tk::frame $w -background $data(-background) -borderwidth 1 \
			 -container 0 -cursor $data(-cursor) \
			 -highlightthickness 0 -relief sunken \
			 -takefocus 0 -width 2
	}
	place $w -in $data(hdrTxtFrmLbl)$col -anchor ne -bordermode outside \
		 -relx 1.0 -x $sepX

	#
	# Replace the binding tag TSeparator or Frame with $data(bodyTag)
	# and TablelistBody in the list of binding tags of the separator
	#
	bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]
    }

    #
    # Create the lower horizontal separator
    #
    set w $data(hsep)2
    if {$usingTile} {
	ttk::separator $w -style Seps$win.TSeparator -cursor $data(-cursor) \
			  -takefocus 0
    } else {
	tk::frame $w -background $data(-background) -borderwidth 1 \
		     -container 0 -cursor $data(-cursor) -height 2 \
		     -highlightthickness 0 -relief sunken -takefocus 0
    }

    #
    # Replace the binding tag TSeparator or Frame with $data(bodyTag) and
    # TablelistBody in the list of binding tags of the horizontal separator
    #
    bindtags $w [lreplace [bindtags $w] 1 1 $data(bodyTag) TablelistBody]

    adjustSepsWhenIdle $win
}

#------------------------------------------------------------------------------
# tablelist::adjustSepsWhenIdle
#
# Arranges for the height and vertical position of each separator in the
# tablelist widget win to be adjusted at idle time.
#------------------------------------------------------------------------------
proc tablelist::adjustSepsWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(sepsId)]} {
	return ""
    }

    set data(sepsId) [after idle [list tablelist::adjustSeps $win]]
}

#------------------------------------------------------------------------------
# tablelist::adjustSeps
#
# Adjusts the height and position of each separator in the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::adjustSeps win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(sepsId)]} {
	after cancel $data(sepsId)
	unset data(sepsId)
    }

    variable winSys
    set onWindows [expr {[string compare $winSys "win32"] == 0}]
    variable usingTile
    set sepX [getSepX]

    #
    # Get the height to be applied to the column separators
    # and place or unmanage the lower horizontal separator
    #
    set w $data(body)
    if {$data(-fullseparators)} {
	set sepHeight [winfo height $w]

	if {[winfo exists $data(hsep)2]} {
	    place forget $data(hsep)2
	}
    } else {
	set btmTextIdx [$w index @0,$data(btmY)]
	set btmLine [expr {int($btmTextIdx)}]
	if {$btmLine > $data(itemCount)} {
	    set btmLine $data(itemCount)
	    set btmTextIdx $btmLine.0
	}
	set dlineinfo [$w dlineinfo $btmTextIdx]
	if {$data(itemCount) == 0 || [llength $dlineinfo] == 0} {
	    set sepHeight 0
	} else {
	    foreach {x y width height baselinePos} $dlineinfo {}
	    set sepHeight [expr {$y + $height}]
	}

	if {$data(-showhorizseparator) && $data(-showseparators) &&
	    $sepHeight > 0 && $sepHeight < [winfo height $w]} {
	    set width [expr {[winfo reqwidth $data(hdrTxtFrm)] + $sepX -
			     [winfo reqheight $data(hsep)2] + 1}]
	    if {$onWindows && !$usingTile} {
		incr width
	    }
	    place $data(hsep)2 -in $w -y $sepHeight -width $width
	} elseif {[winfo exists $data(hsep)2]} {
	    place forget $data(hsep)2
	}
    }

    #
    # Set the height of the vertical main separator (if any) and attach
    # the latter to the right edge of the last non-hidden title column
    #
    set startCol [expr {$data(-titlecolumns) - 1}]
    if {$startCol > $data(lastCol)} {
	set startCol $data(lastCol)
    }
    for {set col $startCol} {$col >= 0} {incr col -1} {
	if {!$data($col-hide)} {
	    break
	}
    }
    set mainSepHeight [expr {$sepHeight + [winfo height $data(hdr)] - 1}]
    set w $data(vsep)
    if {$col < 0 || $mainSepHeight == 0} {
	if {[winfo exists $w]} {
	    place forget $w
	}
    } else {
	if {!$data(-showlabels)} {
	    incr mainSepHeight
	}
	place $w -in $data(hdrTxtFrmLbl)$col -anchor ne -bordermode outside \
		 -height $mainSepHeight -relx 1.0 -x $sepX -y 1
	raise $w
    }

    #
    # Place or unmanage the upper horizontal separator (if any)
    #
    set w $data(hsep)1
    if {[winfo exists $w]} {
	if {$data(hdr_itemCount) == 0} {
	    place forget $w
	} else {
	    set width [expr {[winfo reqwidth $data(hdrTxtFrm)] + $sepX -
			     [winfo reqheight $data(hsep)1] + 1}]
	    if {$onWindows && !$usingTile} {
		incr width
	    }
	    place $w -in $data(hdr) -anchor sw -rely 1.0 -width $width
	    raise $w
	}
    }

    #
    # Set the height and vertical position of the other column separators
    #
    if {$sepHeight == 0 && $data(hdr_itemCount) == 0} {
	set relY 0.0
	set y -10
    } elseif {$data(-showlabels)} {
	set relY 1.0
	if {$usingTile || $onWindows} {
	    set y 0
	    incr sepHeight 1
	} else {
	    set y -1
	    incr sepHeight 2
	}
    } else {
	set relY 0.0
	if {$usingTile || $onWindows} {
	    set y 1
	    incr sepHeight 2
	} else {
	    set y 0
	    incr sepHeight 3
	}
    }
    incr sepHeight [expr {[winfo reqheight $data(hdr)] -
			  [winfo reqheight $data(hdrTxtFrm)]}]
    if {!$data(-showlabels)} {
	incr sepHeight -1
    }
    foreach w [winfo children $win] {
	if {[regexp {^vsep[0-9]+$} [winfo name $w]]} {
	    place configure $w -height $sepHeight -rely $relY -y $y
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::getSepX
#
# Returns the value of the -x option to be used when placing a separator
# relative to the corresponding header label, with -anchor ne.
#------------------------------------------------------------------------------
proc tablelist::getSepX {} {
    set x 1
    variable usingTile
    if {$usingTile} {
	set currentTheme [getCurrentTheme]
	variable xpStyle
	if {([string compare $currentTheme "aqua"] == 0) ||
	    ([string compare $currentTheme "xpnative"] == 0 && $xpStyle)} {
	    set x 0
	} elseif {[string compare $currentTheme "tileqt"] == 0} {
	    switch -- [string tolower [tileqt_currentThemeName]] {
		cleanlooks -
		gtk+ -
		oxygen	{ set x 0 }
		qtcurve	{ set x 2 }
	    }
	}
    }

    return $x
}

#------------------------------------------------------------------------------
# tablelist::adjustColumns
#
# Applies some configuration options to the labels of the tablelist widget win,
# places them in the header frame, computes and sets the tab stops for both
# text widgets, and adjusts the width and height of the header frame.  The
# whichWidths argument specifies the dynamic-width columns or labels whose
# widths are to be computed when performing these operations.  The stretchCols
# argument specifies whether to stretch the stretchable columns.
#------------------------------------------------------------------------------
proc tablelist::adjustColumns {win whichWidths stretchCols} {
    set compAllColWidths [expr {[string compare $whichWidths "allCols"] == 0}]
    set compAllLabelWidths \
	[expr {[string compare $whichWidths "allLabels"] == 0}]

    variable usingTile
    set usingAquaTheme \
	[expr {$usingTile && [string compare [getCurrentTheme] "aqua"] == 0}]

    #
    # Configure the labels and compute the positions
    # of the tab stops to be set in both text widgets
    #
    upvar ::tablelist::ns${win}::data data
    set data(hdrWidth) 0
    variable canElide
    variable centerArrows
    set tabs {}
    set col 0
    set x 0
    foreach {pixels alignment} $data(colList) {
	set w $data(hdrTxtFrmLbl)$col
	if {$data($col-hide) && !$canElide} {
	    place forget $w
	    incr col
	    continue
	}

	#
	# Adjust the col'th label
	#
	if {[info exists data($col-labelalign)]} {
	    set labelAlignment $data($col-labelalign)
	} else {
	    set labelAlignment $alignment
	}
	if {$pixels != 0} {			;# convention: static width
	    incr pixels $data($col-delta)
	}
	adjustLabel $win $col $pixels $labelAlignment

	if {$pixels == 0} {			;# convention: dynamic width
	    #
	    # Compute the column or label width if requested
	    #
	    if {$compAllColWidths || [lsearch -exact $whichWidths $col] >= 0} {
		computeColWidth $win $col
	    } elseif {$compAllLabelWidths ||
		      [lsearch -exact $whichWidths l$col] >= 0} {
		computeLabelWidth $win $col
	    }

	    set pixels $data($col-reqPixels)
	    if {$data($col-maxPixels) > 0 && $pixels > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
		incr pixels $data($col-delta)
		adjustLabel $win $col $pixels $labelAlignment
	    } else {
		incr pixels $data($col-delta)
	    }
	}

	if {$col == $data(editCol) &&
	    ![string match "*Checkbutton" [winfo class $data(bodyFrmEd)]]} {
	    adjustEditWindow $win $pixels
	}

	set canvas $data(hdrTxtFrmCanv)$col
	if {[lsearch -exact $data(arrowColList) $col] >= 0 &&
	    !$data($col-elide) && !$data($col-hide)} {
	    #
	    # Center the canvas horizontally just below the upper edge of
	    # the label, or place it to the left side of the label if the
	    # latter is right-justified and to its right side otherwise
	    #
	    if {$centerArrows} {
		place $canvas -in $w -anchor n -bordermode outside \
			      -relx 0.5 -y 1
	    } else {
		set y 0
		if {([winfo reqheight $w] - [winfo reqheight $canvas]) % 2 == 0
		    && $data(arrowHeight) == 5} {
		    set y -1
		}
		if {[string compare $labelAlignment "right"] == 0} {
		    place $canvas -in $w -anchor w -bordermode outside \
				  -relx 0.0 -x $data(charWidth) \
				  -rely 0.49 -y $y
		} else {
		    place $canvas -in $w -anchor e -bordermode outside \
				  -relx 1.0 -x -$data(charWidth) \
				  -rely 0.49 -y $y
		}
	    }
	    raise $canvas
	} else {
	    place forget $canvas
	}

	#
	# Place the label in the header frame
	#
	if {$data($col-elide) || $data($col-hide)} {
	    foreach l [getSublabels $w] {
		place forget $l
	    }
	    place $w -x [expr {$x - 1}] -relheight 1.0 -width 1
	    lower $w
	} else {
	    set x2 $x
	    set labelPixels [expr {$pixels + 2*$data(charWidth)}]
	    if {$usingAquaTheme} {
		incr x2 -1
		incr labelPixels
		if {$col == 0} {
		    incr x2 -1
		    incr labelPixels
		}
	    }
	    place $w -x $x2 -relheight 1.0 -width $labelPixels
	}

	#
	# Append a tab stop and the alignment to the tabs list
	#
	if {!$data($col-elide) && !$data($col-hide)} {
	    incr x $data(charWidth)
	    switch $alignment {
		left {
		    lappend tabs $x left
		    incr x $pixels
		}
		right {
		    incr x $pixels
		    lappend tabs $x right
		}
		center {
		    lappend tabs [expr {$x + $pixels/2}] center
		    incr x $pixels
		}
	    }
	    incr x $data(charWidth)
	    lappend tabs $x left
	}

	incr col
    }
    place configure $data(hdrFrm) -x $x

    #
    # Apply the value of tabs to both text widgets
    #
    $data(hdrTxt) configure -tabs $tabs
    if {[info exists data(colBeingResized)]} {
	$data(body) tag configure visibleLines -tabs $tabs
    } else {
	$data(body) configure -tabs $tabs
    }

    #
    # Adjust the width and height of the frames data(hdrTxtFrm) and data(hdr)
    #
    $data(hdrTxtFrm) configure -width $x
    if {$data(-width) <= 0} {
	if {$stretchCols} {
	    $data(hdr) configure -width $x
	    $data(lb) configure -width [expr {$x / $data(charWidth)}]
	}
    } else {
	$data(hdr) configure -width 0
    }
    set data(hdrWidth) $x
    adjustHeaderHeight $win

    #
    # Stretch the stretchable columns if requested, and update
    # the scrolled column offset and the horizontal scrollbar
    #
    if {$stretchCols} {
	stretchColumnsWhenIdle $win
    }
    if {![info exists data(colBeingResized)]} {
	updateScrlColOffsetWhenIdle $win
    }
    updateHScrlbarWhenIdle $win
}

#------------------------------------------------------------------------------
# tablelist::adjustLabel
#
# Applies some configuration options to the col'th label of the tablelist
# widget win as well as to the label's sublabels (if any), and places the
# sublabels.
#------------------------------------------------------------------------------
proc tablelist::adjustLabel {win col pixels alignment} {
    variable usingTile
    set usingAquaTheme \
	[expr {$usingTile && [string compare [getCurrentTheme] "aqua"] == 0}]

    #
    # Apply some configuration options to the label and its sublabels (if any)
    #
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrmLbl)$col
    variable anchors
    set anchor $anchors($alignment)
    set borderWidth [winfo pixels $w [$w cget -borderwidth]]
    if {$borderWidth < 0} {
	set borderWidth 0
    }
    set padX [expr {$data(charWidth) - $borderWidth}]
    if {$padX < 0} {
	set padX 0
    }
    set padL $padX
    set padR $padX
    set marginL $data(charWidth)
    set marginR $data(charWidth)
    if {$usingAquaTheme} {
	incr padL
	incr marginL
	if {$col == 0} {
	    incr padL
	    incr marginL
	}
	set padding [$w cget -padding]
	lset padding 0 $padL
	lset padding 2 $padR
	$w configure -anchor $anchor -justify $alignment -padding $padding
    } else {
	configLabel $w -anchor $anchor -justify $alignment -padx $padX
    }
    if {[info exists data($col-labelimage)]} {
	set imageWidth [image width $data($col-labelimage)]
	$w-tl configure -anchor $anchor -justify $alignment
    } else {
	set imageWidth 0
    }

    #
    # Make room for the canvas displaying an up- or down-arrow if needed
    #
    set title [lindex $data(-columns) [expr {3*$col + 1}]]
    set labelFont [$w cget -font]
    set spaces ""
    set spacePixels 0
    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
	set canvas $data(hdrTxtFrmCanv)$col
	set canvasWidth $data(arrowWidth)
	if {[llength $data(arrowColList)] > 1} {
	    incr canvasWidth 6
	    $canvas itemconfigure sortRank \
		    -image sortRank$data($col-sortRank)$win
	}
	$canvas configure -width $canvasWidth

	variable centerArrows
	if {!$centerArrows} {
	    set spaceWidth [font measure $labelFont -displayof $w " "]
	    set spaces "  "
	    set n 2
	    while {$n*$spaceWidth < $canvasWidth + $data(charWidth)} {
		append spaces " "
		incr n
	    }
	    set spacePixels [expr {$n * $spaceWidth}]
	}
    }

    set data($col-isSnipped) 0
    if {$pixels == 0} {				;# convention: dynamic width
	#
	# Set the label text
	#
	if {$imageWidth == 0} {				;# no image
	    if {[string length $title] == 0} {
		set text $spaces
	    } else {
		set lines {}
		foreach line [split $title "\n"] {
		    if {[string compare $alignment "right"] == 0} {
			lappend lines $spaces$line
		    } else {
			lappend lines $line$spaces
		    }
		}
		set text [join $lines "\n"]
	    }
	    $w configure -text $text
	} elseif {[string length $title] == 0} {	;# image w/o text
	    $w configure -text ""
	    set text $spaces
	    $w-tl configure -text $text
	    $w-il configure -width $imageWidth
	} else {					;# both image and text
	    $w configure -text ""
	    set lines {}
	    foreach line [split $title "\n"] {
		if {[string compare $alignment "right"] == 0} {
		    lappend lines "$spaces$line "
		} else {
		    lappend lines " $line$spaces"
		}
	    }
	    set text [join $lines "\n"]
	    $w-tl configure -text $text
	    $w-il configure -width $imageWidth
	}
    } else {
	#
	# Clip each line of title according to pixels and alignment
	#
	set lessPixels [expr {$pixels - $spacePixels}]
	variable snipSides
	set snipSide $snipSides($alignment,$data($col-changetitlesnipside))
	if {$imageWidth == 0} {				;# no image
	    if {[string length $title] == 0} {
		set text $spaces
	    } else {
		set lines {}
		foreach line [split $title "\n"] {
		    set lineSav $line
		    set line [strRange $win $line $labelFont \
			      $lessPixels $snipSide $data(-snipstring)]
		    if {[string compare $line $lineSav] != 0} {
			set data($col-isSnipped) 1
		    }
		    if {[string compare $alignment "right"] == 0} {
			lappend lines $spaces$line
		    } else {
			lappend lines $line$spaces
		    }
		}
		set text [join $lines "\n"]
	    }
	    $w configure -text $text
	} elseif {[string length $title] == 0} {	;# image w/o text
	    $w configure -text ""
	    if {$imageWidth + $spacePixels <= $pixels} {
		set text $spaces
		$w-tl configure -text $text
		$w-il configure -width $imageWidth
	    } elseif {$spacePixels < $pixels} {
		set text $spaces
		$w-tl configure -text $text
		$w-il configure -width [expr {$pixels - $spacePixels}]
	    } else {
		set imageWidth 0			;# can't disp. the image
		set text ""
	    }
	} else {					;# both image and text
	    $w configure -text ""
	    set gap [font measure $labelFont -displayof $win " "]
	    if {$imageWidth + $gap + $spacePixels <= $pixels} {
		incr lessPixels -[expr {$imageWidth + $gap}]
		set lines {}
		foreach line [split $title "\n"] {
		    set lineSav $line
		    set line [strRange $win $line $labelFont \
			      $lessPixels $snipSide $data(-snipstring)]
		    if {[string compare $line $lineSav] != 0} {
			set data($col-isSnipped) 1
		    }
		    if {[string compare $alignment "right"] == 0} {
			lappend lines "$spaces$line "
		    } else {
			lappend lines " $line$spaces"
		    }
		}
		set text [join $lines "\n"]
		$w-tl configure -text $text
		$w-il configure -width $imageWidth
	    } elseif {$imageWidth + $spacePixels <= $pixels} {	
		set data($col-isSnipped) 1
		set text $spaces		;# can't display the orig. text
		$w-tl configure -text $text
		$w-il configure -width $imageWidth
	    } elseif {$spacePixels < $pixels} {
		set data($col-isSnipped) 1
		set text $spaces		;# can't display the orig. text
		$w-tl configure -text $text
		$w-il configure -width [expr {$pixels - $spacePixels}]
	    } else {
		set data($col-isSnipped) 1
		set imageWidth 0		;# can't display the image
		set text ""			;# can't display the text
	    }
	}
    }

    #
    # Place the label's sublabels (if any)
    #
    if {$imageWidth == 0} {
	if {[info exists data($col-labelimage)]} {
	    place forget $w-il
	    place forget $w-tl
	}
    } else {
	if {[string length $text] == 0} {
	    place forget $w-tl
	}

	variable usingTile
	switch $alignment {
	    left {
		place $w-il -in $w -anchor w -bordermode outside \
			    -relx 0.0 -x $marginL -rely 0.49
		raise $w-il
		if {$usingTile} {
		    set padding [$w cget -padding]
		    lset padding 0 [incr padL [winfo reqwidth $w-il]]
		    $w configure -padding $padding -text $text
		} elseif {[string length $text] != 0} {
		    set textX [expr {$marginL + [winfo reqwidth $w-il]}]
		    place $w-tl -in $w -anchor w -bordermode outside \
				-relx 0.0 -x $textX -rely 0.49
		}
	    }

	    right {
		place $w-il -in $w -anchor e -bordermode outside \
			    -relx 1.0 -x -$marginR -rely 0.49
		raise $w-il
		if {$usingTile} {
		    set padding [$w cget -padding]
		    lset padding 2 [incr padR [winfo reqwidth $w-il]]
		    $w configure -padding $padding -text $text
		} elseif {[string length $text] != 0} {
		    set textX [expr {-$marginR - [winfo reqwidth $w-il]}]
		    place $w-tl -in $w -anchor e -bordermode outside \
				-relx 1.0 -x $textX -rely 0.49
		}
	    }

	    center {
		if {$usingTile} {
		    set padding [$w cget -padding]
		    lset padding 0 [incr padL [winfo reqwidth $w-il]]
		    $w configure -padding $padding -text $text
		}

		if {[string length $text] == 0} {
		    place $w-il -in $w -anchor center -relx 0.5 -x 0 -rely 0.49
		} else {
		    set reqWidth [expr {[winfo reqwidth $w-il] +
					[winfo reqwidth $w-tl]}]
		    set iX [expr {-$reqWidth/2}]
		    place $w-il -in $w -anchor w -relx 0.5 -x $iX -rely 0.49
		    if {!$usingTile} {
			set tX [expr {$reqWidth + $iX}]
			place $w-tl -in $w -anchor e -relx 0.5 -x $tX -rely 0.49
		    }
		}
		raise $w-il
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::computeColWidth
#
# Computes the width of the col'th column of the tablelist widget win to be just
# large enough to hold all the elements of the column (including its label).
#------------------------------------------------------------------------------
proc tablelist::computeColWidth {win col} {
    upvar ::tablelist::ns${win}::data data
    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
    set data($col-elemWidth) 0
    set data($col-widestCount) 0

    #
    # Column elements in the header text widget
    #
    set row -1
    foreach item $data(hdr_itemList) {
	incr row

	if {$col >= [llength $item] - 1} {
	    continue
	}

	set key [lindex $item end]

	set text [lindex $item $col]
	if {$fmtCmdFlag} {
	    set text [formatElem $win $key $row $col $text]
	}
	if {[string match "*\t*" $text]} {
	    set text [mapTabs $text]
	}
	getAuxData $win $key $col auxType auxWidth
	set cellFont [getCellFont $win $key $col]
	set elemWidth [getElemWidth $win $text $auxWidth 0 $cellFont]
	if {$elemWidth == $data($col-elemWidth)} {
	    incr data($col-widestCount)
	} elseif {$elemWidth > $data($col-elemWidth)} {
	    set data($col-elemWidth) $elemWidth
	    set data($col-widestCount) 1
	}
    }

    #
    # Column elements in the body text widget
    #
    set row -1
    foreach item $data(itemList) {
	incr row

	if {$col >= [llength $item] - 1} {
	    continue
	}

	set key [lindex $item end]
	if {[info exists data($key-elide)] || [info exists data($key-hide)]} {
	    continue
	}

	set text [lindex $item $col]
	if {$fmtCmdFlag} {
	    set text [formatElem $win $key $row $col $text]
	}
	if {[string match "*\t*" $text]} {
	    set text [mapTabs $text]
	}
	getAuxData $win $key $col auxType auxWidth
	getIndentData $win $key $col indentWidth
	set cellFont [getCellFont $win $key $col]
	set elemWidth [getElemWidth $win $text $auxWidth $indentWidth $cellFont]
	if {$elemWidth == $data($col-elemWidth)} {
	    incr data($col-widestCount)
	} elseif {$elemWidth > $data($col-elemWidth)} {
	    set data($col-elemWidth) $elemWidth
	    set data($col-widestCount) 1
	}
    }

    set data($col-reqPixels) $data($col-elemWidth)

    #
    # Column label
    #
    computeLabelWidth $win $col
}

#------------------------------------------------------------------------------
# tablelist::computeLabelWidth
#
# Computes the width of the col'th label of the tablelist widget win and
# adjusts the column's width accordingly.
#------------------------------------------------------------------------------
proc tablelist::computeLabelWidth {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrmLbl)$col
    if {[info exists data($col-labelimage)]} {
	variable usingTile
	if {$usingTile} {
	    set netLabelWidth [expr {[winfo reqwidth $w] - 2*$data(charWidth)}]
	} else {
	    set netLabelWidth \
		[expr {[winfo reqwidth $w-il] + [winfo reqwidth $w-tl]}]
	}
    } else {
	set netLabelWidth [expr {[winfo reqwidth $w] - 2*$data(charWidth)}]
    }

    if {$netLabelWidth < $data($col-elemWidth)} {
	set data($col-reqPixels) $data($col-elemWidth)
    } else {
	set data($col-reqPixels) $netLabelWidth
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustHeaderHeight
#
# Sets the height of the header frame of the tablelist widget win to the max.
# height of its children.
#------------------------------------------------------------------------------
proc tablelist::adjustHeaderHeight win {
    upvar ::tablelist::ns${win}::data data

    #
    # Set the height of the header frame and some of its descendants
    #
    $data(hdrTxt) tag raise tinyFont
    $data(hdrTxt) tag remove tinyFont 2.0 end
    if {$data(-showlabels)} {
	#
	# Compute the max. label height
	#
	set maxLabelHeight [winfo reqheight $data(hdrFrmLbl)]
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    set w $data(hdrTxtFrmLbl)$col
	    if {[string length [winfo manager $w]] == 0} {
		continue
	    }

	    set reqHeight [winfo reqheight $w]
	    if {$reqHeight > $maxLabelHeight} {
		set maxLabelHeight $reqHeight
	    }

	    foreach l [getSublabels $w] {
		if {[string length [winfo manager $l]] == 0} {
		    continue
		}

		set borderWidth [winfo pixels $w [$w cget -borderwidth]]
		if {$borderWidth < 0} {
		    set borderWidth 0
		}
		set reqHeight [expr {[winfo reqheight $l] + 2*$borderWidth}]
		if {$reqHeight > $maxLabelHeight} {
		    set maxLabelHeight $reqHeight
		}
	    }
	}

	$data(hdrTxtFrm) configure -height $maxLabelHeight
	if {$data(hdr_itemCount) == 0} {
	    set hdrHeight $maxLabelHeight
	} else {
	    set hdrHeight [$data(hdrTxt) count -update -ypixels 1.0 end]
	    incr hdrHeight 2
	}
	$data(hdr) configure -height $hdrHeight
	$data(hdrFrm) configure -height $maxLabelHeight

	place configure $data(hdrTxt) -y 0
	place configure $data(hdrFrm) -y 0

	$data(corner) configure -height $maxLabelHeight
	place configure $data(cornerLbl) -y 0
    } else {
	$data(hdrTxtFrm) configure -height 1
	if {$data(hdr_itemCount) == 0} {
	    set hdrHeight 1
	} else {
	    set hdrHeight [$data(hdrTxt) count -update -ypixels 1.0 end]
	    incr hdrHeight 2
	}
	$data(hdr) configure -height $hdrHeight
	$data(hdrFrm) configure -height 1

	place configure $data(hdrTxt) -y -1
	place configure $data(hdrFrm) -y -1

	$data(corner) configure -height 1
	place configure $data(cornerLbl) -y -1
    }

    adjustSepsWhenIdle $win
}

#------------------------------------------------------------------------------
# tablelist::stretchColumnsWhenIdle
#
# Arranges for the stretchable columns of the tablelist widget win to be
# stretched at idle time.
#------------------------------------------------------------------------------
proc tablelist::stretchColumnsWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stretchId)]} {
	return ""
    }

    set data(stretchId) [after idle [list tablelist::stretchColumns $win -1]]
}

#------------------------------------------------------------------------------
# tablelist::stretchColumns
#
# Stretches the stretchable columns to fill the tablelist window win
# horizontally.  The colOfFixedDelta argument specifies the column for which
# the stretching is to be made using a precomputed amount of pixels.
#------------------------------------------------------------------------------
proc tablelist::stretchColumns {win colOfFixedDelta} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stretchId)]} {
	after cancel $data(stretchId)
	unset data(stretchId)
    }

    set forceAdjust $data(forceAdjust)
    set data(forceAdjust) 0

    if {$data(hdrWidth) == 0 || $data(-width) <= 0} {
	return ""
    }

    #
    # Get the list data(stretchableCols) of the
    # numerical indices of the stretchable columns
    #
    set data(stretchableCols) {}
    if {[string compare $data(-stretch) "all"] == 0} {
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    lappend data(stretchableCols) $col
	}
    } else {
	foreach col $data(-stretch) {
	    lappend data(stretchableCols) [colIndex $win $col 0]
	}
    }

    #
    # Compute the total number data(delta) of pixels by which the
    # columns are to be stretched and the total amount
    # data(stretchablePixels) of stretchable column widths in pixels
    #
    set data(delta) [winfo width $data(hdr)]
    set data(stretchablePixels) 0
    set lastColToStretch -1
    set col 0
    foreach {pixels alignment} $data(colList) {
	if {$data($col-hide)} {
	    incr col
	    continue
	}

	if {$pixels == 0} {			;# convention: dynamic width
	    set pixels $data($col-reqPixels)
	    if {$data($col-maxPixels) > 0} {
		if {$pixels > $data($col-maxPixels)} {
		    set pixels $data($col-maxPixels)
		}
	    }
	}
	incr data(delta) -[expr {$pixels + 2*$data(charWidth)}]
	if {[lsearch -exact $data(stretchableCols) $col] >= 0} {
	    incr data(stretchablePixels) $pixels
	    set lastColToStretch $col
	}

	incr col
    }
    if {$data(delta) < 0} {
	set delta 0
    } else {
	set delta $data(delta)
    }
    if {$data(stretchablePixels) == 0 && !$forceAdjust} {
	return ""
    }

    #
    # Distribute the value of delta to the stretchable
    # columns, proportionally to their widths in pixels
    #
    set rest $delta
    set col 0
    foreach {pixels alignment} $data(colList) {
	if {$data($col-hide) ||
	    [lsearch -exact $data(stretchableCols) $col] < 0} {
	    set data($col-delta) 0
	} else {
	    set oldDelta $data($col-delta)
	    if {$pixels == 0} {			;# convention: dynamic width
		set dynamic 1
		set pixels $data($col-reqPixels)
		if {$data($col-maxPixels) > 0} {
		    if {$pixels > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
			set dynamic 0
		    }
		}
	    } else {
		set dynamic 0
	    }
	    if {$data(stretchablePixels) == 0} {
		set data($col-delta) 0
	    } else {
		if {$col != $colOfFixedDelta} {
		    set data($col-delta) \
			[expr {$delta*$pixels/$data(stretchablePixels)}]
		}
		incr rest -$data($col-delta)
	    }
	    if {$col == $lastColToStretch} {
		incr data($col-delta) $rest
	    }
	    if {!$dynamic && $data($col-delta) != $oldDelta} {
		redisplayColWhenIdle $win $col
	    }
	}

	incr col
    }

    #
    # Adjust the columns and schedule a view update for execution at idle time
    #
    adjustColumns $win {} 0
    updateViewWhenIdle $win 1
}

#------------------------------------------------------------------------------
# tablelist::moveActiveTag
#
# Moves the "active" tag to the line or cell that displays the active item or
# element of the tablelist widget win in its body text child.
#------------------------------------------------------------------------------
proc tablelist::moveActiveTag win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    $w tag remove curRow 1.0 end
    $w tag remove active 1.0 end

    if {$data(itemCount) == 0 || $data(colCount) == 0} {
	return ""
    }

    set activeLine [expr {$data(activeRow) + 1}]
    set activeCol $data(activeCol)
    if {[string compare $data(-selecttype) "row"] == 0} {
	$w tag add active $activeLine.0 $activeLine.end
	updateColors $win $activeLine.0 $activeLine.end
    } elseif {$activeLine > 0 && $activeCol < $data(colCount) &&
	      !$data($activeCol-hide)} {
	$w tag add curRow $activeLine.0 $activeLine.end
	findTabs $win $w $activeLine $activeCol $activeCol tabIdx1 tabIdx2
	variable pu
	$w tag add active $tabIdx1 $tabIdx2+1$pu
	updateColors $win $activeLine.0 $activeLine.end
    }
}

#------------------------------------------------------------------------------
# tablelist::updateColorsWhenIdle
#
# Arranges for the background and foreground colors of the label, frame, and
# message widgets containing the currently visible images, embedded windows,
# and multiline elements in the body text widget of the tablelist widget win to
# be updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateColorsWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(colorsId)]} {
	return ""
    }

    set data(colorsId) [after idle [list tablelist::updateColors $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateColors
#
# Updates the background and foreground colors of the label, frame, and message
# widgets containing the currently visible images, embedded windows, and
# multiline elements in the body text widget of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::updateColors {win {fromTextIdx ""} {toTextIdx ""}} {
    upvar ::tablelist::ns${win}::data data
    if {[string length $fromTextIdx] == 0} {
	set updateAll 1

	if {[info exists data(colorsId)]} {
	    after cancel $data(colorsId)
	    unset data(colorsId)
	}
    } else {
	set updateAll 0
    }

    if {$data(itemCount) == 0 || [info exists data(dispId)]} {
	return ""
    }

    set leftCol [colIndex $win @0,0 0 0]
    if {$leftCol < 0} {
	return ""
    }

    variable pu
    set w $data(body)
    if {$updateAll} {
	set topTextIdx [$w index @0,0]
	set btmTextIdx [$w index @0,$data(btmY)]
	set fromTextIdx "$topTextIdx linestart"
	set toTextIdx   "$btmTextIdx lineend"

	if {$data(isDisabled)} {
	    $w tag add disabled $fromTextIdx $toTextIdx
	}

	if {[string length $data(-colorizecommand)] == 0} {
	    set hasColorizeCmd 0
	} else {
	    set hasColorizeCmd 1
	    set colorizeCmd $data(-colorizecommand)
	}

	variable canElide
	variable elide
	set rightCol [colIndex $win @$data(rightX),0 0 0]
	set topLine [expr {int($topTextIdx)}]
	set btmLine [expr {int($btmTextIdx)}]
	if {$btmLine > $data(itemCount)} {
	    set btmLine $data(itemCount)
	}
	for {set line $topLine; set row [expr {$line - 1}]} \
	    {$line <= $btmLine} {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {[info exists data($key-elide)] ||
		[info exists data($key-hide)]} {
		continue
	    }

	    #
	    # Handle the -stripebackground and -stripeforeground
	    # column configuration options, as well as the
	    # -(select)background and -(select)foreground column,
	    # row, and cell configuration options in this row
	    #
	    findTabs $win $w $line $leftCol $leftCol tabIdx1 tabIdx2
	    set lineTagNames [$w tag names $tabIdx1]
	    set inStripe [expr {[lsearch -exact $lineTagNames stripe] >= 0}]
	    for {set col $leftCol} {$col <= $rightCol} {incr col} {
		if {$data($col-hide) && !$canElide} {
		    continue
		}

		set textIdx2 [$w index $tabIdx2+1$pu]

		set cellTagNames [$w tag names $tabIdx2]
		foreach tag $cellTagNames {
		    if {[string match "*-*ground-*" $tag]} {
			$w tag remove $tag $tabIdx1 $textIdx2
		    }
		}

		if {$inStripe} {
		    foreach opt {-stripebackground -stripeforeground} {
			set name $col$opt
			if {[info exists data($name)]} {
			    $w tag add col$opt-$data($name) $tabIdx1 $textIdx2
			}
		    }
		}

		set selected [expr {[lsearch -exact $cellTagNames select] >= 0}]
		foreach optTail {background foreground} {
		    set normalOpt -$optTail
		    set selectOpt -select$optTail
		    foreach level      [list col row cell] \
			    normalName [list $col$normalOpt $key$normalOpt \
					$key,$col$normalOpt] \
			    selectName [list $col$selectOpt $key$selectOpt \
					$key,$col$selectOpt] {
			if {$selected} {
			    if {[info exists data($selectName)]} {
				$w tag add $level$selectOpt-$data($selectName) \
				       $tabIdx1 $textIdx2
			    }
			} else {
			    if {[info exists data($normalName)]} {
				$w tag add $level$normalOpt-$data($normalName) \
				       $tabIdx1 $textIdx2
			    }
			}
		    }
		}

		if {$hasColorizeCmd} {
		    uplevel #0 $colorizeCmd [list $win $w $key $row $col \
			$tabIdx1 $tabIdx2 $inStripe $selected]
		}

		set tabIdx1 $textIdx2
		set tabIdx2 [$w search $elide "\t" $tabIdx1+1$pu $line.end]
	    }
	}
    }

    set hasExpCollCtrlSelImgs [expr {$::tk_version >= 8.3 &&
	[info exists tablelist::$data(-treestyle)_collapsedSelImg]}]

    foreach {dummy path textIdx} [$w dump -window $fromTextIdx $toTextIdx] {
	if {[string length $path] == 0} {
	    continue
	}

	set class [winfo class $path]
	set isLabel [expr {[string compare $class "Label"] == 0}]
	set isTblWin [expr {[string compare $class "TablelistWindow"] == 0}]
	set isMessage [expr {[string compare $class "Message"] == 0}]
	if {!$isLabel && !$isTblWin && !$isMessage} {
	    continue
	}

	set name [winfo name $path]
	foreach {key col} [split [string range $name 4 end] ","] {}
	if {[info exists data($key-elide)] || [info exists data($key-hide)]} {
	    continue
	}

	set tagNames [$w tag names $textIdx]
	set selected [expr {[lsearch -exact $tagNames select] >= 0}]

	#
	# If the widget is an indentation label then conditionally remove the
	# "active" and "select" tags from its text position and the preceding
	# one, or change its image to become the "normal" or "selected" one
	#
	if {[string compare $path $w.ind_$key,$col] == 0} {
	    if {$data(protectIndents)} {
		set fromTextIdx [$w index $textIdx-1$pu]
		set toTextIdx   [$w index $textIdx+1$pu]

		$w tag remove curRow $fromTextIdx $toTextIdx
		$w tag remove active $fromTextIdx $toTextIdx

		if {$updateAll && $selected} {
		    $w tag remove select $fromTextIdx $toTextIdx
		    foreach tag [$w tag names $fromTextIdx] {
			if {[string match "*-selectbackground-*" $tag] ||
			    [string match "*-selectforeground-*" $tag]} {
			    $w tag remove $tag $fromTextIdx $toTextIdx
			}
		    }
		    set selected 0
		    foreach optTail {background foreground} {
			set opt -$optTail
			foreach level [list col row cell] \
				name  [list $col$opt $key$opt $key,$col$opt] {
			    if {[info exists data($name)]} {
				$w tag add $level$opt-$data($name) \
				       $fromTextIdx $toTextIdx
			    }
			}
		    }
		}
	    } elseif {$hasExpCollCtrlSelImgs} {
		set curImgName [$path cget -image]
		if {$selected} {
		    set newImgName [strMap {
			"SelActImg" "SelActImg" "ActImg" "SelActImg"
			"SelImg" "SelImg" "collapsedImg" "collapsedSelImg"
			"expandedImg" "expandedSelImg"
		    } $curImgName]
		} else {
		    set newImgName [strMap {"Sel" ""} $curImgName]
		}

		if {[string compare $curImgName $newImgName] != 0} {
		    set data($key,$col-indent) $newImgName
		    $path configure -image $data($key,$col-indent)
		}
	    }
	}

	if {!$updateAll} {
	    continue
	}

	#
	# Set the widget's background and foreground
	# colors to those of the containing cell
	#
	if {$data(isDisabled)} {
	    set bg $data(-background)
	    set fg $data(-disabledforeground)
	} elseif {$selected} {
	    if {[info exists data($key,$col-selectbackground)]} {
		set bg $data($key,$col-selectbackground)
	    } elseif {[info exists data($key-selectbackground)]} {
		set bg $data($key-selectbackground)
	    } elseif {[info exists data($col-selectbackground)]} {
		set bg $data($col-selectbackground)
	    } else {
		set bg $data(-selectbackground)
	    }

	    if {$isMessage || $isTblWin} {
		if {[info exists data($key,$col-selectforeground)]} {
		    set fg $data($key,$col-selectforeground)
		} elseif {[info exists data($key-selectforeground)]} {
		    set fg $data($key-selectforeground)
		} elseif {[info exists data($col-selectforeground)]} {
		    set fg $data($col-selectforeground)
		} else {
		    set fg $data(-selectforeground)
		}
	    }
	} else {
	    if {[info exists data($key,$col-background)]} {
		set bg $data($key,$col-background)
	    } elseif {[info exists data($key-background)]} {
		set bg $data($key-background)
	    } elseif {[lsearch -exact $tagNames stripe] >= 0} {
		if {[info exists data($col-stripebackground)]} {
		    set bg $data($col-stripebackground)
		} elseif {[string length $data(-stripebackground)] != 0} {
		    set bg $data(-stripebackground)
		} else {
		    set bg $data(-background)
		}
	    } else {
		if {[info exists data($col-background)]} {
		    set bg $data($col-background)
		} else {
		    set bg $data(-background)
		}
	    }

	    if {$isMessage || $isTblWin} {
		if {[info exists data($key,$col-foreground)]} {
		    set fg $data($key,$col-foreground)
		} elseif {[info exists data($key-foreground)]} {
		    set fg $data($key-foreground)
		} elseif {[lsearch -exact $tagNames stripe] >= 0} {
		    if {[info exists data($col-stripeforeground)]} {
			set fg $data($col-stripeforeground)
		    } elseif {[string length $data(-stripeforeground)] != 0} {
			set fg $data(-stripeforeground)
		    } else {
			set fg $data(-foreground)
		    }
		} else {
		    if {[info exists data($col-foreground)]} {
			set fg $data($col-foreground)
		    } else {
			set fg $data(-foreground)
		    }
		}
	    }
	}
	if {[string compare [$path cget -background] $bg] != 0} {
	    $path configure -background $bg
	}
	if {$isMessage && [string compare [$path cget -foreground] $fg] != 0} {
	    $path configure -foreground $fg
	}
	if {$isTblWin && [info exists data($key,$col-windowupdate)]} {
	    uplevel #0 $data($key,$col-windowupdate) [list \
		$win [keyToRow $win $key] $col $path.w \
		-background $bg -foreground $fg]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_updateColorsWhenIdle
#
# Arranges for the background and foreground colors of the label, frame, and
# message widgets containing the currently visible images, embedded windows,
# and multiline elements in the header text widget of the tablelist widget win
# to be updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::hdr_updateColorsWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(hdr_colorsId)]} {
	return ""
    }

    set data(hdr_colorsId) [after idle [list tablelist::hdr_updateColors $win]]
}

#------------------------------------------------------------------------------
# tablelist::hdr_updateColors
#
# Updates the background and foreground colors of the label, frame, and message
# widgets containing the currently visible images, embedded windows, and
# multiline elements in the header text widget of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::hdr_updateColors win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(hdr_colorsId)]} {
	after cancel $data(hdr_colorsId)
	unset data(hdr_colorsId)
    }

    set leftCol [colIndex $win @0,0 0 0]
    if {$leftCol < 0} {
	return ""
    }

    set w $data(hdrTxt)
    if {$data(isDisabled)} {
	$w tag add disabled 2.0 end
    }

    if {[string length $data(-colorizecommand)] == 0} {
	set hasColorizeCmd 0
    } else {
	set hasColorizeCmd 1
	set colorizeCmd $data(-colorizecommand)
    }

    variable canElide
    variable elide
    variable pu
    set rightCol [colIndex $win @$data(rightX),0 0 0]
    for {set row 0; set line 2} {$row < $data(hdr_itemCount)} \
	{incr row; incr line} {
	set key [lindex $data(hdr_keyList) $row]

	findTabs $win $w $line $leftCol $leftCol tabIdx1 tabIdx2
	for {set col $leftCol} {$col <= $rightCol} {incr col} {
	    if {$data($col-hide) && !$canElide} {
		continue
	    }

	    set textIdx2 [$w index $tabIdx2+1$pu]

	    set cellTagNames [$w tag names $tabIdx2]
	    foreach tag $cellTagNames {
		if {[string match "*-*ground-*" $tag]} {
		    $w tag remove $tag $tabIdx1 $textIdx2
		}
	    }

	    foreach opt {-background -foreground} {
		foreach level [list col row cell] \
			name  [list $col$opt $key$opt $key,$col$opt] {
		    if {[info exists data($name)]} {
			$w tag add $level$opt-$data($name) $tabIdx1 $textIdx2
		    }
		}
	    }

	    if {$hasColorizeCmd} {
		uplevel #0 $colorizeCmd [list $win $w $key $row $col \
		    $tabIdx1 $tabIdx2 0 0]
	    }

	    set tabIdx1 $textIdx2
	    set tabIdx2 [$w search $elide "\t" $tabIdx1+1$pu $line.end]
	}
    }

    foreach {dummy path textIdx} [$w dump -window 2.0 end] {
	if {[string length $path] == 0} {
	    continue
	}

	set class [winfo class $path]
	set isLabel [expr {[string compare $class "Label"] == 0}]
	set isTblWin [expr {[string compare $class "TablelistWindow"] == 0}]
	set isMessage [expr {[string compare $class "Message"] == 0}]
	if {!$isLabel && !$isTblWin && !$isMessage} {
	    continue
	}

	set name [winfo name $path]
	foreach {key col} [split [string range $name 4 end] ","] {}

	#
	# Set the widget's background and foreground
	# colors to those of the containing cell
	#
	if {$data(isDisabled)} {
	    set bg $data(-background)
	    set fg $data(-disabledforeground)
	} else {
	    if {[info exists data($key,$col-background)]} {
		set bg $data($key,$col-background)
	    } elseif {[info exists data($key-background)]} {
		set bg $data($key-background)
	    } else {
		if {[info exists data($col-background)]} {
		    set bg $data($col-background)
		} else {
		    set bg $data(-background)
		}
	    }

	    if {$isMessage || $isTblWin} {
		if {[info exists data($key,$col-foreground)]} {
		    set fg $data($key,$col-foreground)
		} elseif {[info exists data($key-foreground)]} {
		    set fg $data($key-foreground)
		} else {
		    if {[info exists data($col-foreground)]} {
			set fg $data($col-foreground)
		    } else {
			set fg $data(-foreground)
		    }
		}
	    }
	}
	if {[string compare [$path cget -background] $bg] != 0} {
	    $path configure -background $bg
	}
	if {$isMessage && [string compare [$path cget -foreground] $fg] != 0} {
	    $path configure -foreground $fg
	}
	if {$isTblWin && [info exists data($key,$col-windowupdate)]} {
	    uplevel #0 $data($key,$col-windowupdate) [list \
		$win [hdr_keyToRow $win $key] $col $path.w \
		-background $bg -foreground $fg]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::updateScrlColOffsetWhenIdle
#
# Arranges for the scrolled column offset of the tablelist widget win to be
# updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateScrlColOffsetWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(offsetId)]} {
	return ""
    }

    set data(offsetId) [after idle [list tablelist::updateScrlColOffset $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateScrlColOffset
#
# Updates the scrolled column offset of the tablelist widget win to fit into
# the allowed range.
#------------------------------------------------------------------------------
proc tablelist::updateScrlColOffset win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(offsetId)]} {
	after cancel $data(offsetId)
	unset data(offsetId)
    }

    set maxScrlColOffset [getMaxScrlColOffset $win]
    if {$data(scrlColOffset) > $maxScrlColOffset} {
	set data(scrlColOffset) $maxScrlColOffset
	hdr_adjustElidedText $win
	adjustElidedText $win
	redisplayVisibleItems $win
    }
}

#------------------------------------------------------------------------------
# tablelist::updateHScrlbarWhenIdle
#
# Arranges for the horizontal scrollbar associated with the tablelist widget
# win to be updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateHScrlbarWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(hScrlbarId)]} {
	return ""
    }

    set data(hScrlbarId) [after idle [list tablelist::updateHScrlbar $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateHScrlbar
#
# Updates the horizontal scrollbar associated with the tablelist widget win by
# invoking the command specified as the value of the -xscrollcommand option.
#------------------------------------------------------------------------------
proc tablelist::updateHScrlbar win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(hScrlbarId)]} {
	after cancel $data(hScrlbarId)
	unset data(hScrlbarId)
    }

    if {$data(-titlecolumns) > 0 &&
	[string length $data(-xscrollcommand)] != 0} {
	eval $data(-xscrollcommand) [xviewSubCmd $win {}]
    }
}

#------------------------------------------------------------------------------
# tablelist::updateVScrlbarWhenIdle
#
# Arranges for the vertical scrollbar associated with the tablelist widget win
# to be updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateVScrlbarWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(vScrlbarId)]} {
	return ""
    }

    set data(vScrlbarId) [after idle [list tablelist::updateVScrlbar $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateVScrlbar
#
# Updates the vertical scrollbar associated with the tablelist widget win by
# invoking the command specified as the value of the -yscrollcommand option.
#------------------------------------------------------------------------------
proc tablelist::updateVScrlbar win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(vScrlbarId)]} {
	after cancel $data(vScrlbarId)
	unset data(vScrlbarId)
    }

    if {[string length $data(-yscrollcommand)] != 0} {
	eval $data(-yscrollcommand) [yviewSubCmd $win {}]
    }

    if {[winfo viewable $win] && ![info exists data(colBeingResized)] &&
	![info exists data(redrawId)]} {
	set data(redrawId) [after 50 [list tablelist::forceRedraw $win]]
    }

    if {$data(gotResizeEvent)} {
	set data(gotResizeEvent) 0
    } else {
	purgeWidgets $win
    }

    event generate $win <<TablelistViewUpdated>>
}

#------------------------------------------------------------------------------
# tablelist::forceRedraw
#
# Enforces a redraw of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::forceRedraw win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(redrawId)]} {
	after cancel $data(redrawId)
	unset data(redrawId)
    }

    set w $data(body)
    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"
    $w tag add redraw $fromTextIdx $toTextIdx
    $w tag remove redraw $fromTextIdx $toTextIdx

    variable winSys
    if {[string compare $winSys "aqua"] == 0} {
	#
	# Work around some Tk bugs on Mac OS X Aqua
	#
	raise $w
	lower $w
	if {[winfo exists $data(bodyFrm)]} {
	    lower $data(bodyFrm)
	    raise $data(bodyFrm)
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::purgeWidgets
#
# Destroys those label widgets containing embedded images and those message
# widgets containing multiline elements that are outside the currently visible
# range of lines of the body of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::purgeWidgets win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"

    foreach {dummy path textIdx} [$w dump -window 1.0 end] {
	if {[string length $path] == 0} {
	    continue
	}

	set class [winfo class $path]
	if {([string compare $class "Label"] == 0 ||
	     [string compare $class "Message"] == 0) &&
	    ([$w compare $textIdx < $fromTextIdx] ||
	     [$w compare $textIdx > $toTextIdx])} {
	    $w tag add elidedWin $textIdx
	    destroy $path
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::adjustElidedText
#
# Updates the elided text ranges of the body text widget of the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::adjustElidedText win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(dispId)]} {
	return ""
    }

    #
    # Remove the "hiddenCol" tag
    #
    set w $data(body)
    $w tag remove hiddenCol 1.0 end

    #
    # Add the "hiddenCol" tag to the contents of the hidden
    # columns from the top to the bottom window line
    #
    variable canElide
    variable elide
    variable pu
    if {$canElide && $data(hiddenColCount) > 0 && $data(itemCount) > 0} {
	set topLine [expr {int([$w index @0,0])}]
	set btmLine [expr {int([$w index @0,$data(btmY)])}]
	if {$btmLine > $data(itemCount)} {
	    set btmLine $data(itemCount)
	}
	for {set line $topLine; set row [expr {$line - 1}]} \
	    {$line <= $btmLine} {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {[info exists data($key-elide)] ||
		[info exists data($key-hide)]} {
		continue
	    }

	    set textIdx1 $line.0
	    for {set col 0; set count 0} \
		{$col < $data(colCount) && $count < $data(hiddenColCount)} \
		{incr col} {
		set textIdx2 \
		    [$w search $elide "\t" $textIdx1+1$pu $line.end]+1$pu
		if {[string compare $textIdx2 "+1$pu"] == 0} {
		    break
		}
		if {$data($col-hide)} {
		    incr count
		    $w tag add hiddenCol $textIdx1 $textIdx2
		}
		set textIdx1 $textIdx2
	    }

	    #
	    # Update btmLine because it may
	    # change due to the "hiddenCol" tag
	    #
	    set btmLine [expr {int([$w index @0,$data(btmY)])}]
	    if {$btmLine > $data(itemCount)} {
		set btmLine $data(itemCount)
	    }
	}

	if {[lindex [$w yview] 1] == 1} {
	    for {set line $btmLine; set row [expr {$line - 1}]} \
		{$line >= $topLine} {set line $row; incr row -1} {
		set key [lindex $data(keyList) $row]
		if {[info exists data($key-elide)] ||
		    [info exists data($key-hide)]} {
		    continue
		}

		set textIdx1 $line.0
		for {set col 0; set count 0} \
		    {$col < $data(colCount) && $count < $data(hiddenColCount)} \
		    {incr col} {
		    set textIdx2 \
			[$w search $elide "\t" $textIdx1+1$pu $line.end]+1$pu
		    if {[string compare $textIdx2 "+1$pu"] == 0} {
			break
		    }
		    if {$data($col-hide)} {
			incr count
			$w tag add hiddenCol $textIdx1 $textIdx2
		    }
		    set textIdx1 $textIdx2
		}

		#
		# Update topLine because it may
		# change due to the "hiddenCol" tag
		#
		set topLine [expr {int([$w index @0,0])}]
	    }
	}
    }

    if {$data(-titlecolumns) == 0} {
	return ""
    }

    #
    # Remove the "elidedCol" tag
    #
    $w tag remove elidedCol 1.0 end
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set data($col-elide) 0
    }

    if {$data(scrlColOffset) == 0} {
	adjustColumns $win {} 0
	return ""
    }

    #
    # Find max. $data(scrlColOffset) non-hidden columns with indices >=
    # $data(-titlecolumns) and retain the first and last of these indices
    #
    set firstCol $data(-titlecolumns)
    while {$firstCol < $data(colCount) && $data($firstCol-hide)} {
	incr firstCol
    }
    if {$firstCol >= $data(colCount)} {
	return ""
    }
    set lastCol $firstCol
    set nonHiddenCount 1
    while {$nonHiddenCount < $data(scrlColOffset) &&
	   $lastCol < $data(colCount)} {
	incr lastCol
	if {!$data($lastCol-hide)} {
	    incr nonHiddenCount
	}
    }

    #
    # Add the "elidedCol" tag to the contents of these
    # columns from the top to the bottom window line
    #
    if {$data(itemCount) > 0} {
	set topLine [expr {int([$w index @0,0])}]
	set btmLine [expr {int([$w index @0,$data(btmY)])}]
	if {$btmLine > $data(itemCount)} {
	    set btmLine $data(itemCount)
	}
	for {set line $topLine; set row [expr {$line - 1}]} \
	    {$line <= $btmLine} {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		if {[findTabs $win $w $line $firstCol $lastCol \
		     tabIdx1 tabIdx2]} {
		    $w tag add elidedCol $tabIdx1 $tabIdx2+1$pu
		}
	    }

	    #
	    # Update btmLine because it may change due to the "elidedCol" tag
	    #
	    set btmLine [expr {int([$w index @0,$data(btmY)])}]
	    if {$btmLine > $data(itemCount)} {
		set btmLine $data(itemCount)
	    }
	}

	if {[lindex [$w yview] 1] == 1} {
	    for {set line $btmLine; set row [expr {$line - 1}]} \
		{$line >= $topLine} {set line $row; incr row -1} {
		set key [lindex $data(keyList) $row]
		if {![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    if {[findTabs $win $w $line $firstCol $lastCol \
			 tabIdx1 tabIdx2]} {
			$w tag add elidedCol $tabIdx1 $tabIdx2+1$pu
		    }
		}

		#
		# Update topLine because it may
		# change due to the "elidedCol" tag
		#
		set topLine [expr {int([$w index @0,0])}]
	    }
	}
    }

    #
    # Adjust the columns
    #
    for {set col $firstCol} {$col <= $lastCol} {incr col} {
	set data($col-elide) 1
    }
    adjustColumns $win {} 0
}

#------------------------------------------------------------------------------
# tablelist::hdr_adjustElidedText
#
# Updates the elided text ranges of the header text widget of the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::hdr_adjustElidedText win {
    #
    # Remove the "hiddenCol" tag
    #
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxt)
    $w tag remove hiddenCol 1.0 end

    #
    # Add the "hiddenCol" tag to the contents of the hidden columns
    #
    variable canElide
    variable elide
    variable pu
    if {$canElide && $data(hiddenColCount) > 0} {
	for {set row 0; set line 2} {$row < $data(hdr_itemCount)} \
	    {incr row; incr line} {
	    set textIdx1 $line.0
	    for {set col 0; set count 0} \
		{$col < $data(colCount) && $count < $data(hiddenColCount)} \
		{incr col} {
		set textIdx2 \
		    [$w search $elide "\t" $textIdx1+1$pu $line.end]+1$pu
		if {[string compare $textIdx2 "+1$pu"] == 0} {
		    break
		}
		if {$data($col-hide)} {
		    incr count
		    $w tag add hiddenCol $textIdx1 $textIdx2
		}
		set textIdx1 $textIdx2
	    }
	}
    }

    if {$data(-titlecolumns) == 0} {
	return ""
    }

    #
    # Remove the "elidedCol" tag
    #
    $w tag remove elidedCol 1.0 end
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set data($col-elide) 0
    }

    if {$data(scrlColOffset) == 0} {
	adjustColumns $win {} 0
	return ""
    }

    #
    # Find max. $data(scrlColOffset) non-hidden columns with indices >=
    # $data(-titlecolumns) and retain the first and last of these indices
    #
    set firstCol $data(-titlecolumns)
    while {$firstCol < $data(colCount) && $data($firstCol-hide)} {
	incr firstCol
    }
    if {$firstCol >= $data(colCount)} {
	return ""
    }
    set lastCol $firstCol
    set nonHiddenCount 1
    while {$nonHiddenCount < $data(scrlColOffset) &&
	   $lastCol < $data(colCount)} {
	incr lastCol
	if {!$data($lastCol-hide)} {
	    incr nonHiddenCount
	}
    }

    #
    # Add the "elidedCol" tag to the contents of these columns
    #
    for {set row 0; set line 2} {$row < $data(hdr_itemCount)} \
	{incr row; incr line} {
	if {[findTabs $win $w $line $firstCol $lastCol \
	     tabIdx1 tabIdx2]} {
	    $w tag add elidedCol $tabIdx1 $tabIdx2+1$pu
	}
    }

    #
    # Adjust the columns
    #
    for {set col $firstCol} {$col <= $lastCol} {incr col} {
	set data($col-elide) 1
    }
    adjustColumns $win {} 0
}

#------------------------------------------------------------------------------
# tablelist::redisplayWhenIdle
#
# Arranges for the items of the tablelist widget win to be redisplayed at idle
# time.
#------------------------------------------------------------------------------
proc tablelist::redisplayWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(redispId)] || $data(itemCount) == 0} {
	return ""
    }

    set data(redispId) [after idle [list tablelist::redisplay $win]]

    #
    # Cancel the execution of all delayed redisplayCol commands
    #
    foreach name [array names data *-redispId] {
	after cancel $data($name)
	unset data($name)
    }
}

#------------------------------------------------------------------------------
# tablelist::redisplay
#
# Redisplays the items of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::redisplay {win {getSelCells 1} {selCells {}}} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(redispId)]} {
	after cancel $data(redispId)
	unset data(redispId)
    }

    set snipStr $data(-snipstring)
    variable canElide
    variable snipSides

    set w $data(hdrTxt)
    set padY [expr {[$w cget -spacing1] == 0}]
    set hdr_newItemList {}
    set row 0
    set line 2
    foreach item $data(hdr_itemList) {
	#
	# Empty the line, clip the elements if necessary,
	# and insert them with the corresponding tags
	#
	$w delete $line.0 $line.end
	set keyIdx [expr {[llength $item] - 1}]
	set key [lindex $item end]
	set hasRowFont [info exists data($key-font)]
	set newItem {}
	set col 0
	foreach fmtCmdFlag $data(fmtCmdFlagList) \
		colFont $data(colFontList) \
		colTags $data(colTagsList) \
		{pixels alignment} $data(colList) {
	    if {$col < $keyIdx} {
		set text [lindex $item $col]
	    } else {
		set text ""
	    }
	    lappend newItem $text

	    if {$data($col-hide) && !$canElide} {
		incr col
		continue
	    }

	    if {$fmtCmdFlag} {
		set text [formatElem $win $key $row $col $text]
	    }
	    if {[string match "*\t*" $text]} {
		set text [mapTabs $text]
	    }

	    #
	    # Build the list of tags to be applied to the cell
	    #
	    if {$hasRowFont} {
		set cellFont $data($key-font)
	    } else {
		set cellFont $colFont
	    }
	    set cellTags $colTags
	    if {[info exists data($key,$col-font)]} {
		set cellFont $data($key,$col-font)
		lappend cellTags cell-font-$data($key,$col-font)
	    }

	    #
	    # Insert the text and the label or window
	    # (if any) into the header text widget
	    #
	    appendComplexElem $win $key $row $col $text $pixels \
			      $alignment $snipStr $cellFont $cellTags $line

	    incr col
	}

	if {[info exists data($key-font)]} {
	    $w tag add row-font-$data($key-font) $line.0 $line.end
	}

	lappend newItem $key
	lappend hdr_newItemList $newItem

	incr row
	incr line
    }

    set data(hdr_itemList) $hdr_newItemList

    #
    # Save the indices of the selected cells
    #
    if {$getSelCells} {
	set selCells [curCellSelection $win]
    }

    #
    # Save some data of the edit window if present
    #
    if {[set editCol $data(editCol)] >= 0} {
	set editRow $data(editRow)
	saveEditData $win
    }

    variable pu
    set rowTagRefCount $data(rowTagRefCount)
    set cellTagRefCount $data(cellTagRefCount)
    set isSimple [expr {$data(imgCount) == 0 && $data(winCount) == 0 &&
			$data(indentCount) == 0}]
    set w $data(body)
    set padY [expr {[$w cget -spacing1] == 0}]
    set newItemList {}
    set row 0
    set line 1
    foreach item $data(itemList) {
	#
	# Empty the line, clip the elements if necessary,
	# and insert them with the corresponding tags
	#
	$w delete $line.0 $line.end
	set keyIdx [expr {[llength $item] - 1}]
	set key [lindex $item end]
	if {$rowTagRefCount == 0} {
	    set hasRowFont 0
	} else {
	    set hasRowFont [info exists data($key-font)]
	}
	set newItem {}
	set col 0
	if {$isSimple} {
	    set insertArgs {}
	    set multilineData {}
	    foreach fmtCmdFlag $data(fmtCmdFlagList) \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$col < $keyIdx} {
		    set text [lindex $item $col]
		} else {
		    set text ""
		}
		lappend newItem $text

		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		if {[string match "*\t*" $text]} {
		    set text [mapTabs $text]
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$data($col-maxPixels) > 0} {
			if {$data($col-reqPixels) > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $cellFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    set snipSide \
			$snipSides($alignment,$data($col-changesnipside))
		    if {$multiline} {
			set list [split $text "\n"]
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $cellFont \
				  $pixels $snipSide $snipStr]
		    } elseif {$data(-displayondemand)} {
			set text ""
		    } else {
			set text [strRange $win $text $cellFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		if {$multiline} {
		    lappend insertArgs "\t\t" $cellTags
		    lappend multilineData $col $text $cellFont $pixels \
					  $alignment
		} else {
		    lappend insertArgs "\t$text\t" $cellTags
		}

		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    if {[llength $insertArgs] != 0} {
		eval [list $w insert $line.0] $insertArgs
	    }

	    #
	    # Embed the message widgets displaying multiline elements
	    #
	    foreach {col text font pixels alignment} $multilineData {
		if {[findTabs $win $w $line $col $col tabIdx1 tabIdx2]} {
		    set msgScript [list ::tablelist::displayText $win $key \
				   $col $text $font $pixels $alignment]
		    $w window create $tabIdx2 \
			      -align top -pady $padY -create $msgScript
		    $w tag add elidedWin $tabIdx2
		}
	    }

	} else {
	    foreach fmtCmdFlag $data(fmtCmdFlagList) \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$col < $keyIdx} {
		    set text [lindex $item $col]
		} else {
		    set text ""
		}
		lappend newItem $text

		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		if {[string match "*\t*" $text]} {
		    set text [mapTabs $text]
		}

		#
		# Build the list of tags to be applied to the cell
		#
		if {$hasRowFont} {
		    set cellFont $data($key-font)
		} else {
		    set cellFont $colFont
		}
		set cellTags $colTags
		if {$cellTagRefCount != 0} {
		    if {[info exists data($key,$col-font)]} {
			set cellFont $data($key,$col-font)
			lappend cellTags cell-font-$data($key,$col-font)
		    }
		}

		#
		# Insert the text and the label or window
		# (if any) into the body text widget
		#
		appendComplexElem $win $key $row $col $text $pixels \
				  $alignment $snipStr $cellFont $cellTags $line

		incr col
	    }
	}

	if {$rowTagRefCount != 0} {
	    if {[info exists data($key-font)]} {
		$w tag add row-font-$data($key-font) $line.0 $line.end
	    }
	}

	if {[info exists data($key-elide)]} {
	    $w tag add elidedRow $line.0 $line.end+1$pu
	}
	if {[info exists data($key-hide)]} {
	    $w tag add hiddenRow $line.0 $line.end+1$pu
	}

	lappend newItem $key
	lappend newItemList $newItem

	set row $line
	incr line
    }

    set data(itemList) $newItemList

    #
    # Select the cells that were selected before
    #
    foreach cellIdx $selCells {
	scan $cellIdx "%d,%d" row col
	if {$col < $data(colCount)} {
	    cellSelection $win set $row $col $row $col
	}
    }

    #
    # Conditionally move the "active" tag to the active line or cell
    #
    if {$data(ownsFocus)} {
	moveActiveTag $win
    }

    #
    # Adjust the elided text and restore the stripes in the body text widget
    #
    hdr_adjustElidedText $win
    adjustElidedText $win
    redisplayVisibleItems $win
    makeStripes $win

    #
    # Restore the edit window if it was present before
    #
    if {$editCol >= 0} {
	doEditCell $win $editRow $editCol 1
    }
}

#------------------------------------------------------------------------------
# tablelist::redisplayVisibleItems
#
# Redisplays the visible items of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::redisplayVisibleItems win {
    upvar ::tablelist::ns${win}::data data
    if {!$data(-displayondemand) || $data(itemCount) == 0} {
	return ""
    }

    set leftCol [colIndex $win @0,0 0 0]
    if {$leftCol < 0} {
	return ""
    }

    variable canElide
    variable elide
    variable snipSides
    variable pu

    displayItems $win
    set w $data(body)

    set topTextIdx [$w index @0,0]
    set btmTextIdx [$w index @0,$data(btmY)]
    set fromTextIdx "$topTextIdx linestart"
    set toTextIdx   "$btmTextIdx lineend"
    $w tag remove elidedWin $fromTextIdx $toTextIdx

    set rightCol [colIndex $win @$data(rightX),0 0 0]
    set topLine [expr {int($topTextIdx)}]
    set btmLine [expr {int($btmTextIdx)}]
    if {$btmLine > $data(itemCount)} {
	set btmLine $data(itemCount)
    }
    set snipStr $data(-snipstring)

    for {set line $topLine; set row [expr {$line - 1}]} \
	{$line <= $btmLine} {set row $line; incr line} {
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	if {[info exists data($key-elide)] || [info exists data($key-hide)]} {
	    continue
	}

	#
	# Format the item
	#
	set dispItem [lrange $item 0 $data(lastCol)]
	if {$data(hasFmtCmds)} {
	    set dispItem [formatItem $win $key $row $dispItem]
	}
	if {[string match "*\t*" $dispItem]} {
	    set dispItem [mapTabs $dispItem]
	}

	findTabs $win $w $line $leftCol $leftCol tabIdx1 tabIdx2
	set textIdx1 [$w index $tabIdx1+1$pu]
	for {set col $leftCol} {$col <= $rightCol} {incr col} {
	    if {$data($col-hide) && !$canElide} {
		continue
	    }

	    #
	    # Nothing to do if the text is empty or is already displayed,
	    # or interactive editing for this cell is in progress
	    #
	    set text [lindex $dispItem $col]
	    if {[string length $text] == 0 ||
		[string length [$w get $textIdx1 $tabIdx2]] != 0 ||
		($row == $data(editRow) && $col == $data(editCol))} {
		set textIdx1 [$w index $tabIdx2+2$pu]
		set tabIdx2 [$w search $elide "\t" $textIdx1 $line.end]
		continue
	    }

	    set pixels [lindex $data(colList) [expr {2*$col}]]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$data($col-maxPixels) > 0} {
		    if {$data($col-reqPixels) > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
	    }
	    if {$pixels != 0} {
		incr pixels $data($col-delta)
	    }

	    #
	    # Nothing to do if the cell has an (indentation)
	    # image or window, or contains multiline text
	    #
	    set aux [getAuxData $win $key $col auxType auxWidth $pixels]
	    set indent [getIndentData $win $key $col indentWidth]
	    set multiline [string match "*\n*" $text]
	    if {$auxWidth != 0 || $indentWidth != 0 || $multiline} {
		set textIdx1 [$w index $tabIdx2+2$pu]
		set tabIdx2 [$w search $elide "\t" $textIdx1 $line.end]
		continue
	    }

	    #
	    # Adjust the cell text
	    #
	    set maxTextWidth $pixels
	    if {[info exists data($key,$col-font)]} {
		set cellFont $data($key,$col-font)
	    } elseif {[info exists data($key-font)]} {
		set cellFont $data($key-font)
	    } else {
		set cellFont [lindex $data(colFontList) $col]
	    }
	    if {$pixels != 0} {
		set maxTextWidth \
		    [getMaxTextWidth $pixels $auxWidth $indentWidth]

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $cellFont -displayof $win $text] >
			$maxTextWidth} {
			#
			# The element is displayed as multiline text
			#
			set textIdx1 [$w index $tabIdx2+2$pu]
			set tabIdx2 [$w search $elide "\t" $textIdx1 $line.end]
			continue
		    }
		}
	    }
	    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	    set snipSide $snipSides($alignment,$data($col-changesnipside))
	    adjustElem $win text auxWidth indentWidth $cellFont $pixels \
		       $snipSide $snipStr

	    #
	    # Update the text widget's content between the two tabs
	    #
	    $w mark set tabMark2 [$w index $tabIdx2]
	    updateCell $w $textIdx1 $tabIdx2 $text $aux $auxType $auxWidth \
		       $indent $indentWidth $alignment ""

	    set textIdx1 [$w index tabMark2+2$pu]
	    set tabIdx2 [$w search $elide "\t" $textIdx1 $line.end]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::redisplayColWhenIdle
#
# Arranges for the elements of the col'th column of the tablelist widget win to
# be redisplayed at idle time.
#------------------------------------------------------------------------------
proc tablelist::redisplayColWhenIdle {win col} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data($col-redispId)] || [info exists data(redispId)]} {
	return ""
    }

    set data($col-redispId) \
	[after idle [list tablelist::redisplayCol $win $col 0 last]]
}

#------------------------------------------------------------------------------
# tablelist::redisplayCol
#
# Redisplays the elements of the col'th column of the tablelist widget win, in
# the range specified by first and last.  Prior to that, it redisplays the
# elements of the specified column in the header text widget.
#------------------------------------------------------------------------------
proc tablelist::redisplayCol {win col first last} {
    upvar ::tablelist::ns${win}::data data
    set allRows [expr {$first == 0 && [string compare $last "last"] == 0}]
    if {$allRows && [info exists data($col-redispId)]} {
	after cancel $data($col-redispId)
	unset data($col-redispId)
    }

    if {$col > $data(lastCol) || $data($col-hide)} {
	return ""
    }

    displayItems $win
    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
    set colFont [lindex $data(colFontList) $col]
    set snipStr $data(-snipstring)

    set pixels [lindex $data(colList) [expr {2*$col}]]
    if {$pixels == 0} {				;# convention: dynamic width
	if {$data($col-maxPixels) > 0} {
	    if {$data($col-reqPixels) > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
	    }
	}
    }
    if {$pixels != 0} {
	incr pixels $data($col-delta)
    }
    set alignment [lindex $data(colList) [expr {2*$col + 1}]]
    variable snipSides
    set snipSide $snipSides($alignment,$data($col-changesnipside))
    variable pu

    set w $data(hdrTxt)
    for {set row 0; set line 2} {$row < $data(hdr_itemCount)} \
	{incr row; incr line} {
	set item [lindex $data(hdr_itemList) $row]
	set key [lindex $item end]

	#
	# Adjust the cell text and the image or window width
	#
	set text [lindex $item $col]
	if {$fmtCmdFlag} {
	    set text [formatElem $win $key $row $col $text]
	}
	if {[string match "*\t*" $text]} {
	    set text [mapTabs $text]
	}
	set multiline [string match "*\n*" $text]
	set aux [getAuxData $win $key $col auxType auxWidth $pixels]
	set indentWidth 0
	set maxTextWidth $pixels
	if {[info exists data($key,$col-font)]} {
	    set cellFont $data($key,$col-font)
	} elseif {[info exists data($key-font)]} {
	    set cellFont $data($key-font)
	} else {
	    set cellFont $colFont
	}
	if {$pixels != 0} {
	    set maxTextWidth [getMaxTextWidth $pixels $auxWidth 0]

	    if {$data($col-wrap) && !$multiline} {
		if {[font measure $cellFont -displayof $win $text] >
		    $maxTextWidth} {
		    set multiline 1
		}
	    }
	}
	if {$multiline} {
	    set list [split $text "\n"]
	    set snipSide2 $snipSide
	    if {$data($col-wrap)} {
		set snipSide2 ""
	    }
	    adjustMlElem $win list auxWidth indentWidth $cellFont \
			 $pixels $snipSide2 $snipStr
	    set msgScript [list ::tablelist::displayText $win $key $col \
			   [join $list "\n"] $cellFont $maxTextWidth $alignment]
	} else {
	    adjustElem $win text auxWidth indentWidth $cellFont \
		       $pixels $snipSide $snipStr
	}

	#
	# Update the text widget's content between the two tabs
	#
	if {[findTabs $win $w $line $col $col tabIdx1 tabIdx2]} {
	    if {$auxType > 1 && $auxWidth > 0 && ![winfo exists $aux]} {
		#
		# Create a frame and evaluate the script that
		# creates a child window within the frame
		#
		tk::frame $aux -borderwidth 0 -class TablelistWindow \
			       -container 0 -height $data($key,$col-reqHeight) \
			       -highlightthickness 0 -relief flat \
			       -takefocus 0 -width $auxWidth
		catch {$aux configure -padx 0 -pady 0}
		bindtags $aux [linsert [bindtags $aux] 1 \
			       $data(bodyTag) TablelistBody]
		uplevel #0 $data($key,$col-window) [list $win $row $col $aux.w]
	    }

	    if {$multiline} {
		updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
			     $auxType $auxWidth "" 0 $alignment \
			     [getVAlignment $win $key $col]
	    } else {
		updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
			   $auxType $auxWidth "" 0 $alignment \
			   [getVAlignment $win $key $col]
	    }
	}
    }

    if {$first < 0} {
	return ""
    }
    if {[string compare $last "last"] == 0} {
	set last $data(lastRow)
    }

    set w $data(body)
    for {set row $first; set line [expr {$first + 1}]} {$row <= $last} \
	{set row $line; incr line} {
	if {$row == $data(editRow) && $col == $data(editCol)} {
	    continue
	}

	set item [lindex $data(itemList) $row]
	set key [lindex $item end]
	if {!$allRows &&
	    ([info exists data($key-elide)] ||
	     [info exists data($key-hide)])} {
	    continue
	}

	#
	# Adjust the cell text and the image or window width
	#
	set text [lindex $item $col]
	if {$fmtCmdFlag} {
	    set text [formatElem $win $key $row $col $text]
	}
	if {[string match "*\t*" $text]} {
	    set text [mapTabs $text]
	}
	set multiline [string match "*\n*" $text]
	set aux [getAuxData $win $key $col auxType auxWidth $pixels]
	set indent [getIndentData $win $key $col indentWidth]
	set maxTextWidth $pixels
	if {[info exists data($key,$col-font)]} {
	    set cellFont $data($key,$col-font)
	} elseif {[info exists data($key-font)]} {
	    set cellFont $data($key-font)
	} else {
	    set cellFont $colFont
	}
	if {$pixels != 0} {
	    set maxTextWidth [getMaxTextWidth $pixels $auxWidth $indentWidth]

	    if {$data($col-wrap) && !$multiline} {
		if {[font measure $cellFont -displayof $win $text] >
		    $maxTextWidth} {
		    set multiline 1
		}
	    }
	}
	if {$multiline} {
	    set list [split $text "\n"]
	    set snipSide2 $snipSide
	    if {$data($col-wrap)} {
		set snipSide2 ""
	    }
	    adjustMlElem $win list auxWidth indentWidth $cellFont \
			 $pixels $snipSide2 $snipStr
	    set msgScript [list ::tablelist::displayText $win $key $col \
			   [join $list "\n"] $cellFont $maxTextWidth $alignment]
	} else {
	    adjustElem $win text auxWidth indentWidth $cellFont \
		       $pixels $snipSide $snipStr
	}

	#
	# Update the text widget's content between the two tabs
	#
	if {[findTabs $win $w $line $col $col tabIdx1 tabIdx2]} {
	    if {$auxType > 1 && $auxWidth > 0 && ![winfo exists $aux]} {
		#
		# Create a frame and evaluate the script that
		# creates a child window within the frame
		#
		tk::frame $aux -borderwidth 0 -class TablelistWindow \
			       -container 0 -height $data($key,$col-reqHeight) \
			       -highlightthickness 0 -relief flat \
			       -takefocus 0 -width $auxWidth
		catch {$aux configure -padx 0 -pady 0}
		bindtags $aux [linsert [bindtags $aux] 1 \
			       $data(bodyTag) TablelistBody]
		uplevel #0 $data($key,$col-window) [list $win $row $col $aux.w]
	    }

	    if {$multiline} {
		updateMlCell $w $tabIdx1+1$pu $tabIdx2 $msgScript $aux \
			     $auxType $auxWidth $indent $indentWidth \
			     $alignment [getVAlignment $win $key $col]
	    } else {
		updateCell $w $tabIdx1+1$pu $tabIdx2 $text $aux \
			   $auxType $auxWidth $indent $indentWidth \
			   $alignment [getVAlignment $win $key $col]
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::makeStripesWhenIdle
#
# Arranges for the stripes in the body of the tablelist widget win to be
# redrawn at idle time.
#------------------------------------------------------------------------------
proc tablelist::makeStripesWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stripesId)] || $data(itemCount) == 0} {
	return ""
    }

    set data(stripesId) [after idle [list tablelist::makeStripes $win]]
}

#------------------------------------------------------------------------------
# tablelist::makeStripes
#
# Redraws the stripes in the body of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::makeStripes win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(stripesId)]} {
	after cancel $data(stripesId)
	unset data(stripesId)
    }

    if {[info exists data(dispId)]} {
	return ""
    }

    set w $data(body)
    $w tag remove stripe 1.0 end
    if {[string length $data(-stripebackground)] != 0 ||
	[string length $data(-stripeforeground)] != 0} {
	set count 0
	set inStripe 0
	for {set row 0; set line 1} {$row < $data(itemCount)} \
	    {set row $line; incr line} {
	    set key [lindex $data(keyList) $row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		if {$inStripe} {
		    $w tag add stripe $line.0 $line.end
		}

		if {[incr count] == $data(-stripeheight)} {
		    set count 0
		    set inStripe [expr {!$inStripe}]
		}
	    }
	}
    }

    updateColors $win
}

#------------------------------------------------------------------------------
# tablelist::showLineNumbersWhenIdle
#
# Arranges for the line numbers in the tablelist widget win to be redisplayed
# at idle time.
#------------------------------------------------------------------------------
proc tablelist::showLineNumbersWhenIdle win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(lineNumsId)] || $data(itemCount) == 0} {
	return ""
    }

    set data(lineNumsId) [after idle [list tablelist::showLineNumbers $win]]
}

#------------------------------------------------------------------------------
# tablelist::showLineNumbers
#
# Redisplays the line numbers (if any) in the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::showLineNumbers win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(lineNumsId)]} {
	after cancel $data(lineNumsId)
	unset data(lineNumsId)
    }

    #
    # Update the item list
    #
    set colIdxList {}
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {!$data($col-showlinenumbers)} {
	    continue
	}

	lappend colIdxList $col

	set newItemList {}
	set line 1
	foreach item $data(itemList) {
	    set item [lreplace $item $col $col $line]
	    lappend newItemList $item
	    set key [lindex $item end]
	    if {![info exists data($key-hide)]} {
		incr line
	    }
	}
	set data(itemList) $newItemList

	redisplayColWhenIdle $win $col
    }

    if {[llength $colIdxList] == 0} {
	return ""
    }

    #
    # Update the list variable if present, and adjust the columns
    #
    condUpdateListVar $win
    adjustColumns $win $colIdxList 1
    return ""
}

#------------------------------------------------------------------------------
# tablelist::updateViewWhenIdle
#
# Arranges for the visible part of the body text widget of the tablelist widget
# win to be updated at idle time.
#------------------------------------------------------------------------------
proc tablelist::updateViewWhenIdle {win {reschedule 0}} {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(viewId)]} {
	if {$reschedule} {
	    after cancel $data(viewId)
	} else {
	    return ""
	}
    }

    set data(viewId) [after idle [list tablelist::updateView $win]]
}

#------------------------------------------------------------------------------
# tablelist::updateView
#
# Updates the visible part of the body text widget of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::updateView win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(viewId)]} {
	after cancel $data(viewId)
	unset data(viewId)

	hdr_adjustElidedText $win
	hdr_updateColors $win
	adjustHeaderHeight $win
    }

    adjustElidedText $win
    redisplayVisibleItems $win
    updateColors $win
    adjustSeps $win
    updateVScrlbar $win
}

#------------------------------------------------------------------------------
# tablelist::destroyWidgets
#
# Destroys a list of widgets embedded into the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::destroyWidgets win {
    upvar ::tablelist::ns${win}::data data
    set destroyId [lindex $data(destroyIdList) 0]

    eval destroy $data(widgets-$destroyId)

    set data(destroyIdList) [lrange $data(destroyIdList) 1 end]
    unset data(widgets-$destroyId)
}

#------------------------------------------------------------------------------
# tablelist::synchronize
#
# This procedure is invoked either as an idle callback after the list variable
# associated with the tablelist widget win was written, or directly, upon
# execution of some widget commands.  It makes sure that the content of the
# widget is synchronized with the value of the list variable.
#------------------------------------------------------------------------------
proc tablelist::synchronize win {
    #
    # Nothing to do if the list variable was not written
    #
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(syncId)]} {
	return ""
    }

    #
    # Here we are in the case that the procedure was scheduled for
    # execution at idle time.  However, it might have been invoked
    # directly, before the idle time occured; in this case we should
    # cancel the execution of the previously scheduled idle callback.
    #
    after cancel $data(syncId)	;# no harm if data(syncId) is no longer valid
    unset data(syncId)

    upvar #0 $data(-listvariable) var
    set newCount [llength $var]
    if {$newCount < $data(itemCount)} {
	#
	# Delete the items with indices >= newCount from the widget
	#
	set updateCount $newCount
	deleteRows $win $newCount $data(lastRow) 0
    } elseif {$newCount > $data(itemCount)} {
	#
	# Insert the items of var with indices
	# >= data(itemCount) into the widget
	#
	set updateCount $data(itemCount)
	insertRows $win $data(itemCount) [lrange $var $data(itemCount) end] 0 \
		   root $data(itemCount)
    } else {
	set updateCount $newCount
    }

    #
    # Update the first updateCount items of the internal list
    #
    set itemsChanged 0
    for {set row 0} {$row < $updateCount} {incr row} {
	set oldItem [lindex $data(itemList) $row]
	set newItem [adjustItem [lindex $var $row] $data(colCount)]
	lappend newItem [lindex $oldItem end]

	if {[string compare $oldItem $newItem] != 0} {
	    set data(itemList) [lreplace $data(itemList) $row $row $newItem]
	    set itemsChanged 1
	}
    }

    #
    # If necessary, adjust the columns and make sure
    # that the items will be redisplayed at idle time
    #
    if {$itemsChanged} {
	adjustColumns $win allCols 1
	redisplayWhenIdle $win
	showLineNumbersWhenIdle $win
	updateViewWhenIdle $win
    }
}

#------------------------------------------------------------------------------
# tablelist::getSublabels
#
# Returns the list of the existing sublabels $w-il and $w-tl associated with
# the label widget w.
#------------------------------------------------------------------------------
proc tablelist::getSublabels w {
    set lst {}
    foreach lbl [list $w-il $w-tl] {
	if {[winfo exists $lbl]} {
	    lappend lst $lbl
	}
    }

    return $lst
}

#------------------------------------------------------------------------------
# tablelist::parseLabelPath
#
# Extracts the path name of the tablelist widget as well as the column number
# from the path name w of a header label.
#------------------------------------------------------------------------------
proc tablelist::parseLabelPath {w winName colName} {
    if {![winfo exists $w]} {
	return 0
    }

    upvar $winName win $colName col
    return [regexp {^(\..+)\.hdr\.t\.f\.l([0-9]+)$} $w dummy win col]
}

#------------------------------------------------------------------------------
# tablelist::configLabel
#
# This procedure configures the label widget w according to the options and
# their values given in args.  It is needed for label widgets with sublabels.
#------------------------------------------------------------------------------
proc tablelist::configLabel {w args} {
    foreach {opt val} $args {
	switch -- $opt {
	    -active {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    $w instate !selected {
			set state [expr {$val ? "active" : "!active"}]
			$w state $state
			variable themeDefaults
			if {$val} {
			    set bg $themeDefaults(-labelactiveBg)
			} else {
			    set bg $themeDefaults(-labelbackground)
			}
			foreach l [getSublabels $w] {
			    $l configure -background $bg
			}
		    }
		} else {
		    set state [expr {$val ? "active" : "normal"}]
		    catch {
			$w configure -state $state
			foreach l [getSublabels $w] {
			    $l configure -state $state
			}
		    }
		}

		parseLabelPath $w win col
		upvar ::tablelist::ns${win}::data data
		if {[lsearch -exact $data(arrowColList) $col] >= 0} {
		    configCanvas $win $col
		}
	    }

	    -activebackground -
	    -activeforeground -
	    -disabledforeground -
	    -cursor {
		$w configure $opt $val
		foreach l [getSublabels $w] {
		    $l configure $opt $val
		}
	    }

	    -background -
	    -font {
		if {[string compare [winfo class $w] "TLabel"] == 0 &&
		    [string length $val] == 0} {
		    variable themeDefaults
		    set val $themeDefaults(-label[string range $opt 1 end])
		}
		$w configure $opt $val
		foreach l [getSublabels $w] {
		    $l configure $opt $val
		}
	    }

	    -foreground {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    variable themeDefaults
		    if {[string compare [winfo rgb $w $val] [winfo rgb $w \
			 $themeDefaults(-labelforeground)]] == 0} {
			set val ""    ;# for automatic adaptation to the states
		    }
		    $w instate !disabled {
			$w configure $opt $val
		    }
		} else {
		    $w configure $opt $val
		    foreach l [getSublabels $w] {
			$l configure $opt $val
		    }
		}
	    }

	    -padx {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set padding [$w cget -padding]
		    lset padding 0 $val
		    lset padding 2 $val
		    $w configure -padding $padding
		} else {
		    $w configure $opt $val
		}
	    }

	    -pady {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set val [winfo pixels $w $val]
		    set padding [$w cget -padding]
		    lset padding 1 $val
		    lset padding 3 $val
		    $w configure -padding $padding
		} else {
		    $w configure $opt $val
		}
	    }

	    -pressed {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set state [expr {$val ? "pressed" : "!pressed"}]
		    $w state $state
		    variable themeDefaults
		    if {$val} {
			if {[$w instate selected]} {
			    set bg $themeDefaults(-labelselectedpressedBg)
			} else {
			    set bg $themeDefaults(-labelpressedBg)
			}
		    } else {
			if {[$w instate selected]} {
			    set bg $themeDefaults(-labelselectedBg)
			} elseif {[$w instate active]} {
			    set bg $themeDefaults(-labelactiveBg)
			} else {
			    set bg $themeDefaults(-labelbackground)
			}
		    }
		    foreach l [getSublabels $w] {
			$l configure -background $bg
		    }

		    parseLabelPath $w win col
		    upvar ::tablelist::ns${win}::data data
		    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
			configCanvas $win $col
		    }
		}
	    }

	    -selected {
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    set state [expr {$val ? "selected" : "!selected"}]
		    $w state $state
		    variable themeDefaults
		    if {$val} {
			if {[$w instate pressed]} {
			    set bg $themeDefaults(-labelselectedpressedBg)
			} else {
			    set bg $themeDefaults(-labelselectedBg)
			}
		    } else {
			if {[$w instate pressed]} {
			    set bg $themeDefaults(-labelpressedBg)
			} else {
			    set bg $themeDefaults(-labelbackground)
			}
		    }
		    foreach l [getSublabels $w] {
			$l configure -background $bg
		    }

		    parseLabelPath $w win col
		    upvar ::tablelist::ns${win}::data data
		    if {[lsearch -exact $data(arrowColList) $col] >= 0} {
			configCanvas $win $col
		    }
		}
	    }

	    -state {
		$w configure $opt $val
		if {[string compare [winfo class $w] "TLabel"] == 0} {
		    variable themeDefaults
		    if {[string compare $val "disabled"] == 0} {
			#
			# Set the label's foreground color to the theme-
			# specific one (needed for current tile versions)
			#
			$w configure -foreground ""

			set bg $themeDefaults(-labeldisabledBg)
		    } else {
			#
			# Restore the label's foreground color
			# (needed for current tile versions)
			#
			if {[parseLabelPath $w win col]} {
			    upvar ::tablelist::ns${win}::data data
			    if {[info exists data($col-labelforeground)]} {
				set fg $data($col-labelforeground)
			    } else {
				set fg $data(-labelforeground)
			    }
			    configLabel $w -foreground $fg
			}

			set bg $themeDefaults(-labelbackground)
		    }
		    foreach l [getSublabels $w] {
			$l configure -background $bg
		    }
		} else {
		    foreach l [getSublabels $w] {
			$l configure $opt $val
		    }
		}
	    }

	    default {
		if {[string compare $val [$w cget $opt]] != 0} {
		    $w configure $opt $val
		}
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createArrows
#
# Creates two arrows in the canvas w.
#------------------------------------------------------------------------------
proc tablelist::createArrows {w width height relief} {
    if {$height < 6} {
	set wHeight 6
	variable centerArrows
	set y [expr {$centerArrows ? 0 : 1}]
    } else {
	set wHeight $height
	set y 0
    }

    $w configure -width $width -height $wHeight

    #
    # Delete any existing arrow image items from
    # the canvas and the corresponding images
    #
    set imgNames [image names]
    foreach shape {triangleUp darkLineUp lightLineUp
		   triangleDn darkLineDn lightLineDn} {
	$w delete $shape
	if {[lsearch -exact $imgNames $shape$w] >= 0} {
	    image delete $shape$w
	}
    }

    #
    # Create the arrow images and canvas image items
    # corresponding to the procedure's arguments
    #
    $relief${width}x${height}Arrows $w
    set imgNames [image names]
    foreach shape {triangleUp darkLineUp lightLineUp
		   triangleDn darkLineDn lightLineDn} {
	if {[lsearch -exact $imgNames $shape$w] >= 0} {
	    $w create image 0 $y -anchor nw -image $shape$w -tags $shape
	}
    }

    #
    # Create the sort rank image item
    #
    $w delete sortRank
    set x [expr {$width + 2}]
    set y [expr {$wHeight - 6}]
    $w create image $x $y -anchor nw -tags sortRank
}

#------------------------------------------------------------------------------
# tablelist::configCanvas
#
# Sets the background color of the canvas displaying an up- or down-arrow for
# the given column, and fills the two arrows contained in the canvas.
#------------------------------------------------------------------------------
proc tablelist::configCanvas {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrmLbl)$col

    if {[string compare [winfo class $w] "TLabel"] == 0} {
	variable themeDefaults
	set labelBg $themeDefaults(-labelbackground)
	set fg [$w cget -foreground]
	set labelFg $fg
	if {[string length $fg] == 0} {
	    set labelFg $themeDefaults(-labelforeground)
	}

	if {[$w instate disabled]} {
	    set labelBg $themeDefaults(-labeldisabledBg)
	    set labelFg $themeDefaults(-labeldisabledFg)
	} elseif {[$win instate background]} {
	    set labelBg $themeDefaults(-labeldeactivatedBg)
	} else {
	    foreach state {active pressed selected} {
		$w instate $state {
		    set labelBg $themeDefaults(-label${state}Bg)
		    if {[string length $fg] == 0} {
			set labelFg $themeDefaults(-label${state}Fg)
		    }
		}
	    }
	    $w instate {selected pressed} {
		set labelBg $themeDefaults(-labelselectedpressedBg)
		if {[string length $fg] == 0} {
		    set labelFg $themeDefaults(-labelselectedpressedFg)
		}
	    }
	}
    } else {
	set labelBg [$w cget -background]
	set labelFg [$w cget -foreground]

	catch {
	    set state [$w cget -state]
	    if {[string compare $state "disabled"] == 0} {
		set labelFg [$w cget -disabledforeground]
	    } elseif {[string compare $state "active"] == 0} {
		variable winSys
		if {!([string compare $winSys "classic"] == 0 ||
		      [string compare $winSys "aqua"] == 0) ||
		    $::tk_version > 8.4} {
		    set labelBg [$w cget -activebackground]
		    set labelFg [$w cget -activeforeground]
		}
	    }
	}
    }

    set canvas $data(hdrTxtFrmCanv)$col
    $canvas configure -background $labelBg
    sortRank$data($col-sortRank)$win configure -foreground $labelFg

    if {$data(isDisabled)} {
	fillArrows $canvas $data(-arrowdisabledcolor) $data(-arrowstyle)
    } else {
	fillArrows $canvas $data(-arrowcolor) $data(-arrowstyle)
    }
}

#------------------------------------------------------------------------------
# tablelist::fillArrows
#
# Fills the two arrows contained in the canvas w with the given color, or with
# the background color of the canvas if color is an empty string.  Also fills
# the arrow's borders (if any) with the corresponding 3-D shadow colors.
#------------------------------------------------------------------------------
proc tablelist::fillArrows {w color arrowStyle} {
    set bgColor [$w cget -background]
    if {[string length $color] == 0} {
	set color $bgColor
    }

    getShadows $w $color darkColor lightColor

    foreach dir {Up Dn} {
	if {[string compare [image type triangle$dir$w] "bitmap"] == 0} {
	    triangle$dir$w configure -foreground $color -background $bgColor
	}

	if {[string match "sunken*" $arrowStyle]} {
	    darkLine$dir$w  configure -foreground $darkColor
	    lightLine$dir$w configure -foreground $lightColor
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::getShadows
#
# Computes the shadow colors for a 3-D border from a given (background) color.
# This is the Tcl-counterpart of the function TkpGetShadows() in the Tk
# distribution file unix/tkUnix3d.c.
#------------------------------------------------------------------------------
proc tablelist::getShadows {w color darkColorName lightColorName} {
    upvar $darkColorName darkColor $lightColorName lightColor

    set rgb [winfo rgb $w $color]
    foreach {r g b} $rgb {}
    set maxIntens [lindex [winfo rgb $w white] 0]

    #
    # Compute the dark shadow color
    #
    if {[string compare $::tk_patchLevel "8.3.1"] >= 0 &&
	$r*0.5*$r + $g*1.0*$g + $b*0.28*$b < $maxIntens*0.05*$maxIntens} {
	#
	# The background is already very dark: make the dark
	# color a little lighter than the background by increasing
	# each color component 1/4th of the way to $maxIntens
	#
	foreach comp $rgb {
	    lappend darkRGB [expr {($maxIntens + 3*$comp)/4}]
	}
    } else {
	#
	# Compute the dark color by cutting 40% from
	# each of the background color components.
	#
	foreach comp $rgb {
	    lappend darkRGB [expr {60*$comp/100}]
	}
    }
    set darkColor [eval format "#%04x%04x%04x" $darkRGB]

    #
    # Compute the light shadow color
    #
    if {[string compare $::tk_patchLevel "8.3.1"] >= 0 &&
	$g > $maxIntens*0.95} {
	#
	# The background is already very bright: make the
	# light color a little darker than the background
	# by reducing each color component by 10%
	#
	foreach comp $rgb {
	    lappend lightRGB [expr {90*$comp/100}]
	}
    } else {
	#
	# Compute the light color by boosting each background
	# color component by 40% or half-way to white, whichever
	# is greater (the first approach works better for
	# unsaturated colors, the second for saturated ones)
	#
	foreach comp $rgb {
	    set comp1 [expr {140*$comp/100}]
	    if {$comp1 > $maxIntens} {
		set comp1 $maxIntens
	    }
	    set comp2 [expr {($maxIntens + $comp)/2}]
	    lappend lightRGB [expr {($comp1 > $comp2) ? $comp1 : $comp2}]
	}
    }
    set lightColor [eval format "#%04x%04x%04x" $lightRGB]
}

#------------------------------------------------------------------------------
# tablelist::raiseArrow
#
# Raises one of the two arrows contained in the canvas associated with the
# given column of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::raiseArrow {win col} {
    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxtFrmCanv)$col
    variable directions
    set dir $directions($data(-incrarrowtype),$data($col-sortOrder))

    if {[string match "photo*" $data(-arrowstyle)]} {
	$w itemconfigure triangle$dir -state normal
	set dir [expr {([string compare $dir "Up"] == 0) ? "Dn" : "Up"}]
	$w itemconfigure triangle$dir -state hidden
    } else {
	$w raise triangle$dir
	$w raise darkLine$dir
	$w raise lightLine$dir
    }
}

#------------------------------------------------------------------------------
# tablelist::isHdrTxtFrXPosVisible
#
# Checks whether the given x position in the header text widget component of
# the tablelist widget win is visible.
#------------------------------------------------------------------------------
proc tablelist::isHdrTxtFrXPosVisible {win x} {
    upvar ::tablelist::ns${win}::data data
    foreach {fraction1 fraction2} [$data(hdrTxt) xview] {}
    return [expr {$x >= $fraction1 * $data(hdrWidth) &&
		  $x <  $fraction2 * $data(hdrWidth)}]
}

#------------------------------------------------------------------------------
# tablelist::getScrlContentWidth
#
# Returns the total width of the non-hidden scrollable columns of the tablelist
# widget win, in the specified range.
#------------------------------------------------------------------------------
proc tablelist::getScrlContentWidth {win scrlColOffset lastCol} {
    upvar ::tablelist::ns${win}::data data
    set scrlContentWidth 0
    set nonHiddenCount 0
    for {set col $data(-titlecolumns)} {$col <= $lastCol} {incr col} {
	if {!$data($col-hide) && [incr nonHiddenCount] > $scrlColOffset} {
	    incr scrlContentWidth [colWidth $win $col -total]
	}
    }

    return $scrlContentWidth
}

#------------------------------------------------------------------------------
# tablelist::getScrlWindowWidth
#
# Returns the number of pixels obtained by subtracting the widths of the non-
# hidden title columns from the width of the header frame of the tablelist
# widget win.
#------------------------------------------------------------------------------
proc tablelist::getScrlWindowWidth win {
    upvar ::tablelist::ns${win}::data data
    set scrlWindowWidth [winfo width $data(hdr)]
    for {set col 0} {$col < $data(-titlecolumns) && $col < $data(colCount)} \
	{incr col} {
	if {!$data($col-hide)} {
	    incr scrlWindowWidth -[colWidth $win $col -total]
	}
    }

    return $scrlWindowWidth
}

#------------------------------------------------------------------------------
# tablelist::getMaxScrlColOffset
#
# Returns the max. scrolled column offset of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::getMaxScrlColOffset win {
    #
    # Get the number of non-hidden scrollable columns
    #
    upvar ::tablelist::ns${win}::data data
    set maxScrlColOffset 0
    for {set col $data(-titlecolumns)} {$col < $data(colCount)} {incr col} {
	if {!$data($col-hide)} {
	    incr maxScrlColOffset
	}
    }

    #
    # Decrement maxScrlColOffset while the total width of the
    # non-hidden scrollable columns starting with this offset
    # is less than the width of the window's scrollable part
    #
    set scrlWindowWidth [getScrlWindowWidth $win]
    if {$scrlWindowWidth > 0} {
	while {$maxScrlColOffset > 0} {
	    incr maxScrlColOffset -1
	    set scrlContentWidth \
		[getScrlContentWidth $win $maxScrlColOffset $data(lastCol)]
	    if {$scrlContentWidth == $scrlWindowWidth} {
		break
	    } elseif {$scrlContentWidth > $scrlWindowWidth} {
		incr maxScrlColOffset
		break
	    }
	}
    }

    return $maxScrlColOffset
}

#------------------------------------------------------------------------------
# tablelist::changeScrlColOffset
#
# Changes the scrolled column offset of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::changeScrlColOffset {win scrlColOffset} {
    #
    # Make sure the offset is non-negative and no
    # greater than the max. scrolled column offset
    #
    if {$scrlColOffset < 0} {
	set scrlColOffset 0
    } else {
	set maxScrlColOffset [getMaxScrlColOffset $win]
	if {$scrlColOffset > $maxScrlColOffset} {
	    set scrlColOffset $maxScrlColOffset
	}
    }

    #
    # Update data(scrlColOffset) and adjust the
    # elided text in the tablelist's body if necessary
    #
    upvar ::tablelist::ns${win}::data data
    if {$scrlColOffset != $data(scrlColOffset)} {
	set data(scrlColOffset) $scrlColOffset
	hdr_adjustElidedText $win
	adjustElidedText $win
	redisplayVisibleItems $win
    }
}

#------------------------------------------------------------------------------
# tablelist::scrlXOffsetToColOffset
#
# Returns the scrolled column offset of the tablelist widget win, corresponding
# to the desired x offset.
#------------------------------------------------------------------------------
proc tablelist::scrlXOffsetToColOffset {win scrlXOffset} {
    upvar ::tablelist::ns${win}::data data
    set scrlColOffset 0
    set scrlContentWidth 0
    for {set col $data(-titlecolumns)} {$col < $data(colCount)} {incr col} {
	if {$data($col-hide)} {
	    continue
	}

	incr scrlContentWidth [colWidth $win $col -total]
	if {$scrlContentWidth > $scrlXOffset} {
	    break
	} else {
	    incr scrlColOffset
	}
    }

    return $scrlColOffset
}

#------------------------------------------------------------------------------
# tablelist::scrlColOffsetToXOffset
#
# Returns the x offset corresponding to the specified scrolled column offset of
# the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::scrlColOffsetToXOffset {win scrlColOffset} {
    upvar ::tablelist::ns${win}::data data
    set scrlXOffset 0
    set nonHiddenCount 0
    for {set col $data(-titlecolumns)} {$col < $data(colCount)} {incr col} {
	if {$data($col-hide)} {
	    continue
	}

	if {[incr nonHiddenCount] > $scrlColOffset} {
	    break
	} else {
	    incr scrlXOffset [colWidth $win $col -total]
	}
    }

    return $scrlXOffset
}

#------------------------------------------------------------------------------
# tablelist::getVertComplTopRow
#
# Returns the row number of the topmost vertically complete item visible in the
# tablelist window win.
#------------------------------------------------------------------------------
proc tablelist::getVertComplTopRow win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)

    set topTextIdx [$w index @0,0]
    set topRow [expr {int($topTextIdx) - 1}]

    foreach {x y width height baselinePos} [$w dlineinfo $topTextIdx] {}
    if {$y < 0} {
	incr topRow		;# top row incomplete in vertical direction
    }

    return $topRow
}

#------------------------------------------------------------------------------
# tablelist::getVertComplBtmRow
#
# Returns the row number of the bottommost vertically complete item visible in
# the tablelist window win.
#------------------------------------------------------------------------------
proc tablelist::getVertComplBtmRow win {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)

    set btmTextIdx [$w index @0,$data(btmY)]
    set btmRow [expr {int($btmTextIdx) - 1}]
    if {$btmRow > $data(lastRow)} {
	set btmRow $data(lastRow)
    }

    foreach {x y width height baselinePos} [$w dlineinfo $btmTextIdx] {}
    set y2 [expr {$y + $height}]
    if {[$w compare [$w index @0,$y] == [$w index @0,$y2]]} {
	incr btmRow -1		;# btm row incomplete in vertical direction
    }

    return $btmRow
}

#------------------------------------------------------------------------------
# tablelist::getViewableRowCount
#
# Returns the number of viewable rows of the tablelist widget win in the
# specified range.
#------------------------------------------------------------------------------
proc tablelist::getViewableRowCount {win first last} {
    upvar ::tablelist::ns${win}::data data
    if {$data(nonViewableRowCount) == 0} {
	#
	# Speed optimization
	#
	set count [expr {$last - $first + 1}]
	if {$count < 0} {
	    return 0
	} else {
	    return $count
	}
    } elseif {$first == 0 && $last == $data(lastRow)} {
	#
	# Speed optimization
	#
	return [expr {$data(itemCount) - $data(nonViewableRowCount)}]
    } else {
	set count 0
	for {set row $first} {$row <= $last} {incr row} {
	    set key [lindex $data(keyList) $row]
	    if {![info exists data($key-elide)] &&
		![info exists data($key-hide)]} {
		incr count
	    }
	}
	return $count
    }
}

#------------------------------------------------------------------------------
# tablelist::viewableRowOffsetToRowIndex
#
# Returns the row index corresponding to the given viewable row offset in the
# tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::viewableRowOffsetToRowIndex {win offset} {
    upvar ::tablelist::ns${win}::data data
    if {$data(nonViewableRowCount) == 0} {
	return $offset
    } else {
	#
	# Rebuild the list data(viewableRowList) of the row
	# indices indicating the viewable rows if needed
	#
	if {[lindex $data(viewableRowList) 0] == -1} {
	    set data(viewableRowList) {}
	    for {set row 0} {$row < $data(itemCount)} {incr row} {
		set key [lindex $data(keyList) $row]
		if {![info exists data($key-elide)] &&
		    ![info exists data($key-hide)]} {
		    lappend data(viewableRowList) $row
		}
	    }
	}

	if {$offset >= [llength $data(viewableRowList)]} {
	    return $data(itemCount)			;# this is out of range
	} else {
	    if {$offset < 0} {
		set offset 0
	    }
	    return [lindex $data(viewableRowList) $offset]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createFrameWithCheckbutton
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget win, along with a checkbutton child.
#------------------------------------------------------------------------------
proc tablelist::createFrameWithCheckbutton {cmd win row col w} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::checkStates checkStates
    set item [lindex $data(itemList) $row]
    set key [lindex $item end]
    set checkStates($key,$col) [lindex $item $col]

    frame $w
    makeCheckbutton $w.ckbtn
    $w.ckbtn configure -variable ::tablelist::ns${win}::checkStates($key,$col)

    if {[string length $cmd] != 0} {
	$w.ckbtn configure -command [format {
	    after idle [list %s %s %d %d]
	} $cmd $win $row $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_createFrameWithCheckbutton
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget win, along with a checkbutton child.
#------------------------------------------------------------------------------
proc tablelist::hdr_createFrameWithCheckbutton {cmd win row col w} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::checkStates checkStates
    set item [lindex $data(hdr_itemList) $row]
    set key [lindex $item end]
    set checkStates($key,$col) [lindex $item $col]

    frame $w
    makeCheckbutton $w.ckbtn
    $w.ckbtn configure -variable ::tablelist::ns${win}::checkStates($key,$col)

    if {[string length $cmd] != 0} {
	$w.ckbtn configure -command [format {
	    after idle [list %s %s %d %d]
	} $cmd $win $row $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::makeCheckbutton
#
# Creates a checkbutton widget of the given path name and manages it in its
# parent, which is supposed to be a frame widget.
#------------------------------------------------------------------------------
proc tablelist::makeCheckbutton w {
    checkbutton $w -activebackground white -background white \
	-highlightthickness 0 -padx 0 -pady 0 -selectcolor white -takefocus 0

    set frm [winfo parent $w]
    variable winSys
    switch $winSys {
	x11 {
	    if {$::tk_version > 8.4} {
		$frm configure -width 11 -height 11
		$w configure -borderwidth 0 -font "Helvetica -12"
		place $w -x -5 -y -3
	    } else {
		variable checkedImg
		variable uncheckedImg
		if {![info exists checkedImg]} {
		    createCheckbuttonImgs
		}

		$w configure -borderwidth 2 -indicatoron 0 \
		    -image $uncheckedImg -selectimage $checkedImg
		if {$::tk_version == 8.4} {
		    $w configure -offrelief sunken ;# -offrelief added in Tk8.4
		}
		pack $w
	    }
	}

	win32 {
	    $frm configure -width 13 -height 13
	    $w configure -borderwidth 0 -font {"MS Sans Serif" 8}
	    switch [winfo reqheight $w {
		17	{ set y -1 }
		20	{ set y -3 }
		25	{ set y -5 }
		30 -
		31	{ set y -8 }
		default	{ set y -1 }
	    }
	    place $w -x -1 -y $y
	}

	classic {
	    $frm configure -width 16 -height 14
	    $w configure -borderwidth 0 -font "system"
	    place $w -x 0 -y -1
	}

	aqua {
	    $w configure -borderwidth 0 -font "system"
	    if {$::tk_version > 8.4} {
		$frm configure -width 12 -height 12
		place $w -x -1 -y -3
	    } else {
		$frm configure -width 14 -height 14
		place $w -x -4 -y -3
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::createFrameWithTileCheckbutton
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget win, along with a tile checkbutton child.
#------------------------------------------------------------------------------
proc tablelist::createFrameWithTileCheckbutton {cmd win row col w} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::checkStates checkStates
    set item [lindex $data(itemList) $row]
    set key [lindex $item end]
    set checkStates($key,$col) [lindex $item $col]

    frame $w
    makeTileCheckbutton $w.ckbtn
    $w.ckbtn configure -variable ::tablelist::ns${win}::checkStates($key,$col)

    if {[string length $cmd] != 0} {
	$w.ckbtn configure -command [format {
	    after idle [list %s %s %d %d]
	} $cmd $win $row $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_createFrameWithTileCheckbutton
#
# Creates a frame widget w to be embedded into the specified cell of the
# tablelist widget win, along with a tile checkbutton child.
#------------------------------------------------------------------------------
proc tablelist::hdr_createFrameWithTileCheckbutton {cmd win row col w} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::checkStates checkStates
    set item [lindex $data(hdr_itemList) $row]
    set key [lindex $item end]
    set checkStates($key,$col) [lindex $item $col]

    frame $w
    makeTileCheckbutton $w.ckbtn
    $w.ckbtn configure -variable ::tablelist::ns${win}::checkStates($key,$col)

    if {[string length $cmd] != 0} {
	$w.ckbtn configure -command [format {
	    after idle [list %s %s %d %d]
	} $cmd $win $row $col]
    }
}

#------------------------------------------------------------------------------
# tablelist::makeTileCheckbutton
#
# Creates a tile checkbutton widget of the given path name and manages it in
# its parent, which is supposed to be a frame widget.
#------------------------------------------------------------------------------
proc tablelist::makeTileCheckbutton w {
    if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
	package require tile 0.6
    }
    createTileAliases 

    #
    # Define the checkbutton layout; use catch to suppress
    # the error message in case the layout already exists
    #
    set currentTheme [getCurrentTheme]
    if {[string compare $currentTheme "aqua"] == 0} {
	catch {style layout Tablelist.TCheckbutton { Checkbutton.button }}
    } else {
	catch {style layout Tablelist.TCheckbutton { Checkbutton.indicator }}
	styleConfig Tablelist.TCheckbutton -indicatormargin 0
    }

    ttk::checkbutton $w -style Tablelist.TCheckbutton -takefocus 0

    #
    # Adjust the dimensions of the tile checkbutton's parent
    # and manage the checkbutton, depending on the current theme
    #
    set frm [winfo parent $w]
    switch -- $currentTheme {
	aqua {
	    $frm configure -width 16 -height 16
	    place $w -x -3 -y -3
	}

	Aquativo -
	aquativo -
	Arc {
	    $frm configure -width 14 -height 14
	    place $w -x -1 -y -1
	}

	blue -
	winxpblue {
	    set height [winfo reqheight $w]
	    $frm configure -width $height -height $height
	    place $w -x 0
	}

	clam {
	    $frm configure -width 11 -height 11
	    place $w -x 0
	}

	classic -
	default {
	    styleConfig Tablelist.TCheckbutton -background white
	    pack $w
	}

	clearlooks {
	    $frm configure -width 13 -height 13
	    place $w -x -2 -y -2
	}

	keramik -
	keramik_alt {
	    $frm configure -width 16 -height 16
	    place $w -x -1 -y -1
	}

	plastik {
	    $frm configure -width 15 -height 15
	    place $w -x -2 -y 1
	}

	sriv -
	srivlg {
	    $frm configure -width 15 -height 17
	    place $w -x -1
	}

	tileqt {
	    switch -- [string tolower [tileqt_currentThemeName]] {
		acqua {
		    $frm configure -width 17 -height 18
		    place $w -x -1 -y -2
		}
		cde -
		cleanlooks -
		motif {
		    $frm configure -width 13 -height 13
		    if {[info exists ::env(KDE_SESSION_VERSION)] &&
			[string length $::env(KDE_SESSION_VERSION)] != 0} {
			place $w -x -2
		    } else {
			place $w -x 0
		    }
		}
		gtk+ {
		    $frm configure -width 15 -height 15
		    place $w -x -1 -y -1
		}
		kde_xp {
		    $frm configure -width 13 -height 13
		    place $w -x 0
		}
		keramik -
		thinkeramik {
		    $frm configure -width 16 -height 16
		    place $w -x 0
		}
		oxygen {
		    $frm configure -width 17 -height 17
		    place $w -x -2 -y -1
		}
		default {
		    set height [winfo reqheight $w]
		    $frm configure -width $height -height $height
		    place $w -x 0
		}
	    }
	}

	vista {
	    set height [winfo reqheight $w]
	    $frm configure -width $height -height $height
	    place $w -x 0
	}

	winnative -
	xpnative {
	    set height [winfo reqheight $w]
	    $frm configure -width $height -height $height
	    if {[info exists tile::version]} {
		place $w -x -2
	    } else {
		place $w -x 0
	    }
	}

	default {
	    pack $w
	}
    }
}

Added libs/tablelist6.0/scripts/tablelistWidget.tcl.

























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
#==============================================================================
# Contains the implementation of the tablelist widget.
#
# Structure of the module:
#   - Namespace initialization
#   - Private procedure creating the default bindings
#   - Public procedure creating a new tablelist widget
#   - Private procedures implementing the tablelist widget command
#   - Private callback procedures
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

#
# Namespace initialization
# ========================
#

namespace eval tablelist {
    #
    # Get the current windowing system ("x11", "win32", "classic", or "aqua")
    #
    variable winSys
    if {[catch {tk windowingsystem} winSys] != 0} {
	switch $::tcl_platform(platform) {
	    unix	{ set winSys x11 }
	    windows	{ set winSys win32 }
	    macintosh	{ set winSys classic }
	}
    }

    #
    # Create aliases for a few tile commands if not yet present
    #
    proc createTileAliases {} {
	if {[string length [interp alias {} ::tablelist::style]] != 0} {
	    return ""
	}

	if {[llength [info commands ::ttk::style]] == 0} {
	    interp alias {} ::tablelist::style      {} ::style
	    if {[string compare $::tile::version "0.7"] >= 0} {
		interp alias {} ::tablelist::styleConfig {} ::style configure
	    } else {
		interp alias {} ::tablelist::styleConfig {} ::style default
	    }
	    interp alias {} ::tablelist::getThemes  {} ::tile::availableThemes
	    interp alias {} ::tablelist::setTheme   {} ::tile::setTheme

	    interp alias {} ::tablelist::tileqt_kdeStyleChangeNotification \
			 {} ::tile::theme::tileqt::kdeStyleChangeNotification
	    interp alias {} ::tablelist::tileqt_currentThemeName \
			 {} ::tile::theme::tileqt::currentThemeName
	    interp alias {} ::tablelist::tileqt_currentThemeColour \
			 {} ::tile::theme::tileqt::currentThemeColour
	} else {
	    interp alias {} ::tablelist::style	      {} ::ttk::style
	    interp alias {} ::tablelist::styleConfig  {} ::ttk::style configure
	    interp alias {} ::tablelist::getThemes    {} ::ttk::themes
	    interp alias {} ::tablelist::setTheme     {} ::ttk::setTheme

	    interp alias {} ::tablelist::tileqt_kdeStyleChangeNotification \
			 {} ::ttk::theme::tileqt::kdeStyleChangeNotification
	    interp alias {} ::tablelist::tileqt_currentThemeName \
			 {} ::ttk::theme::tileqt::currentThemeName
	    interp alias {} ::tablelist::tileqt_currentThemeColour \
			 {} ::ttk::theme::tileqt::currentThemeColour
	}
    }
    if {$usingTile} {
	createTileAliases 
    }

    variable pngSupported [expr {($::tk_version >= 8.6 &&
	![regexp {^8\.6(a[1-3]|b1)$} $::tk_patchLevel]) ||
	($::tk_version >= 8.5 && [catch {package require img::png}] == 0)}]

    variable specialAquaHandling [expr {$usingTile && ($::tk_version >= 8.6 ||
	[regexp {^8\.5\.(9|[1-9][0-9])$} $::tk_patchLevel]) &&
	[lsearch -exact [winfo server .] "AppKit"] >= 0}]

    #
    # The array configSpecs is used to handle configuration options.  The
    # names of its elements are the configuration options for the Tablelist
    # class.  The value of an array element is either an alias name or a list
    # containing the database name and class as well as an indicator specifying
    # the widget(s) to which the option applies: c stands for all children
    # (text widgets and labels), b for the body text widget, l for the labels,
    # f for the frame, and w for the widget itself.
    #
    #	Command-Line Name	 {Database Name		  Database Class      W}
    #	------------------------------------------------------------------------
    #
    variable configSpecs
    array set configSpecs {
	-acceptchildcommand	 {acceptChildCommand	  AcceptChildCommand  w}
	-acceptdropcommand	 {acceptDropCommand	  AcceptDropCommand   w}
	-activestyle		 {activeStyle		  ActiveStyle	      w}
	-arrowcolor		 {arrowColor		  ArrowColor	      w}
	-arrowdisabledcolor	 {arrowDisabledColor	  ArrowDisabledColor  w}
	-arrowstyle		 {arrowStyle		  ArrowStyle	      w}
	-autofinishediting	 {autoFinishEditing	  AutoFinishEditing   w}
	-autoscan		 {autoScan		  AutoScan	      w}
	-background		 {background		  Background	      b}
	-bg			 -background
	-borderwidth		 {borderWidth		  BorderWidth	      f}
	-bd			 -borderwidth
	-collapsecommand	 {collapseCommand	  CollapseCommand     w}
	-colorizecommand	 {colorizeCommand	  ColorizeCommand     w}
	-columns		 {columns		  Columns	      w}
	-columntitles		 {columnTitles		  ColumnTitles	      w}
	-cursor			 {cursor		  Cursor	      c}
	-customdragsource	 {customDragSource	  CustomDragSource    w}
	-disabledforeground	 {disabledForeground	  DisabledForeground  w}
	-displayondemand	 {displayOnDemand	  DisplayOnDemand     w}
	-editendcommand		 {editEndCommand	  EditEndCommand      w}
	-editselectedonly	 {editSelectedOnly	  EditSelectedOnly    w}
	-editstartcommand	 {editStartCommand	  EditStartCommand    w}
	-expandcommand		 {expandCommand		  ExpandCommand       w}
	-exportselection	 {exportSelection	  ExportSelection     w}
	-font			 {font			  Font		      b}
	-forceeditendcommand	 {forceEditEndCommand	  ForceEditEndCommand w}
	-foreground		 {foreground		  Foreground	      b}
	-fg			 -foreground
	-fullseparators		 {fullSeparators	  FullSeparators      w}
	-height			 {height		  Height	      w}
	-highlightbackground	 {highlightBackground	  HighlightBackground f}
	-highlightcolor		 {highlightColor	  HighlightColor      f}
	-highlightthickness	 {highlightThickness	  HighlightThickness  f}
	-incrarrowtype		 {incrArrowType		  IncrArrowType	      w}
	-instanttoggle		 {instantToggle		  InstantToggle	      w}
	-labelactivebackground	 {labelActiveBackground	  Foreground	      l}
	-labelactiveforeground	 {labelActiveForeground	  Background	      l}
	-labelbackground	 {labelBackground	  Background	      l}
	-labelbg		 -labelbackground
	-labelborderwidth	 {labelBorderWidth	  BorderWidth	      l}
	-labelbd		 -labelborderwidth
	-labelcommand		 {labelCommand		  LabelCommand	      w}
	-labelcommand2		 {labelCommand2		  LabelCommand2	      w}
	-labeldisabledforeground {labelDisabledForeground DisabledForeground  l}
	-labelfont		 {labelFont		  Font		      l}
	-labelforeground	 {labelForeground	  Foreground	      l}
	-labelfg		 -labelforeground
	-labelheight		 {labelHeight		  Height	      l}
	-labelpady		 {labelPadY		  Pad		      l}
	-labelrelief		 {labelRelief		  Relief	      l}
	-listvariable		 {listVariable		  Variable	      w}
	-movablecolumns	 	 {movableColumns	  MovableColumns      w}
	-movablerows		 {movableRows		  MovableRows	      w}
	-movecolumncursor	 {moveColumnCursor	  MoveColumnCursor    w}
	-movecursor		 {moveCursor		  MoveCursor	      w}
	-populatecommand	 {populateCommand	  PopulateCommand     w}
	-protecttitlecolumns	 {protectTitleColumns	  ProtectTitleColumns w}
	-relief			 {relief		  Relief	      f}
	-resizablecolumns	 {resizableColumns	  ResizableColumns    w}
	-resizecursor		 {resizeCursor		  ResizeCursor	      w}
	-selectbackground	 {selectBackground	  Foreground	      w}
	-selectborderwidth	 {selectBorderWidth	  BorderWidth	      w}
	-selectforeground	 {selectForeground	  Background	      w}
	-selectmode		 {selectMode		  SelectMode	      w}
	-selecttype		 {selectType		  SelectType	      w}
	-setfocus		 {setFocus		  SetFocus	      w}
	-setgrid		 {setGrid		  SetGrid	      w}
	-showarrow		 {showArrow		  ShowArrow	      w}
	-showeditcursor		 {showEditCursor	  ShowEditCursor      w}
	-showhorizseparator	 {showHorizSeparator	  ShowHorizSeparator  w}
	-showlabels		 {showLabels		  ShowLabels	      w}
	-showseparators		 {showSeparators	  ShowSeparators      w}
	-snipstring		 {snipString		  SnipString	      w}
	-sortcommand		 {sortCommand		  SortCommand	      w}
	-spacing		 {spacing		  Spacing	      w}
	-state			 {state			  State		      w}
	-stretch		 {stretch		  Stretch	      w}
	-stripebackground	 {stripeBackground	  Background	      w}
	-stripebg		 -stripebackground
	-stripeforeground	 {stripeForeground	  Foreground	      w}
	-stripefg		 -stripeforeground
	-stripeheight		 {stripeHeight		  StripeHeight	      w}
	-takefocus		 {takeFocus		  TakeFocus	      f}
	-targetcolor		 {targetColor		  TargetColor	      w}
	-tight			 {tight			  Tight		      w}
	-titlecolumns		 {titleColumns	  	  TitleColumns	      w}
	-tooltipaddcommand	 {tooltipAddCommand	  TooltipAddCommand   w}
	-tooltipdelcommand	 {tooltipDelCommand	  TooltipDelCommand   w}
	-treecolumn		 {treeColumn		  TreeColumn	      w}
	-treestyle		 {treeStyle		  TreeStyle	      w}
	-width			 {width			  Width		      w}
	-xscrollcommand		 {xScrollCommand	  ScrollCommand	      w}
	-yscrollcommand		 {yScrollCommand	  ScrollCommand	      w}
    }

    #
    # Extend the elements of the array configSpecs
    #
    extendConfigSpecs 

    variable configOpts [lsort [array names configSpecs]]

    #
    # The array colConfigSpecs is used to handle column configuration options.
    # The names of its elements are the column configuration options for the
    # Tablelist widget class.  The value of an array element is either an alias
    # name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	    }
    #	---------------------------------------------------------------------
    #
    variable colConfigSpecs
    array set colConfigSpecs {
	-align			{align			Align		    }
	-background		{background		Background	    }
	-bg			-background
	-changesnipside		{changeSnipSide		ChangeSnipSide	    }
	-changetitlesnipside	{changeTitleSnipSide	ChangeTitleSnipSide }
	-editable		{editable		Editable	    }
	-editwindow		{editWindow		EditWindow	    }
	-font			{font			Font		    }
	-foreground		{foreground		Foreground	    }
	-fg			-foreground
	-formatcommand		{formatCommand		FormatCommand	    }
	-hide			{hide			Hide		    }
	-labelalign		{labelAlign		Align		    }
	-labelbackground	{labelBackground	Background	    }
	-labelbg		-labelbackground
	-labelborderwidth	{labelBorderWidth	BorderWidth	    }
	-labelbd		-labelborderwidth
	-labelcommand		{labelCommand		LabelCommand	    }
	-labelcommand2		{labelCommand2		LabelCommand2	    }
	-labelfont		{labelFont		Font		    }
	-labelforeground	{labelForeground	Foreground	    }
	-labelfg		-labelforeground
	-labelheight		{labelHeight		Height		    }
	-labelimage		{labelImage		Image		    }
	-labelpady		{labelPadY		Pad		    }
	-labelrelief		{labelRelief		Relief		    }
	-maxwidth		{maxWidth		MaxWidth	    }
	-name			{name			Name		    }
	-resizable		{resizable		Resizable	    }
	-selectbackground	{selectBackground	Foreground	    }
	-selectforeground	{selectForeground	Background	    }
	-showarrow		{showArrow		ShowArrow	    }
	-showlinenumbers	{showLineNumbers	ShowLineNumbers	    }
	-sortcommand		{sortCommand		SortCommand	    }
	-sortmode		{sortMode		SortMode	    }
	-stretchable		{stretchable		Stretchable	    }
	-stripebackground	{stripeBackground	Background	    }
	-stripeforeground	{stripeForeground	Foreground	    }
	-text			{text			Text		    }
	-title			{title			Title		    }
	-valign			{valign			Valign		    }
	-width			{width			Width		    }
	-wrap			{wrap			Wrap		    }
    }

    #
    # Extend some elements of the array colConfigSpecs
    #
    lappend colConfigSpecs(-align)			- left
    lappend colConfigSpecs(-changesnipside)		- 0
    lappend colConfigSpecs(-changetitlesnipside)	- 0
    lappend colConfigSpecs(-editable)			- 0
    lappend colConfigSpecs(-editwindow)			- entry
    lappend colConfigSpecs(-hide)			- 0
    lappend colConfigSpecs(-maxwidth)			- 0
    lappend colConfigSpecs(-resizable)			- 1
    lappend colConfigSpecs(-showarrow)			- 1
    lappend colConfigSpecs(-showlinenumbers)		- 0
    lappend colConfigSpecs(-sortmode)			- ascii
    lappend colConfigSpecs(-stretchable)		- 0
    lappend colConfigSpecs(-valign)			- center
    lappend colConfigSpecs(-width)			- 0
    lappend colConfigSpecs(-wrap)			- 0

    if {$usingTile} {
	unset colConfigSpecs(-labelbackground)
	unset colConfigSpecs(-labelbg)
	unset colConfigSpecs(-labelheight)
    }

    #
    # The array rowConfigSpecs is used to handle row configuration options.
    # The names of its elements are the row configuration options for the
    # Tablelist widget class.  The value of an array element is either an alias
    # name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	}
    #	-----------------------------------------------------------------
    #
    variable rowConfigSpecs
    array set rowConfigSpecs {
	-background		{background		Background	}
	-bg			-background
	-font			{font			Font		}
	-foreground		{foreground		Foreground	}
	-fg			-foreground
	-hide			{hide			Hide		}
	-name			{name			Name		}
	-selectable		{selectable		Selectable	}
	-selectbackground	{selectBackground	Foreground	}
	-selectforeground	{selectForeground	Background	}
	-text			{text			Text		}
    }

    #
    # Check whether the -elide text widget tag option is available
    #
    variable canElide
    variable elide
    if {$::tk_version >= 8.3} {
	set canElide 1
	set elide -elide
    } else {
	set canElide 0
	set elide --
    }

    #
    # Extend some elements of the array rowConfigSpecs
    #
    if {$canElide} {
	lappend rowConfigSpecs(-hide)	- 0
    } else {
	unset rowConfigSpecs(-hide)
    }
    lappend rowConfigSpecs(-selectable)	- 1

    #
    # The array hdr_rowConfigSpecs is used to handle header row configuration
    # options.  The names of its elements are the header row configuration
    # options for the Tablelist widget class.  The value of an array element is
    # either an alias name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	}
    #	-----------------------------------------------------------------
    #
    variable hdr_rowConfigSpecs
    array set hdr_rowConfigSpecs {
	-background		{background		Background	}
	-bg			-background
	-font			{font			Font		}
	-foreground		{foreground		Foreground	}
	-fg			-foreground
	-name			{name			Name		}
	-text			{text			Text		}
    }

    #
    # The array cellConfigSpecs is used to handle cell configuration options.
    # The names of its elements are the cell configuration options for the
    # Tablelist widget class.  The value of an array element is either an alias
    # name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	}
    #	-----------------------------------------------------------------
    #
    variable cellConfigSpecs
    array set cellConfigSpecs {
	-background		{background		Background	}
	-bg			-background
	-editable		{editable		Editable	}
	-editwindow		{editWindow		EditWindow	}
	-font			{font			Font		}
	-foreground		{foreground		Foreground	}
	-fg			-foreground
	-image			{image			Image		}
	-selectbackground	{selectBackground	Foreground	}
	-selectforeground	{selectForeground	Background	}
	-stretchwindow		{stretchWindow		StretchWindow	}
	-text			{text			Text		}
	-valign			{valign			Valign		}
	-window			{window			Window		}
	-windowdestroy		{windowDestroy		WindowDestroy	}
	-windowupdate		{windowUpdate		WindowUpdate	}
    }

    #
    # Extend some elements of the array cellConfigSpecs
    #
    lappend cellConfigSpecs(-editable)		- 0
    lappend cellConfigSpecs(-editwindow)	- entry
    lappend cellConfigSpecs(-stretchwindow)	- 0
    lappend cellConfigSpecs(-valign)		- center

    #
    # The array hdr_cellConfigSpecs is used to handle header cell configuration
    # options.  The names of its elements are the header cell configuration
    # options for the Tablelist widget class.  The value of an array element is
    # either an alias name or a list containing the database name and class.
    #
    #	Command-Line Name	{Database Name		Database Class	}
    #	-----------------------------------------------------------------
    #
    variable hdr_cellConfigSpecs
    array set hdr_cellConfigSpecs {
	-background		{background		Background	}
	-bg			-background
	-font			{font			Font		}
	-foreground		{foreground		Foreground	}
	-fg			-foreground
	-image			{image			Image		}
	-stretchwindow		{stretchWindow		StretchWindow	}
	-text			{text			Text		}
	-valign			{valign			Valign		}
	-window			{window			Window		}
	-windowdestroy		{windowDestroy		WindowDestroy	}
	-windowupdate		{windowUpdate		WindowUpdate	}
    }

    #
    # Extend some elements of the array hdr_cellConfigSpecs
    #
    lappend hdr_cellConfigSpecs(-stretchwindow)	- 0
    lappend hdr_cellConfigSpecs(-valign)	- center

    #
    # Use a list to facilitate the handling of the command options
    #
    variable cmdOpts [list \
	activate activatecell applysorting attrib bbox bodypath bodytag \
	canceledediting cancelediting cellattrib cellbbox cellcget \
	cellconfigure cellindex cellselection cget childcount childindex \
	childkeys collapse collapseall columnattrib columncget \
	columnconfigure columncount columnindex columnwidth config \
	configcelllist configcells configcolumnlist configcolumns \
	configrowlist configrows configure containing containingcell \
	containingcolumn cornerlabelpath cornerpath curcellselection \
	curselection depth delete deletecolumns descendantcount dicttoitem \
	editcell editinfo editwinpath editwintag embedcheckbutton \
	embedcheckbuttons embedttkcheckbutton embedttkcheckbuttons entrypath \
	expand expandall expandedkeys fillcolumn findcolumnname findrowname \
	finishediting formatinfo get getcells getcolumns getformatted \
	getformattedcells getformattedcolumns getfullkeys getkeys hasattrib \
	hascellattrib hascolumnattrib hasrowattrib header headerpath \
	headertag hidetargetmark imagelabelpath index insert insertchild \
	insertchildlist insertchildren insertcolumnlist insertcolumns \
	insertlist iselemsnipped isexpanded istitlesnipped isviewable \
	itemlistvar itemtodict labelpath labels labeltag move movecolumn \
	nearest nearestcell nearestcolumn noderow parentkey refreshsorting \
	rejectinput resetsortinfo rowattrib rowcget rowconfigure scan \
	searchcolumn see seecell seecolumn selection separatorpath separators \
	showtargetmark size sort sortbycolumn sortbycolumnlist sortcolumn \
	sortcolumnlist sortorder sortorderlist targetmarkpath targetmarkpos \
	togglecolumnhide togglerowhide toplevelkey unsetattrib \
	unsetcellattrib unsetcolumnattrib unsetrowattrib viewablerowcount \
	windowpath xview yview]

    proc restrictCmdOpts {} {
	variable canElide
	variable cmdOpts
	if {!$canElide} {
	    foreach opt [list collapse collapseall expand expandall \
			 insertchild insertchildlist insertchildren \
			 togglerowhide] {
		set idx [lsearch -exact $cmdOpts $opt]
		set cmdOpts [lreplace $cmdOpts $idx $idx]
	    }
	}

	if {[llength [info commands ::dict]] == 0} {
	    foreach opt [list dicttoitem itemtodict] {
		set idx [lsearch -exact $cmdOpts $opt]
		set cmdOpts [lreplace $cmdOpts $idx $idx]
	    }
	}

	if {$::tk_version < 8.5} {
	    foreach opt [list header headerpath headertag] {
		set idx [lsearch -exact $cmdOpts $opt]
		set cmdOpts [lreplace $cmdOpts $idx $idx]
	    }
	}
    }
    restrictCmdOpts 

    #
    # Use lists to facilitate the handling of miscellaneous options
    #
    variable activeStyles  [list frame none underline]
    variable alignments    [list left right center]
    variable arrowStyles   [list flat5x3 flat5x4 flat6x4 flat7x4 flat7x5 \
				 flat7x7 flat8x4 flat8x5 flat9x5 flat9x6 \
				 flat11x6 flat15x8 flatAngle7x4 flatAngle7x5 \
				 flatAngle9x5 flatAngle9x6 flatAngle9x7 \
				 flatAngle10x6 flatAngle10x7 flatAngle11x6 \
				 flatAngle15x8 photo7x4 photo7x7 photo9x5 \
				 photo11x6 photo15x8 sunken8x7 sunken10x9 \
				 sunken12x11]
    variable arrowTypes    [list up down]
    variable colWidthOpts  [list -requested -stretched -total]
    variable curSelOpts    [list -all -nonhidden -viewable]
    variable expCollOpts   [list -fully -partly]
    variable findOpts      [list -descend -parent]
    variable gapTypeOpts   [list -any -horizontal -vertical]
    variable headerOpts    [list bbox cellattrib cellbbox cellcget \
				 cellconfigure cellindex configcelllist \
				 configcells configrowlist configrows \
				 containing containingcell delete \
				 embedcheckbutton embedcheckbuttons \
				 embedttkcheckbutton embedttkcheckbuttons \
				 fillcolumn findrowname get getcells \
				 getcolumns getformatted getformattedcells \
				 getformattedcolumns getfullkeys getkeys \
				 hascellattrib hasrowattrib imagelabelpath \
				 index insert insertlist iselemsnipped \
				 itemlistvar nearest nearestcell rowattrib \
				 rowcget rowconfigure size unsetcellattrib \
				 unsetrowattrib windowpath]
    variable scanOpts      [list mark dragto]
    variable searchOpts    [list -all -backwards -check -descend -exact \
				 -formatted -glob -nocase -not -numeric \
				 -parent -regexp -start]
    variable selectionOpts [list anchor clear includes set]
    variable selectTypes   [list row cell]
    variable targetOpts    [list before inside]
    variable sortModes     [list ascii asciinocase command dictionary \
				 integer real]
    variable sortOpts      [list -increasing -decreasing]
    variable sortOrders    [list increasing decreasing]
    variable states	   [list disabled normal]
    variable treeStyles    [list adwaita ambiance aqua arc baghira bicolor1 \
				 bicolor2 bicolor3 bicolor4 blueMenta \
				 classic1 classic2 classic3 classic4 dust \
				 dustSand gtk klearlooks mate menta mint \
				 mint2 newWave oxygen1 oxygen2 phase plain1 \
				 plain2 plain3 plain4 plastik plastique \
				 radiance ubuntu ubuntu2 ubuntu3 ubuntuMate \
				 vistaAero vistaClassic win7Aero win7Classic \
				 win10 winnative winxpBlue winxpOlive \
				 winxpSilver yuyo]
    variable valignments   [list center top bottom]

    proc restrictArrowStyles {} {
	variable pngSupported
	if {!$pngSupported} {
	    variable arrowStyles
	    set idx [lsearch -exact $arrowStyles "photo7x7"]
	    set arrowStyles [lreplace $arrowStyles $idx $idx]
	}
    }
    restrictArrowStyles 

    #
    # The array maxIndentDepths holds the current max.
    # indentation depth for every tree style in use
    #
    variable maxIndentDepths

    #
    # Whether to support strictly Tk core listbox compatible bindings only
    #
    variable strictTk 0

    #
    # Define the command mapTabs, which returns the string obtained by
    # replacing all \t characters in its argument with \\t, as well as
    # the commands strMap and isInteger, needed because the "string map"
    # and "string is" commands were not available in Tcl 8.0 and 8.1.0
    #
    if {[catch {string map {} ""}] == 0} {
	interp alias {} ::tablelist::mapTabs {} string map {"\t" "\\t"}
	interp alias {} ::tablelist::strMap  {} string map
    } else {
	proc mapTabs str {
	    regsub -all "\t" $str "\\t" str
	    return $str
	}

	proc strMap {charMap str} {
	    foreach {key val} $charMap {
		#
		# We will only need this for noncritical key and str values
		#
		regsub -all $key $str $val str
	    }

	    return $str
	}
    }
    if {[catch {string is integer "0"}] == 0} {
	interp alias {} ::tablelist::isInteger {} string is integer -strict
    } else {
	proc isInteger str {
	    return [expr {[catch {format "%d" $str}] == 0}]
	}
    }

    #
    # Define the command genVirtualEvent, needed because the -data option of the
    # "event generate" command was not available in Tk versions earlier than 8.5
    #
    if {[catch {event generate . <<__>> -data ""}] == 0} {
	proc genVirtualEvent {win event userData} {
	    event generate $win $event -data $userData
	}
    } else {
	proc genVirtualEvent {win event userData} {
	    event generate $win $event
	}
    }

    #
    # Define the variable pu holding the position unit "indices" or "chars"
    # to be used in text widget indices of the form <index>(+|-)<count>$pu
    #
    variable pu
    if {$::tk_version >= 8.5} {
	set pu indices
    } else {
	set pu chars
    }

    interp alias {} ::tablelist::configSubCmd \
		 {} ::tablelist::configureSubCmd
    interp alias {} ::tablelist::insertchildSubCmd \
		 {} ::tablelist::insertchildrenSubCmd
}

#
# Private procedure creating the default bindings
# ===============================================
#

#------------------------------------------------------------------------------
# tablelist::createBindings
#
# Creates the default bindings for the binding tags Tablelist, TablelistWindow,
# TablelistKeyNav, TablelistBody, TablelistLabel, TablelistSubLabel,
# TablelistArrow, and TablelistEdit.
#------------------------------------------------------------------------------
proc tablelist::createBindings {} {
    #
    # Define some Tablelist class bindings
    #
    bind Tablelist <KeyPress> continue
    bind Tablelist <FocusIn> {
	tablelist::addActiveTag %W
	if {[string compare [focus -lastfor %W] %W] == 0} {
	    if {[winfo exists [%W editwinpath]]} {
		focus [set tablelist::ns%W::data(editFocus)]
	    } else {
		focus [%W bodypath]
	    }
	}
    }
    bind Tablelist <FocusOut>		{ tablelist::removeActiveTag %W }
    bind Tablelist <<TablelistSelect>>	{ event generate %W <<ListboxSelect>> }
    bind Tablelist <Destroy>		{ tablelist::cleanup %W }
    bind Tablelist <<ThemeChanged>> {
	after idle [list tablelist::updateConfigSpecs %W]
    }
    variable usingTile
    if {$usingTile} {
	bind Tablelist <Activate>	{ tablelist::updateCanvases %W }
	bind Tablelist <Deactivate>	{ tablelist::updateCanvases %W }
    }

    #
    # Define a TablelistWindow class binding
    #
    bind TablelistWindow <Destroy>	{ tablelist::cleanupWindow %W }

    #
    # Define the binding tags TablelistKeyNav,
    # TablelistBody, and TablelistHeader
    #
    mwutil::defineKeyNav Tablelist
    defineTablelistBody 
    defineTablelistHeader 

    #
    # Define the virtual events <<Button3>> and <<ShiftButton3>>
    #
    event add <<Button3>> <Button-3>
    event add <<ShiftButton3>> <Shift-Button-3>
    variable winSys
    if {[string compare $winSys "classic"] == 0 ||
	[string compare $winSys "aqua"] == 0} {
	event add <<Button3>> <Control-Button-1>
	event add <<ShiftButton3>> <Shift-Control-Button-1>
    }

    #
    # Define the binding tags TablelistLabel,
    # TablelistSubLabel, and TablelistArrow
    #
    defineTablelistLabel 
    defineTablelistSubLabel 
    defineTablelistArrow 

    #
    # Define the binding tag TablelistEdit if the file tablelistEdit.tcl exists
    #
    catch {defineTablelistEdit}
}

#
# Public procedure creating a new tablelist widget
# ================================================
#

#------------------------------------------------------------------------------
# tablelist::tablelist
#
# Creates a new tablelist widget whose name is specified as the first command-
# line argument, and configures it according to the options and their values
# given on the command line.  Returns the name of the newly created widget.
#------------------------------------------------------------------------------
proc tablelist::tablelist args {
    variable usingTile
    variable configSpecs
    variable configOpts
    variable canElide

    if {[llength $args] == 0} {
	mwutil::wrongNumArgs "tablelist pathName ?options?"
    }

    #
    # Create a frame of the class Tablelist
    #
    set win [lindex $args 0]
    if {[catch {
	if {$usingTile} {
	    ttk::frame $win -style Frame$win.TFrame -class Tablelist \
			    -height 0 -width 0 -padding 0
	} else {
	    tk::frame $win -class Tablelist -container 0 -height 0 -width 0
	    catch {$win configure -padx 0 -pady 0}
	}
    } result] != 0} {
	return -code error $result
    }

    #
    # Create a namespace within the current one to hold the data of the widget
    #
    namespace eval ns$win {
	#
	# The folowing array holds various data for this widget
	#
	variable data
	array set data {
	    arrowWidth		 10
	    arrowHeight		 9
	    hasListVar		 0
	    isDisabled		 0
	    ownsFocus		 0
	    charWidth		 1
	    hdrWidth		 0
	    activeRow		 0
	    activeCol		 0
	    anchorRow		 0
	    anchorCol		 0
	    seqNum		-1
	    hdr_seqNum		-1
	    freeKeyList		 {}
	    keyList		 {}
	    hdr_keyList		 {}
	    itemList		 {}
	    hdr_itemList	 {}
	    itemCount		 0
	    hdr_itemCount	 0
	    lastRow		-1
	    hdr_lastRow		-1
	    colList		 {}
	    colCount		 0
	    lastCol		-1
	    treeCol		 0
	    gotResizeEvent	 0
	    rightX		 0
	    btmY		 0
	    rowTagRefCount	 0
	    cellTagRefCount	 0
	    imgCount		 0
	    winCount		 0
	    indentCount		 0
	    afterId		 ""
	    labelClicked	 0
	    arrowColList	 {}
	    sortColList		 {}
	    sortOrder		 ""
	    editKey		 ""
	    editRow		-1
	    editCol		-1
	    canceled		 0
	    fmtKey		 ""
	    fmtRow		-1
	    fmtCol		-1
	    prevCell		 ""
	    hdr_prevCell	 ""
	    prevCol		-1
	    forceAdjust		 0
	    fmtCmdFlagList	 {}
	    hasFmtCmds		 0
	    scrlColOffset	 0
	    cellsToReconfig	 {}
	    hdr_cellsToReconfig	 {}
	    nonViewableRowCount	 0
	    viewableRowList	 {-1}
	    hiddenColCount	 0
	    root-row		-1
	    root-parent		 ""
	    root-children	 {}
	    keyToRowMapValid	 1
	    searchStartIdx	 0
	    keyBeingExpanded	 ""
	    destroyIdList	 {}
	    justEntered		 0
	    inEditWin		 0
	}

	#
	# The following array is used to hold arbitrary
	# attributes and their values for this widget
	#
	variable attribs

	#
	# The following array is used to hold the selection
	# state of embedded checkbutton windows created via
	# createTkCheckbutton and createTtkCheckbutton
	#
	variable checkStates
    }

    #
    # Initialize some further components of data
    #
    upvar ::tablelist::ns${win}::data data
    foreach opt $configOpts {
	set data($opt) [lindex $configSpecs($opt) 3]
    }
    set data(currentTheme) [getCurrentTheme]
    if {[string compare $data(currentTheme) "tileqt"] == 0} {
	set data(widgetStyle) [tileqt_currentThemeName]
	if {[info exists ::env(KDE_SESSION_VERSION)] &&
	    [string length $::env(KDE_SESSION_VERSION)] != 0} {
	    set data(colorScheme) [getKdeConfigVal "General" "ColorScheme"]
	} else {
	    set data(colorScheme) [getKdeConfigVal "KDE" "colorScheme"]
	}
    } else {
	set data(widgetStyle) ""
	set data(colorScheme) ""
    }
    if {$usingTile} {
	setThemeDefaults 
	variable themeDefaults
	set data(themeDefaults) [array get themeDefaults]
    }
    set data(-titlecolumns)	0		;# for Tk versions < 8.3
    set data(-treecolumn)	0		;# for Tk versions < 8.3
    set data(-treestyle)	""		;# for Tk versions < 8.3
    set data(colFontList)	[list $data(-font)]
    set data(listVarTraceCmd)	[list tablelist::listVarTrace $win]
    set data(bodyTag)		body$win
    set data(headerTag)		header$win
    set data(labelTag)		label$win
    set data(editwinTag)	editwin$win
    set data(body)		$win.body
    set data(bodyFrm)		$data(body).f
    set data(bodyFrmEd)		$data(bodyFrm).e
    set data(rowGap)		$data(body).g
    set data(hdr)		$win.hdr
    set data(hdrTxt)		$data(hdr).t
    set data(hdrTxtFrm)		$data(hdrTxt).f
    set data(hdrTxtFrmCanv)	$data(hdrTxtFrm).c
    set data(hdrTxtFrmLbl)	$data(hdrTxtFrm).l
    set data(hdrFrm)		$data(hdr).f
    set data(hdrFrmLbl)		$data(hdrFrm).l
    set data(colGap)		$data(hdr).g
    set data(lb)		$win.lb
    set data(vsep)		$win.vsep
    set data(hsep)		$win.hsep

    #
    # Get a unique name for the corner frame (a sibling of the tablelist widget)
    #
    set data(corner) $win-corner
    for {set n 2} {[winfo exists $data(corner)]} {incr n} {
	set data(corner) $data(corner)$n
    }
    set data(cornerLbl) $data(corner).l

    #
    # Create a child hierarchy used to hold the column labels.  The
    # labels will be created as children of the frame data(hdrTxtFrm),
    # which is embedded into the text widget data(hdrTxt) (in order
    # to make it scrollable), which in turn fills the frame data(hdr)
    # (whose width and height can be set arbitrarily in pixels).
    #

    set w $data(hdr)			;# header frame
    tk::frame $w -borderwidth 0 -container 0 -height 0 -highlightthickness 0 \
		 -relief flat -takefocus 0 -width 0
    catch {$w configure -padx 0 -pady 0}
    bind $w <Configure> { tablelist::hdrConfigure %W %w }
    pack $w -fill x

    set w $data(hdrTxt)			;# text widget within the header frame
    text $w -borderwidth 0 -highlightthickness 0 -insertwidth 0 \
	    -padx 0 -pady 0 -state normal -takefocus 0 -wrap none
    catch {$w configure -undo 0};  # because of a text widget issue in Tk 8.6.6
    place $w -relheight 1.0 -relwidth 1.0
    bindtags $w [list $w $data(headerTag) TablelistHeader [winfo toplevel $w] \
		 all]
    tk::frame $data(hdrTxtFrm) -borderwidth 0 -container 0 -height 0 \
			       -highlightthickness 0 -relief flat \
			       -takefocus 0 -width 0
    catch {$data(hdrTxtFrm) configure -padx 0 -pady 0}
    $w window create 1.0 -window $data(hdrTxtFrm) -align top
    $w tag configure noSpacings -spacing1 0 -spacing3 0
    $w tag add noSpacings 1.0
    $w tag configure tinyFont -font "Courier -1"
    $w tag add tinyFont 1.0 end
    $w tag configure disabled -foreground ""	;# will be changed
    $w tag configure hiddenCol -elide 1		;# used for hiding a column
    $w tag configure elidedCol -elide 1		;# used for horizontal scrolling

    set w $data(hdrFrm)			;# filler frame within the header frame
    tk::frame $w -borderwidth 0 -container 0 -height 0 -highlightthickness 0 \
		 -relief flat -takefocus 0 -width 0
    catch {$w configure -padx 0 -pady 0}
    place $w -relwidth 1.0

    set w $data(hdrFrmLbl)		;# label within the filler frame
    set x 0
    if {$usingTile} {
	ttk::label $w -style TablelistHeader.TLabel -image "" \
		      -padding {1 1 1 1} -takefocus 0 -text "" \
		      -textvariable "" -underline -1 -wraplength 0
	if {[string compare [getCurrentTheme] "aqua"] == 0} {
	    set x -1
	}
    } else {
	tk::label $w -bitmap "" -highlightthickness 0 -image "" \
		     -takefocus 0 -text "" -textvariable "" -underline -1 \
		     -wraplength 0
    }
    place $w -x $x -relheight 1.0 -relwidth 1.0

    set w $data(corner)			;# corner frame (outside the tablelist)
    tk::frame $w -borderwidth 0 -container 0 -height 0 -highlightthickness 0 \
		 -relief flat -takefocus 0 -width 0
    catch {$w configure -padx 0 -pady 0}

    set w $data(cornerLbl)		;# label within the corner frame
    if {$usingTile} {
	ttk::label $w -style TablelistHeader.TLabel -image "" \
		      -padding {1 1 1 1} -takefocus 0 -text "" \
		      -textvariable "" -underline -1 -wraplength 0
    } else {
	tk::label $w -bitmap "" -highlightthickness 0 -image "" \
		     -takefocus 0 -text "" -textvariable "" -underline -1 \
		     -wraplength 0
    }
    place $w -relheight 1.0 -relwidth 1.0

    if {$::tk_version >= 8.5} {
	#
	# Create the upper horizontal separator
	# (to be placed just below the header rows)
	#
	set w $data(hsep)1
	if {$usingTile} {
	    ttk::separator $w -style Main$win.TSeparator \
			      -cursor $data(-cursor) -takefocus 0
	} else {
	    tk::frame $w -background $data(-foreground) -borderwidth 1 \
			 -container 0 -cursor $data(-cursor) -height 2 \
			 -highlightthickness 0 -relief sunken -takefocus 0
	}
    }

    #
    # Create the body text widget within the main frame
    #
    set w $data(body)
    text $w -borderwidth 0 -exportselection 0 -highlightthickness 0 \
	    -insertwidth 0 -padx 0 -pady 0 -state normal -takefocus 0 -wrap none
    catch {$w configure -undo 0};  # because of a text widget issue in Tk 8.6.6
    bind $w <Configure> { tablelist::bodyConfigure %W %w %h }
    pack $w -expand 1 -fill both
    bindtags $w [list $w $data(bodyTag) TablelistBody [winfo toplevel $w] \
		 TablelistKeyNav all]

    #
    # Create the "stripe", "select", "curRow", "active", "disabled", "redraw",
    # "hiddenRow", "elidedRow", "hiddenCol", and "elidedCol" tags in the body
    # text widget.  Don't use the built-in "sel" tag because on Windows the
    # selection in a text widget only becomes visible when the window gets
    # the input focus.  DO NOT CHANGE the order of creation of these tags!
    #
    $w tag configure stripe -background "" -foreground ""    ;# will be changed
    $w tag configure select -relief raised
    $w tag configure curRow -borderwidth 1 -relief raised
    $w tag configure active -borderwidth ""		     ;# will be changed
    $w tag configure disabled -foreground ""		     ;# will be changed
    $w tag configure redraw -relief sunken
    if {$canElide} {
	$w tag configure hiddenRow -elide 1	;# used for hiding a row
	$w tag configure elidedRow -elide 1	;# used when collapsing a node
	$w tag configure hiddenCol -elide 1	;# used for hiding a column
	$w tag configure elidedCol -elide 1	;# used for horizontal scrolling
    }
    if {$::tk_version >= 8.5} {
	$w tag configure elidedWin -elide 1	;# used for eliding a window
    }

    #
    # Create two frames used to display a gap between two consecutive
    # rows/columns when moving a row/column interactively
    #
    tk::frame $data(rowGap) -borderwidth 1 -container 0 -highlightthickness 0 \
			    -relief sunken -takefocus 0 -height 4
    tk::frame $data(colGap) -borderwidth 1 -container 0 -highlightthickness 0 \
			    -relief sunken -takefocus 0 -width 4

    #
    # Create an unmanaged listbox child, used to handle the -setgrid option
    #
    listbox $data(lb)

    #
    # Create the bitmaps needed to display the sort ranks
    #
    createSortRankImgs $win

    #
    # Take into account that some scripts start by
    # destroying all children of the root window
    #
    variable helpLabel
    if {![winfo exists $helpLabel]} {
	if {$usingTile} {
	    ttk::label $helpLabel -takefocus 0
	} else {
	    tk::label $helpLabel -takefocus 0
	}
    }

    #
    # Configure the widget according to the command-line
    # arguments and to the available database options
    #
    if {[catch {
	mwutil::configureWidget $win configSpecs tablelist::doConfig \
				tablelist::doCget [lrange $args 1 end] 1
    } result] != 0} {
	destroy $win
	return -code error $result
    }

    #
    # Move the original widget command into the current namespace and
    # create an alias of the original name for a new widget procedure
    #
    rename ::$win $win
    interp alias {} ::$win {} tablelist::tablelistWidgetCmd $win

    #
    # Register a callback to be invoked whenever the PRIMARY
    # selection is owned by the window win and someone
    # attempts to retrieve it as a UTF8_STRING or STRING
    #
    selection handle -type UTF8_STRING $win \
	[list ::tablelist::fetchSelection $win]
    selection handle -type STRING $win \
	[list ::tablelist::fetchSelection $win]

    #
    # Set a trace on the array elements data(activeRow),
    # data(avtiveCol), and data(-selecttype)
    #
    foreach name {activeRow activeCol -selecttype} {
	trace variable data($name) w [list tablelist::activeTrace $win]
    }

    trace variable ::tablelist::ns${win}::checkStates w \
	  [list tablelist::checkStatesTrace $win]

    return $win
}

#
# Private procedures implementing the tablelist widget command
# ============================================================
#

#------------------------------------------------------------------------------
# tablelist::tablelistWidgetCmd
#
# Processes the Tcl command corresponding to a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::tablelistWidgetCmd {win args} {
    if {[llength $args] == 0} {
	mwutil::wrongNumArgs "$win option ?arg arg ...?"
    }

    variable cmdOpts
    set cmd [mwutil::fullOpt "option" [lindex $args 0] $cmdOpts]
    return [${cmd}SubCmd $win [lrange $args 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::activateSubCmd
#------------------------------------------------------------------------------
proc tablelist::activateSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win activate index"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0]

    #
    # Adjust the index to fit within the existing viewable items
    #
    adjustRowIndex $win index 1

    set data(activeRow) $index
    return ""
}

#------------------------------------------------------------------------------
# tablelist::activatecellSubCmd
#------------------------------------------------------------------------------
proc tablelist::activatecellSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win activatecell cellIndex"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 0] {}

    #
    # Adjust the row and column indices to fit
    # within the existing viewable elements
    #
    adjustRowIndex $win row 1
    adjustColIndex $win col 1

    set data(activeRow) $row
    set data(activeCol) $col
    return ""
}

#------------------------------------------------------------------------------
# tablelist::applysortingSubCmd
#------------------------------------------------------------------------------
proc tablelist::applysortingSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win applysorting itemList"
    }

    return [sortList $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::attribSubCmd
#------------------------------------------------------------------------------
proc tablelist::attribSubCmd {win argList} {
    return [mwutil::attribSubCmd $win "widget" $argList]
}

#------------------------------------------------------------------------------
# tablelist::bboxSubCmd
#------------------------------------------------------------------------------
proc tablelist::bboxSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win bbox index"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0]

    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set dlineinfo [$w dlineinfo [expr {$index + 1}].0]
    if {$data(itemCount) == 0 || [llength $dlineinfo] == 0} {
	return {}
    }

    set spacing1 [$w cget -spacing1]
    set spacing3 [$w cget -spacing3]
    foreach {x y width height baselinePos} $dlineinfo {}
    incr height -[expr {$spacing1 + $spacing3}]
    if {$height < 0} {
	set height 0
    }
    return [list [expr {$x + [winfo x $w]}] \
		 [expr {$y + [winfo y $w] + $spacing1}] $width $height]
}

#------------------------------------------------------------------------------
# tablelist::bodypathSubCmd
#------------------------------------------------------------------------------
proc tablelist::bodypathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win bodypath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(body)
}

#------------------------------------------------------------------------------
# tablelist::bodytagSubCmd
#------------------------------------------------------------------------------
proc tablelist::bodytagSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win bodytag"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(bodyTag)
}

#------------------------------------------------------------------------------
# tablelist::cancelededitingSubCmd
#------------------------------------------------------------------------------
proc tablelist::cancelededitingSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win canceledediting"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(canceled)
}

#------------------------------------------------------------------------------
# tablelist::canceleditingSubCmd
#------------------------------------------------------------------------------
proc tablelist::canceleditingSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win cancelediting"
    }

    synchronize $win
    return [doCancelEditing $win]
}

#------------------------------------------------------------------------------
# tablelist::cellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win cellattrib cellIndex ?name? ?value name value ...?"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::attribSubCmd $win $key,$col [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::cellbboxSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellbboxSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win cellbbox cellIndex"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 0] {}
    upvar ::tablelist::ns${win}::data data
    if {$row < 0 || $row > $data(lastRow) ||
	$col < 0 || $col > $data(lastCol)} {
	return {}
    }

    foreach {x y width height} [bboxSubCmd $win $row] {}
    set w $data(hdrTxtFrmLbl)$col
    return [list [expr {[winfo rootx $w] - [winfo rootx $win]}] $y \
		 [winfo width $w] $height]
}

#------------------------------------------------------------------------------
# tablelist::cellcgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellcgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win cellcget cellIndex option"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    variable cellConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] cellConfigSpecs]
    return [doCellCget $row $col $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::cellconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win cellconfigure cellIndex ?option? ?value option value ...?"
    }

    synchronize $win
    displayItems $win
    variable cellConfigSpecs
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    return [mwutil::configureSubCmd $win cellConfigSpecs \
	    "tablelist::doCellConfig $row $col" \
	    "tablelist::doCellCget $row $col" [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::cellindexSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellindexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win cellindex cellIndex"
    }

    synchronize $win
    return [join [cellIndex $win [lindex $argList 0] 0] ","]
}

#------------------------------------------------------------------------------
# tablelist::cellselectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::cellselectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2 || $argCount > 3} {
	mwutil::wrongNumArgs \
		"$win cellselection option firstCellIndex lastCellIndex" \
		"$win cellselection option cellIndexList"
    }

    synchronize $win
    displayItems $win
    variable selectionOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $selectionOpts]
    set first [lindex $argList 1]

    switch $opt {
	anchor -
	includes {
	    if {$argCount != 2} {
		mwutil::wrongNumArgs "$win cellselection $opt cellIndex"
	    }
	    foreach {row col} [cellIndex $win $first 0] {}
	    return [cellSelection $win $opt $row $col $row $col]
	}

	clear -
	set {
	    if {$argCount == 2} {
		foreach elem $first {
		    foreach {row col} [cellIndex $win $elem 0] {}
		    cellSelection $win $opt $row $col $row $col
		}
	    } else {
		foreach {firstRow firstCol} [cellIndex $win $first 0] {}
		foreach {lastRow lastCol} \
			[cellIndex $win [lindex $argList 2] 0] {}
		cellSelection $win $opt $firstRow $firstCol $lastRow $lastCol
	    }

	    updateColors $win
	    invokeMotionHandler $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::cgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::cgetSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win cget option"
    }

    #
    # Return the value of the specified configuration option
    #
    variable configSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 0] configSpecs]
    return [doCget $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::childcountSubCmd
#------------------------------------------------------------------------------
proc tablelist::childcountSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win childcount nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    upvar ::tablelist::ns${win}::data data
    return [llength $data($key-children)]
}

#------------------------------------------------------------------------------
# tablelist::childindexSubCmd
#------------------------------------------------------------------------------
proc tablelist::childindexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win childindex index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set parentKey $data($key-parent)
    return [lsearch -exact $data($parentKey-children) $key]
}

#------------------------------------------------------------------------------
# tablelist::childkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::childkeysSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win childkeys nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    upvar ::tablelist::ns${win}::data data
    return $data($key-children)
}

#------------------------------------------------------------------------------
# tablelist::collapseSubCmd
#------------------------------------------------------------------------------
proc tablelist::collapseSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win collapse index ?-fully|-partly?"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0 1]

    if {$argCount == 1} {
	set fullCollapsion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $expCollOpts]
	set fullCollapsion [expr {[string compare $opt "-fully"] == 0}]
    }

    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    set col $data(treeCol)
    if {![info exists data($key,$col-indent)]} {
	return ""
    }

    if {[string length $data(-collapsecommand)] != 0} {
	uplevel #0 $data(-collapsecommand) [list $win $index]
    }

    #
    # Set the indentation image to the collapsed one
    #
    set data($key,$col-indent) [strMap \
	{"indented" "collapsed" "expanded" "collapsed"} $data($key,$col-indent)]
    if {[winfo exists $data(body).ind_$key,$col]} {
	$data(body).ind_$key,$col configure -image $data($key,$col-indent)
    }

    if {[llength $data($key-children)] == 0} {
	return ""
    }

    #
    # Elide the descendants of this item
    #
    set fromRow [expr {$index + 1}]
    set toRow [nodeRow $win $key end]
    for {set row $fromRow} {$row < $toRow} {incr row} {
	doRowConfig $row $win -elide 1

	if {$fullCollapsion} {
	    set descKey [lindex $data(keyList) $row]
	    if {[llength $data($descKey-children)] != 0} {
		if {[string length $data(-collapsecommand)] != 0} {
		    uplevel #0 $data(-collapsecommand) \
			[list $win [keyToRow $win $descKey]]
		}

		#
		# Change the descendant's indentation image
		# from the expanded to the collapsed one
		#
		set data($descKey,$col-indent) [strMap \
		    {"expanded" "collapsed"} $data($descKey,$col-indent)]
		if {[winfo exists $data(body).ind_$descKey,$col]} {
		    $data(body).ind_$descKey,$col configure -image \
			$data($descKey,$col-indent)
		}
	    }
	}
    }

    set callerProc [lindex [info level -1] 0]
    if {![string match "collapse*SubCmd" $callerProc]} {
	#
	# Destroy the label and messsage widgets
	# embedded into the descendants just elided
	#
	set widgets {}
	set fromTextIdx [expr {$fromRow + 1}].0
	set toTextIdx [expr {$toRow + 1}].0
	foreach {dummy path textIdx} \
		[$data(body) dump -window $fromTextIdx $toTextIdx] {
	    if {[string length $path] != 0} {
		set class [winfo class $path]
		if {[string compare $class "Label"] == 0 ||
		    [string compare $class "Message"] == 0} {
		    lappend widgets $path
		}
	    }
	}
	set destroyId [after 300 [list tablelist::destroyWidgets $win]]
	lappend data(destroyIdList) $destroyId
	set data(widgets-$destroyId) $widgets

	adjustRowIndex $win data(anchorRow) 1

	set activeRow $data(activeRow)
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow

	hdr_adjustElidedText $win
	hdr_updateColors $win
	adjustElidedText $win
	redisplayVisibleItems $win
	updateColors $win
	makeStripes $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::collapseallSubCmd
#------------------------------------------------------------------------------
proc tablelist::collapseallSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win collapseall ?-fully|-partly?"
    }

    if {$argCount == 0} {
	set fullCollapsion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $expCollOpts]
	set fullCollapsion [expr {[string compare $opt "-fully"] == 0}]
    }

    synchronize $win
    displayItems $win

    upvar ::tablelist::ns${win}::data data
    set col $data(treeCol)

    if {[winfo viewable $win]} {
	purgeWidgets $win
	update idletasks
	if {[destroyed $win]} {
	    return ""
	}
    }

    set childIdx 0
    set childCount [llength $data(root-children)]
    foreach key $data(root-children) {
	if {[llength $data($key-children)] == 0} {
	    incr childIdx
	    continue
	}

	if {[string length $data(-collapsecommand)] != 0} {
	    uplevel #0 $data(-collapsecommand) [list $win [keyToRow $win $key]]
	}

	#
	# Change the indentation image from the expanded to the collapsed one
	#
	set data($key,$col-indent) \
	    [strMap {"expanded" "collapsed"} $data($key,$col-indent)]
	if {[winfo exists $data(body).ind_$key,$col]} {
	    $data(body).ind_$key,$col configure -image $data($key,$col-indent)
	}

	#
	# Elide the descendants of this item
	#
	incr childIdx
	if {[llength $data($key-children)] != 0} {
	    set fromRow [expr {[keyToRow $win $key] + 1}]
	    if {$childIdx < $childCount} {
		set nextChildKey [lindex $data(root-children) $childIdx]
		set toRow [keyToRow $win $nextChildKey]
	    } else {
		set toRow $data(itemCount)
	    }
	    for {set row $fromRow} {$row < $toRow} {incr row} {
		doRowConfig $row $win -elide 1

		if {$fullCollapsion} {
		    set descKey [lindex $data(keyList) $row]
		    if {[llength $data($descKey-children)] != 0} {
			if {[string length $data(-collapsecommand)] != 0} {
			    uplevel #0 $data(-collapsecommand) \
				[list $win [keyToRow $win $descKey]]
			}

			#
			# Change the descendant's indentation image
			# from the expanded to the collapsed one
			#
			set data($descKey,$col-indent) \
			    [strMap {"expanded" "collapsed"} \
				    $data($descKey,$col-indent)]
			if {[winfo exists $data(body).ind_$descKey,$col]} {
			    $data(body).ind_$descKey,$col configure -image \
				$data($descKey,$col-indent)
			}
		    }
		}
	    }

	    #
	    # Destroy the label and messsage widgets
	    # embedded into the descendants just elided
	    #
	    set widgets {}
	    set fromTextIdx [expr {$fromRow + 1}].0
	    set toTextIdx [expr {$toRow + 1}].0
	    foreach {dummy path textIdx} \
		    [$data(body) dump -window $fromTextIdx $toTextIdx] {
		if {[string length $path] != 0} {
		    set class [winfo class $path]
		    if {[string compare $class "Label"] == 0 ||
			[string compare $class "Message"] == 0} {
			lappend widgets $path
		    }
		}
	    }
	    set destroyId [after 300 [list tablelist::destroyWidgets $win]]
	    lappend data(destroyIdList) $destroyId
	    set data(widgets-$destroyId) $widgets
	}
    }

    adjustRowIndex $win data(anchorRow) 1

    set activeRow $data(activeRow)
    adjustRowIndex $win activeRow 1
    set data(activeRow) $activeRow

    hdr_adjustElidedText $win
    hdr_updateColors $win
    adjustElidedText $win
    redisplayVisibleItems $win
    updateColors $win
    makeStripes $win
    adjustSepsWhenIdle $win
    updateVScrlbarWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::columnattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win columnattrib columnIndex ?name? ?value name value ...?"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::attribSubCmd $win $col [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::columncgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::columncgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win columncget columnIndex option"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    variable colConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] colConfigSpecs]
    return [doColCget $col $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::columnconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win columnconfigure columnIndex ?option? ?value\
		 option value ...?"
    }

    synchronize $win
    displayItems $win
    variable colConfigSpecs
    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::configureSubCmd $win colConfigSpecs \
	    "tablelist::doColConfig $col" "tablelist::doColCget $col" \
	    [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::columncountSubCmd
#------------------------------------------------------------------------------
proc tablelist::columncountSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win columncount"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(colCount)
}

#------------------------------------------------------------------------------
# tablelist::columnindexSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnindexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win columnindex columnIndex"
    }

    return [colIndex $win [lindex $argList 0] 0]
}

#------------------------------------------------------------------------------
# tablelist::columnwidthSubCmd
#------------------------------------------------------------------------------
proc tablelist::columnwidthSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win columnwidth columnIndex ?-requested|-stretched|-total?"
    }

    synchronize $win
    set col [colIndex $win [lindex $argList 0] 1]
    if {$argCount == 1} {
	set opt -requested
    } else {
	variable colWidthOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $colWidthOpts]
    }
    return [colWidth $win $col $opt]
}

#------------------------------------------------------------------------------
# tablelist::configcelllistSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcelllistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win configcelllist cellConfigSpecList"
    }

    return [configcellsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::configcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcellsSubCmd {win argList} {
    synchronize $win
    displayItems $win
    variable cellConfigSpecs

    set argCount [llength $argList]
    foreach {cell opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$cell\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	foreach {row col} [cellIndex $win $cell 1] {}
	mwutil::configureWidget $win cellConfigSpecs \
		"tablelist::doCellConfig $row $col" \
		"tablelist::doCellCget $row $col" [list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::configcolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcolumnlistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win configcolumnlist columnConfigSpecList"
    }

    return [configcolumnsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::configcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::configcolumnsSubCmd {win argList} {
    synchronize $win
    displayItems $win
    variable colConfigSpecs

    set argCount [llength $argList]
    foreach {col opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$col\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	set col [colIndex $win $col 1]
	mwutil::configureWidget $win colConfigSpecs \
		"tablelist::doColConfig $col" "tablelist::doColCget $col" \
		[list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::configrowlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::configrowlistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win configrowlist rowConfigSpecList"
    }

    return [configrowsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::configrowsSubCmd
#------------------------------------------------------------------------------
proc tablelist::configrowsSubCmd {win argList} {
    synchronize $win
    displayItems $win
    variable rowConfigSpecs

    set argCount [llength $argList]
    foreach {rowSpec opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$rowSpec\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	set row [rowIndex $win $rowSpec 0 1]
	mwutil::configureWidget $win rowConfigSpecs \
		"tablelist::doRowConfig $row" "tablelist::doRowCget $row" \
		[list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::configureSubCmd
#------------------------------------------------------------------------------
proc tablelist::configureSubCmd {win argList} {
    variable configSpecs
    return [mwutil::configureSubCmd $win configSpecs tablelist::doConfig \
	    tablelist::doCget $argList]
}

#------------------------------------------------------------------------------
# tablelist::containingSubCmd
#------------------------------------------------------------------------------
proc tablelist::containingSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win containing y"
    }

    set y [format "%d" [lindex $argList 0]]
    synchronize $win
    displayItems $win
    return [containingRow $win $y]
}

#------------------------------------------------------------------------------
# tablelist::containingcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::containingcellSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win containingcell x y"
    }

    set x [format "%d" [lindex $argList 0]]
    set y [format "%d" [lindex $argList 1]]
    synchronize $win
    displayItems $win
    return [containingRow $win $y],[containingCol $win $x]
}

#------------------------------------------------------------------------------
# tablelist::containingcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::containingcolumnSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win containingcolumn x"
    }

    set x [format "%d" [lindex $argList 0]]
    synchronize $win
    displayItems $win
    return [containingCol $win $x]
}

#------------------------------------------------------------------------------
# tablelist::cornerlabelpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::cornerlabelpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win cornerlabelpath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(cornerLbl)
}

#------------------------------------------------------------------------------
# tablelist::cornerpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::cornerpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win cornerpath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(corner)
}

#------------------------------------------------------------------------------
# tablelist::curcellselectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::curcellselectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs \
		"$win curcellselection ?-all|-nonhidden||-viewable?"
    }

    if {$argCount == 0} {
	set constraint 0
    } else {
	variable curSelOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $curSelOpts]
	set constraint [lsearch -exact $curSelOpts $opt]
    }


    synchronize $win
    displayItems $win
    return [curCellSelection $win 0 $constraint]
}

#------------------------------------------------------------------------------
# tablelist::curselectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::curselectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs \
		"$win curselection ?-all|-nonhidden||-viewable?"
    }

    if {$argCount == 0} {
	set constraint 0
    } else {
	variable curSelOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $curSelOpts]
	set constraint [lsearch -exact $curSelOpts $opt]
    }

    synchronize $win
    displayItems $win
    return [curSelection $win $constraint]
}

#------------------------------------------------------------------------------
# tablelist::deleteSubCmd
#------------------------------------------------------------------------------
proc tablelist::deleteSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win delete firstIndex lastIndex" "$win delete indexList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    if {$argCount == 1} {
	if {[llength $first] == 1} {			;# just to save time
	    set index [rowIndex $win [lindex $first 0] 0]
	    return [deleteRows $win $index $index $data(hasListVar)]
	} elseif {$data(itemCount) == 0} {		;# no items present
	    return ""
	} else {					;# a bit more work
	    #
	    # Sort the numerical equivalents of the
	    # specified indices in decreasing order
	    #
	    set indexList {}
	    foreach elem $first {
		set index [rowIndex $win $elem 0]
		if {$index < 0} {
		    set index 0
		} elseif {$index > $data(lastRow)} {
		    set index $data(lastRow)
		}
		lappend indexList $index
	    }
	    set indexList [lsort -integer -decreasing $indexList]

	    #
	    # Traverse the sorted index list and ignore any duplicates
	    #
	    set prevIndex -1
	    foreach index $indexList {
		if {$index != $prevIndex} {
		    deleteRows $win $index $index $data(hasListVar)
		    set prevIndex $index
		}
	    }
	    return ""
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	return [deleteRows $win $first $last $data(hasListVar)]
    }
}

#------------------------------------------------------------------------------
# tablelist::deletecolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::deletecolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win deletecolumns firstColumn lastColumn" \
		"$win deletecolumns columnIndexList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    if {$argCount == 1} {
	if {[llength $first] == 1} {			;# just to save time
	    set col [colIndex $win [lindex $first 0] 1]
	    set selCells [curCellSelection $win]
	    deleteCols $win $col $col selCells
	    redisplay $win 0 $selCells
	} elseif {$data(colCount) == 0} {		;# no columns present
	    return ""
	} else {					;# a bit more work
	    #
	    # Sort the numerical equivalents of the
	    # specified column indices in decreasing order
	    #
	    set colList {}
	    foreach elem $first {
		lappend colList [colIndex $win $elem 1]
	    }
	    set colList [lsort -integer -decreasing $colList]

	    #
	    # Traverse the sorted column index list and ignore any duplicates
	    #
	    set selCells [curCellSelection $win]
	    set deleted 0
	    set prevCol -1
	    foreach col $colList {
		if {$col != $prevCol} {
		    deleteCols $win $col $col selCells
		    set deleted 1
		    set prevCol $col
		}
	    }
	    if {$deleted} {
		redisplay $win 0 $selCells
	    }
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]
	if {$first <= $last} {
	    set selCells [curCellSelection $win]
	    deleteCols $win $first $last selCells
	    redisplay $win 0 $selCells
	}
    }

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::depthSubCmd
#------------------------------------------------------------------------------
proc tablelist::depthSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win depth nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    return [depth $win $key]
}

#------------------------------------------------------------------------------
# tablelist::descendantcountSubCmd
#------------------------------------------------------------------------------
proc tablelist::descendantcountSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win descendantcount nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    return [descCount $win $key]
}

#------------------------------------------------------------------------------
# tablelist::dicttoitemSubCmd
#------------------------------------------------------------------------------
proc tablelist::dicttoitemSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win dicttoitem dictionary"
    }

    set origDict [lindex $argList 0]
    set newDict {}
    dict for {key val} $origDict {
	set col [colIndex $win $key 1]
	dict set newDict $col $val
    }

    set item {}
    upvar ::tablelist::ns${win}::data data
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {[dict exists $newDict $col]} {
	    set elem [dict get $newDict $col]
	} else {
	    set elem ""
	}
	lappend item $elem
    }
    return $item
}

#------------------------------------------------------------------------------
# tablelist::editcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::editcellSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win editcell cellIndex"
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    return [doEditCell $win $row $col 0]
}

#------------------------------------------------------------------------------
# tablelist::editinfoSubCmd
#------------------------------------------------------------------------------
proc tablelist::editinfoSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win editinfo"
    }

    upvar ::tablelist::ns${win}::data data
    return [list $data(editKey) $data(editRow) $data(editCol)]
}

#------------------------------------------------------------------------------
# tablelist::editwinpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::editwinpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win editwinpath"
    }

    upvar ::tablelist::ns${win}::data data
    if {[winfo exists $data(bodyFrmEd)]} {
	return $data(bodyFrmEd)
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::editwintagSubCmd
#------------------------------------------------------------------------------
proc tablelist::editwintagSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win editwintag"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(editwinTag)
}

#------------------------------------------------------------------------------
# tablelist::embedcheckbuttonSubCmd
#------------------------------------------------------------------------------
proc tablelist::embedcheckbuttonSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win embedcheckbutton cellIndex ?command?"
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    doCellConfig $row $col $win -window \
		 [list ::tablelist::createFrameWithCheckbutton $cmd]
    return ""
}

#------------------------------------------------------------------------------
# tablelist::embedcheckbuttonsSubCmd
#------------------------------------------------------------------------------
proc tablelist::embedcheckbuttonsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win embedcheckbuttons columnIndex ?command?"
    }

    synchronize $win
    displayItems $win
    set col [colIndex $win [lindex $argList 0] 1]

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    upvar ::tablelist::ns${win}::data data
    for {set row 0} {$row < $data(itemCount)} {incr row} {
	doCellConfig $row $col $win -window \
		     [list ::tablelist::createFrameWithCheckbutton $cmd]
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::embedttkcheckbuttonSubCmd
#------------------------------------------------------------------------------
proc tablelist::embedttkcheckbuttonSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win embedttkcheckbutton cellIndex ?command?"
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    doCellConfig $row $col $win -window \
		 [list ::tablelist::createFrameWithTileCheckbutton $cmd]
    return ""
}

#------------------------------------------------------------------------------
# tablelist::embedttkcheckbuttonsSubCmd
#------------------------------------------------------------------------------
proc tablelist::embedttkcheckbuttonsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win embedttkcheckbuttons columnIndex ?command?"
    }

    synchronize $win
    displayItems $win
    set col [colIndex $win [lindex $argList 0] 1]

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    upvar ::tablelist::ns${win}::data data
    for {set row 0} {$row < $data(itemCount)} {incr row} {
	doCellConfig $row $col $win -window \
		     [list ::tablelist::createFrameWithTileCheckbutton $cmd]
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::entrypathSubCmd
#------------------------------------------------------------------------------
proc tablelist::entrypathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win entrypath"
    }

    upvar ::tablelist::ns${win}::data data
    if {[winfo exists $data(bodyFrmEd)]} {
	set class [winfo class $data(bodyFrmEd)]
	if {[regexp {^(Mentry|T?Checkbutton|T?Menubutton)$} $class]} {
	    return ""
	} else {
	    return $data(editFocus)
	}
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::expandSubCmd
#------------------------------------------------------------------------------
proc tablelist::expandSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win expand index ?-fully|-partly?"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0 1]

    if {$argCount == 1} {
	set fullExpansion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $expCollOpts]
	set fullExpansion [expr {[string compare $opt "-fully"] == 0}]
    }

    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    set col $data(treeCol)
    if {![info exists data($key,$col-indent)] ||
	[string match "*indented*" $data($key,$col-indent)]} {
	return ""
    }

    set callerProc [lindex [info level -1] 0]
    if {[string compare $callerProc "doRowConfig"] != 0 &&
	[string length $data(-expandcommand)] != 0} {
	set data(keyBeingExpanded) $key
	uplevel #0 $data(-expandcommand) [list $win $index]
	set data(keyBeingExpanded) ""
    }

    #
    # Set the indentation image to the indented or expanded one
    #
    set childCount [llength $data($key-children)]
    set state [expr {($childCount == 0) ? "indented" : "expanded"}]
    set data($key,$col-indent) [strMap \
	[list "collapsed" $state "expanded" $state] $data($key,$col-indent)]
    if {[string compare $state "indented"] == 0} {
	set data($key,$col-indent) [strMap \
	    {"Act" "" "Sel" ""} $data($key,$col-indent)]
    }
    if {[winfo exists $data(body).ind_$key,$col]} {
	$data(body).ind_$key,$col configure -image $data($key,$col-indent)
    }

    #
    # Unelide the children if appropriate and
    # invoke this procedure recursively on them
    #
    set isViewable [expr {![info exists data($key-elide)] &&
			  ![info exists data($key-hide)]}]
    foreach childKey $data($key-children) {
	set childRow [keyToRow $win $childKey]
	if {$isViewable} {
	    doRowConfig $childRow $win -elide 0
	}
	if {$fullExpansion} {
	    expandSubCmd $win [list $childRow -fully]
	} elseif {[string match "*expanded*" $data($childKey,$col-indent)]} {
	    expandSubCmd $win [list $childRow -partly]
	}
    }

    if {![string match "expand*SubCmd" $callerProc]} {
	hdr_adjustElidedText $win
	hdr_updateColors $win
	adjustElidedText $win
	redisplayVisibleItems $win
	updateColors $win
	makeStripes $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::expandallSubCmd
#------------------------------------------------------------------------------
proc tablelist::expandallSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win expandall ?-fully|-partly?"
    }

    if {$argCount == 0} {
	set fullExpansion 1
    } else {
	variable expCollOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 0] $expCollOpts]
	set fullExpansion [expr {[string compare $opt "-fully"] == 0}]
    }

    synchronize $win
    displayItems $win

    upvar ::tablelist::ns${win}::data data
    set col $data(treeCol)

    foreach key $data(root-children) {
	if {![info exists data($key,$col-indent)] ||
	    [string match "*indented*" $data($key,$col-indent)]} {
	    continue
	}

	if {[string length $data(-expandcommand)] != 0} {
	    set data(keyBeingExpanded) $key
	    uplevel #0 $data(-expandcommand) [list $win [keyToRow $win $key]]
	    set data(keyBeingExpanded) ""
	}

	#
	# Set the indentation image to the indented or expanded one
	#
	set childCount [llength $data($key-children)]
	set state [expr {($childCount == 0) ? "indented" : "expanded"}]
	set data($key,$col-indent) [strMap \
	    [list "collapsed" $state "expanded" $state] $data($key,$col-indent)]
	if {[string compare $state "indented"] == 0} {
	    set data($key,$col-indent) [strMap \
		{"Act" "" "Sel" ""} $data($key,$col-indent)]
	}
	if {[winfo exists $data(body).ind_$key,$col]} {
	    $data(body).ind_$key,$col configure -image $data($key,$col-indent)
	}

	#
	# Unelide the children and invoke expandSubCmd on them
	#
	foreach childKey $data($key-children) {
	    set childRow [keyToRow $win $childKey]
	    doRowConfig $childRow $win -elide 0
	    if {$fullExpansion} {
		expandSubCmd $win [list $childRow -fully]
	    } elseif {[string match "*expanded*" \
		       $data($childKey,$col-indent)]} {
		expandSubCmd $win [list $childRow -partly]
	    }
	}
    }

    hdr_adjustElidedText $win
    hdr_updateColors $win
    adjustElidedText $win
    redisplayVisibleItems $win
    updateColors $win
    makeStripes $win
    adjustSepsWhenIdle $win
    updateVScrlbarWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::expandedkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::expandedkeysSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win expandedkeys"
    }

    upvar ::tablelist::ns${win}::data data
    set result {}
    foreach name [array names data "*,$data(treeCol)-indent"] {
	if {[string match "tablelist_*_expanded*Img*" $data($name)]} {
	    set commaPos [string first "," $name]
	    lappend result [string range $name 0 [expr {$commaPos - 1}]]
	}
    }
    return $result
}

#------------------------------------------------------------------------------
# tablelist::fillcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::fillcolumnSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win fillcolumn columnIndex text"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set col [colIndex $win [lindex $argList 0] 1]
    set text [lindex $argList 1]

    #
    # Update the item list
    #
    set newItemList {}
    foreach item $data(itemList) {
	set item [lreplace $item $col $col $text]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Adjust the columns and make sure the specified
    # column will be redisplayed at idle time
    #
    adjustColumns $win $col 1
    redisplayColWhenIdle $win $col
    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::findcolumnnameSubCmd
#------------------------------------------------------------------------------
proc tablelist::findcolumnnameSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win findcolumnname name"
    }

    set name [lindex $argList 0]
    set nameIsEmpty [expr {[string length $name] == 0}]

    upvar ::tablelist::ns${win}::data data
    for {set col 0} {$col < $data(colCount)} {incr col} {
	set hasName [info exists data($col-name)]
	if {($hasName && [string compare $name $data($col-name)] == 0) ||
	    (!$hasName && $nameIsEmpty)} {
	    return $col
	}
    }
    return -1
}

#------------------------------------------------------------------------------
# tablelist::findrownameSubCmd
#------------------------------------------------------------------------------
proc tablelist::findrownameSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1} {
	mwutil::wrongNumArgs \
		"$win findrowname name ?-descend? ?-parent nodeIndex?"
    }

    synchronize $win
    set name [lindex $argList 0]
    set nameIsEmpty [expr {[string length $name] == 0}]

    #
    # Initialize some processing parameters
    #
    set parentKey root
    set descend 0						;# boolean

    #
    # Parse the argument list
    #
    variable findOpts
    for {set n 1} {$n < $argCount} {incr n} {
	set arg [lindex $argList $n]
	set opt [mwutil::fullOpt "option" $arg $findOpts]
	switch -- $opt {
	    -descend { set descend 1 }
	    -parent {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set parentKey [nodeIndexToKey $win [lindex $argList $n]]
	    }
	}
    }

    upvar ::tablelist::ns${win}::data data
    set childCount [llength $data($parentKey-children)]
    if {$childCount == 0} {
	return -1
    }

    if {$descend} {
	set fromChildKey [lindex $data($parentKey-children) 0]
	set fromRow [keyToRow $win $fromChildKey]
	set toRow [nodeRow $win $parentKey end]
	for {set row $fromRow} {$row < $toRow} {incr row} {
	    set key [lindex $data(keyList) $row]
	    set hasName [info exists data($key-name)]
	    if {($hasName && [string compare $name $data($key-name)] == 0) ||
		(!$hasName && $nameIsEmpty)} {
		return $row
	    }
	}
    } else {
	for {set childIdx 0} {$childIdx < $childCount} {incr childIdx} {
	    set key [lindex $data($parentKey-children) $childIdx]
	    set hasName [info exists data($key-name)]
	    if {($hasName && [string compare $name $data($key-name)] == 0) ||
		(!$hasName && $nameIsEmpty)} {
		return [keyToRow $win $key]
	    }
	}
    }
    return -1
}

#------------------------------------------------------------------------------
# tablelist::finisheditingSubCmd
#------------------------------------------------------------------------------
proc tablelist::finisheditingSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win finishediting"
    }

    synchronize $win
    return [doFinishEditing $win]
}

#------------------------------------------------------------------------------
# tablelist::formatinfoSubCmd
#------------------------------------------------------------------------------
proc tablelist::formatinfoSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win formatinfo"
    }

    upvar ::tablelist::ns${win}::data data
    return [list $data(fmtKey) $data(fmtRow) $data(fmtCol)]
}

#------------------------------------------------------------------------------
# tablelist::getSubCmd
#------------------------------------------------------------------------------
proc tablelist::getSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win get firstIndex lastIndex" "$win get indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified items from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		set item [lindex $data(itemList) $row]
		lappend result [lrange $item 0 $data(lastCol)]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	foreach item [lrange $data(itemList) $first $last] {
	    lappend result [lrange $item 0 $data(lastCol)]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getcellsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getcells firstCellIndex lastCellIndex" \
		"$win getcells cellIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified elements from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    foreach {row col} [cellIndex $win $elem 1] {}
	    lappend result [lindex [lindex $data(itemList) $row] $col]
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	foreach {firstRow firstCol} [cellIndex $win $first 1] {}
	foreach {lastRow lastCol} [cellIndex $win [lindex $argList 1] 1] {}

	foreach item [lrange $data(itemList) $firstRow $lastRow] {
	    foreach elem [lrange $item $firstCol $lastCol] {
		lappend result $elem
	    }
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getcolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getcolumns firstColumn lastColumn" \
		"$win getcolumns columnIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified columns from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set colResult {}
	    foreach item $data(itemList) {
		lappend colResult [lindex $item $col]
	    }
	    lappend result $colResult
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set colResult {}
	    foreach item $data(itemList) {
		lappend colResult [lindex $item $col]
	    }
	    lappend result $colResult
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getformattedSubCmd
#------------------------------------------------------------------------------
proc tablelist::getformattedSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getformatted firstIndex lastIndex" \
		"$win getformatted indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified items from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		set item [lindex $data(itemList) $row]
		set key [lindex $item end]
		set item [lrange $item 0 $data(lastCol)]
		lappend result [formatItem $win $key $row $item]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	set row $first
	foreach item [lrange $data(itemList) $first $last] {
	    set key [lindex $item end]
	    set item [lrange $item 0 $data(lastCol)]
	    lappend result [formatItem $win $key $row $item]
	    incr row
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getformattedcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getformattedcellsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getformattedcells firstCellIndex lastCellIndex" \
		"$win getformattedcells cellIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified elements from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    foreach {row col} [cellIndex $win $elem 1] {}
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    lappend result $text
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	foreach {firstRow firstCol} [cellIndex $win $first 1] {}
	foreach {lastRow lastCol} [cellIndex $win [lindex $argList 1] 1] {}

	set row $firstRow
	foreach item [lrange $data(itemList) $firstRow $lastRow] {
	    set key [lindex $item end]
	    set col $firstCol
	    foreach text [lrange $item $firstCol $lastCol] {
		if {[lindex $data(fmtCmdFlagList) $col]} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend result $text
		incr col
	    }
	    incr row
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getformattedcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::getformattedcolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getformattedcolumns firstColumn lastColumn" \
		"$win getformattedcolumns columnIndexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified columns from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    set colResult {}
	    set row 0
	    foreach item $data(itemList) {
		set key [lindex $item end]
		set text [lindex $item $col]
		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend colResult $text
		incr row
	    }
	    lappend result $colResult
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    set colResult {}
	    set row 0
	    foreach item $data(itemList) {
		set key [lindex $item end]
		set text [lindex $item $col]
		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend colResult $text
		incr row
	    }
	    lappend result $colResult
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getfullkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::getfullkeysSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getfullkeys firstIndex lastIndex" \
		"$win getfullkeys indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified keys from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		lappend result [lindex [lindex $data(itemList) $row] end]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	foreach item [lrange $data(itemList) $first $last] {
	    lappend result [lindex $item end]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::getkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::getkeysSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win getkeys firstIndex lastIndex" "$win getkeys indexList"
    }

    synchronize $win
    set first [lindex $argList 0]

    #
    # Get the specified keys from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(itemCount)} {
		set item [lindex $data(itemList) $row]
		lappend result [string range [lindex $item end] 1 end]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [rowIndex $win $first 0]
	set last [rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(lastRow)} {
	    set last $data(lastRow)
	}

	foreach item [lrange $data(itemList) $first $last] {
	    lappend result [string range [lindex $item end] 1 end]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::hasattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hasattribSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win hasattrib name"
    }

    return [mwutil::hasattribSubCmd $win "widget" [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::hascellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hascellattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win hascellattrib cellIndex name"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::hasattribSubCmd $win $key,$col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::hascolumnattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hascolumnattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win hascolumnattrib columnIndex name"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::hasattribSubCmd $win $col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::hasrowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::hasrowattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win hasrowattrib index name"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::hasattribSubCmd $win $key [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::headerSubCmd
#------------------------------------------------------------------------------
proc tablelist::headerSubCmd {win argList} {
    if {[llength $argList] == 0} {
	mwutil::wrongNumArgs "$win header option ?arg arg ...?"
    }

    variable headerOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $headerOpts]
    return [header_${opt}SubCmd $win [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::header_bboxSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_bboxSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header bbox headerIndex"
    }

    set index [hdr_rowIndex $win [lindex $argList 0] 0]

    upvar ::tablelist::ns${win}::data data
    set w $data(hdrTxt)
    set dlineinfo [$w dlineinfo [expr {$index + 2}].0]
    if {$data(hdr_itemCount) == 0 || [llength $dlineinfo] == 0} {
	return {}
    }

    set spacing1 [$w cget -spacing1]
    set spacing3 [$w cget -spacing3]
    foreach {x y width height baselinePos} $dlineinfo {}
    incr height -[expr {$spacing1 + $spacing3}]
    if {$height < 0} {
	set height 0
    }
    return [list [expr {$x + [winfo x $w]}] \
		 [expr {$y + [winfo y $w] + $spacing1}] $width $height]
}

#------------------------------------------------------------------------------
# tablelist::header_cellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_cellattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win header cellattrib headerCellIndex ?name? ?value\
		 name value ...?"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    return [mwutil::attribSubCmd $win $key,$col [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::header_cellbboxSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_cellbboxSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header cellbbox headerCellIndex"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 0] {}
    upvar ::tablelist::ns${win}::data data
    if {$row < 0 || $row > $data(hdr_lastRow) ||
	$col < 0 || $col > $data(lastCol)} {
	return {}
    }

    foreach {x y width height} [header_bboxSubCmd $win $row] {}
    set w $data(hdrTxtFrmLbl)$col
    return [list [expr {[winfo rootx $w] - [winfo rootx $win]}] $y \
		 [winfo width $w] $height]
}

#------------------------------------------------------------------------------
# tablelist::header_cellcgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_cellcgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header cellcget headerCellIndex option"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    variable hdr_cellConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] hdr_cellConfigSpecs]
    return [doCellCget h$row $col $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::header_cellconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_cellconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win header cellconfigure headerCellIndex ?option? ?value\
		 option value ...?"
    }

    variable hdr_cellConfigSpecs
    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    return [mwutil::configureSubCmd $win hdr_cellConfigSpecs \
	    "tablelist::doCellConfig h$row $col" \
	    "tablelist::doCellCget h$row $col" [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::header_cellindexSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_cellindexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header cellindex headerCellIndex"
    }

    return [join [hdr_cellIndex $win [lindex $argList 0] 0] ","]
}

#------------------------------------------------------------------------------
# tablelist::header_configcelllistSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_configcelllistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs \
		"$win header configcelllist headerCellConfigSpecList"
    }

    return [header_configcellsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::header_configcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_configcellsSubCmd {win argList} {
    variable hdr_cellConfigSpecs

    set argCount [llength $argList]
    foreach {cell opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$cell\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	foreach {row col} [hdr_cellIndex $win $cell 1] {}
	mwutil::configureWidget $win hdr_cellConfigSpecs \
		"tablelist::doCellConfig h$row $col" \
		"tablelist::doCellCget h$row $col" [list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::header_configrowlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_configrowlistSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header configrowlist headerRowConfigSpecList"
    }

    return [header_configrowsSubCmd $win [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::header_configrowsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_configrowsSubCmd {win argList} {
    variable hdr_rowConfigSpecs

    set argCount [llength $argList]
    foreach {rowSpec opt val} $argList {
	if {$argCount == 1} {
	    return -code error "option and value for \"$rowSpec\" missing"
	} elseif {$argCount == 2} {
	    return -code error "value for \"$opt\" missing"
	}
	set row [hdr_rowIndex $win $rowSpec 0 1]
	mwutil::configureWidget $win hdr_rowConfigSpecs \
		"tablelist::doRowConfig h$row" "tablelist::doRowCget $row" \
		[list $opt $val] 0
	incr argCount -3
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::header_containingSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_containingSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header containing y"
    }

    set y [format "%d" [lindex $argList 0]]
    return [hdr_containingRow $win $y]
}

#------------------------------------------------------------------------------
# tablelist::header_containingcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_containingcellSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header containingcell x y"
    }

    set x [format "%d" [lindex $argList 0]]
    set y [format "%d" [lindex $argList 1]]
    return [hdr_containingRow $win $y],[containingCol $win $x]
}

#------------------------------------------------------------------------------
# tablelist::header_deleteSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_deleteSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header delete firstHeaderIndex lastHeaderIndex" \
		"$win header delete headerIndexList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    set first [lindex $argList 0]

    if {$argCount == 1} {
	if {[llength $first] == 1} {		;# just to save time
	    set index [hdr_rowIndex $win [lindex $first 0] 0]
	    return [hdr_deleteRows $win $index $index]
	} elseif {$data(hdr_itemCount) == 0} {	;# no header items present
	    return ""
	} else {				;# a bit more work
	    #
	    # Sort the numerical equivalents of the
	    # specified indices in decreasing order
	    #
	    set indexList {}
	    foreach elem $first {
		set index [hdr_rowIndex $win $elem 0]
		if {$index < 0} {
		    set index 0
		} elseif {$index > $data(hdr_lastRow)} {
		    set index $data(hdr_lastRow)
		}
		lappend indexList $index
	    }
	    set indexList [lsort -integer -decreasing $indexList]

	    #
	    # Traverse the sorted index list and ignore any duplicates
	    #
	    set prevIndex -1
	    foreach index $indexList {
		if {$index != $prevIndex} {
		    hdr_deleteRows $win $index $index
		    set prevIndex $index
		}
	    }
	    return ""
	}
    } else {
	set first [hdr_rowIndex $win $first 0]
	set last [hdr_rowIndex $win [lindex $argList 1] 0]
	return [hdr_deleteRows $win $first $last]
    }
}

#------------------------------------------------------------------------------
# tablelist::header_embedcheckbuttonSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_embedcheckbuttonSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header embedcheckbutton headerCellIndex ?command?"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    doCellConfig h$row $col $win -window \
		 [list ::tablelist::hdr_createFrameWithCheckbutton $cmd]
    return ""
}

#------------------------------------------------------------------------------
# tablelist::header_embedcheckbuttonsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_embedcheckbuttonsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header embedcheckbuttons columnIndex ?command?"
    }

    set col [colIndex $win [lindex $argList 0] 1]

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    upvar ::tablelist::ns${win}::data data
    for {set row 0} {$row < $data(hdr_itemCount)} {incr row} {
	doCellConfig h$row $col $win -window \
		     [list ::tablelist::hdr_createFrameWithCheckbutton $cmd]
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::header_embedttkcheckbuttonSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_embedttkcheckbuttonSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header embedttkcheckbutton headerCellIndex ?command?"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    doCellConfig h$row $col $win -window \
		 [list ::tablelist::hdr_createFrameWithTileCheckbutton $cmd]
    return ""
}

#------------------------------------------------------------------------------
# tablelist::header_embedttkcheckbuttonsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_embedttkcheckbuttonsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header embedttkcheckbuttons columnIndex ?command?"
    }

    set col [colIndex $win [lindex $argList 0] 1]

    if {$argCount == 1} {
	set cmd ""
    } else {
	set cmd [lindex $argList 1]
    }

    upvar ::tablelist::ns${win}::data data
    for {set row 0} {$row < $data(hdr_itemCount)} {incr row} {
	doCellConfig h$row $col $win -window \
		     [list ::tablelist::hdr_createFrameWithTileCheckbutton $cmd]
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::header_fillcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_fillcolumnSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header fillcolumn columnIndex text"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    set col [colIndex $win [lindex $argList 0] 1]
    set text [lindex $argList 1]

    #
    # Update the item list
    #
    set hdr_newItemList {}
    foreach item $data(hdr_itemList) {
	set item [lreplace $item $col $col $text]
	lappend hdr_newItemList $item
    }
    set data(hdr_itemList) $hdr_newItemList

    #
    # Adjust the columns and make sure the specified
    # column will be redisplayed at idle time
    #
    adjustColumns $win $col 1
    redisplayColWhenIdle $win $col
    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::header_findrownameSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_findrownameSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header findrowname name"
    }

    set name [lindex $argList 0]
    set nameIsEmpty [expr {[string length $name] == 0}]

    upvar ::tablelist::ns${win}::data data
    for {set row 0} {$row < $data(hdr_itemCount)} {incr row} {
	set key [lindex $data(hdr_keyList) $row]
	set hasName [info exists data($key-name)]
	if {($hasName && [string compare $name $data($key-name)] == 0) ||
	    (!$hasName && $nameIsEmpty)} {
	    return $row
	}
    }
    return -1
}

#------------------------------------------------------------------------------
# tablelist::header_getSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header get firstHeaderIndex lastHeaderIndex" \
		"$win header get headerIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified items from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [hdr_rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(hdr_itemCount)} {
		set item [lindex $data(hdr_itemList) $row]
		lappend result [lrange $item 0 $data(lastCol)]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [hdr_rowIndex $win $first 0]
	set last [hdr_rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(hdr_lastRow)} {
	    set last $data(hdr_lastRow)
	}

	foreach item [lrange $data(hdr_itemList) $first $last] {
	    lappend result [lrange $item 0 $data(lastCol)]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_getcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getcellsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header getcells firstHeaderCell lastHeaderCell" \
		"$win header getcells headerCellIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified elements from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    foreach {row col} [hdr_cellIndex $win $elem 1] {}
	    lappend result [lindex [lindex $data(hdr_itemList) $row] $col]
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	foreach {firstRow firstCol} [hdr_cellIndex $win $first 1] {}
	foreach {lastRow lastCol} [hdr_cellIndex $win [lindex $argList 1] 1] {}

	foreach item [lrange $data(hdr_itemList) $firstRow $lastRow] {
	    foreach elem [lrange $item $firstCol $lastCol] {
		lappend result $elem
	    }
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_getcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getcolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header getcolumns firstColumn lastColumn" \
		"$win header getcolumns columnIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified columns from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set colResult {}
	    foreach item $data(hdr_itemList) {
		lappend colResult [lindex $item $col]
	    }
	    lappend result $colResult
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set colResult {}
	    foreach item $data(hdr_itemList) {
		lappend colResult [lindex $item $col]
	    }
	    lappend result $colResult
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_getformattedSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getformattedSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header getformatted firstHeaderIndex lastHeaderIndex" \
		"$win header getformatted headerIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified items from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [hdr_rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(hdr_itemCount)} {
		set item [lindex $data(hdr_itemList) $row]
		set key [lindex $item end]
		set item [lrange $item 0 $data(lastCol)]
		lappend result [formatItem $win $key $row $item]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [hdr_rowIndex $win $first 0]
	set last [hdr_rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(hdr_lastRow)} {
	    set last $data(hdr_lastRow)
	}

	set row $first
	foreach item [lrange $data(hdr_itemList) $first $last] {
	    set key [lindex $item end]
	    set item [lrange $item 0 $data(lastCol)]
	    lappend result [formatItem $win $key $row $item]
	    incr row
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_getformattedcellsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getformattedcellsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header getformattedcells firstHeaderCell lastHeaderCell" \
		"$win header getformattedcells headerCellIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified elements from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    foreach {row col} [hdr_cellIndex $win $elem 1] {}
	    set item [lindex $data(hdr_itemList) $row]
	    set key [lindex $item end]
	    set text [lindex $item $col]
	    if {[lindex $data(fmtCmdFlagList) $col]} {
		set text [formatElem $win $key $row $col $text]
	    }
	    lappend result $text
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	foreach {firstRow firstCol} [hdr_cellIndex $win $first 1] {}
	foreach {lastRow lastCol} [hdr_cellIndex $win [lindex $argList 1] 1] {}

	set row $firstRow
	foreach item [lrange $data(hdr_itemList) $firstRow $lastRow] {
	    set key [lindex $item end]
	    set col $firstCol
	    foreach text [lrange $item $firstCol $lastCol] {
		if {[lindex $data(fmtCmdFlagList) $col]} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend result $text
		incr col
	    }
	    incr row
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_getformattedcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getformattedcolumnsSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header getformattedcolumns firstColumn lastColumn" \
		"$win header getformattedcolumns columnIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified columns from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    set colResult {}
	    set row 0
	    foreach item $data(hdr_itemList) {
		set key [lindex $item end]
		set text [lindex $item $col]
		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend colResult $text
		incr row
	    }
	    lappend result $colResult
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set fmtCmdFlag [lindex $data(fmtCmdFlagList) $col]
	    set colResult {}
	    set row 0
	    foreach item $data(hdr_itemList) {
		set key [lindex $item end]
		set text [lindex $item $col]
		if {$fmtCmdFlag} {
		    set text [formatElem $win $key $row $col $text]
		}
		lappend colResult $text
		incr row
	    }
	    lappend result $colResult
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_getfullkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getfullkeysSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header getfullkeys firstHeaderIndex lastHeaderIndex" \
		"$win header getfullkeys headerIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified keys from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [hdr_rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(hdr_itemCount)} {
		lappend result [lindex [lindex $data(hdr_itemList) $row] end]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [hdr_rowIndex $win $first 0]
	set last [hdr_rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(hdr_lastRow)} {
	    set last $data(hdr_lastRow)
	}

	foreach item [lrange $data(hdr_itemList) $first $last] {
	    lappend result [lindex $item end]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_getkeysSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_getkeysSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win header getkeys firstHeaderIndex lastHeaderIndex" \
		"$win header getkeys headerIndexList"
    }

    set first [lindex $argList 0]

    #
    # Get the specified keys from the internal list
    #
    upvar ::tablelist::ns${win}::data data
    set result {}
    if {$argCount == 1} {
	foreach elem $first {
	    set row [hdr_rowIndex $win $elem 0]
	    if {$row >= 0 && $row < $data(hdr_itemCount)} {
		set item [lindex $data(hdr_itemList) $row]
		lappend result [string range [lindex $item end] 2 end]
	    }
	}

	if {[llength $first] == 1} {
	    return [lindex $result 0]
	} else {
	    return $result
	}
    } else {
	set first [hdr_rowIndex $win $first 0]
	set last [hdr_rowIndex $win [lindex $argList 1] 0]
	if {$last < $first} {
	    return {}
	}

	#
	# Adjust the range to fit within the existing items
	#
	if {$first < 0} {
	    set first 0
	}
	if {$last > $data(hdr_lastRow)} {
	    set last $data(hdr_lastRow)
	}

	foreach item [lrange $data(hdr_itemList) $first $last] {
	    lappend result [string range [lindex $item end] 2 end]
	}
	return $result
    }
}

#------------------------------------------------------------------------------
# tablelist::header_hascellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_hascellattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header hascellattrib headerCellIndex name"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    return [mwutil::hasattribSubCmd $win $key,$col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::header_hasrowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_hasrowattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header hasrowattrib headerIndex name"
    }

    set row [hdr_rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    return [mwutil::hasattribSubCmd $win $key [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::header_imagelabelpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_imagelabelpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header imagelabelpath headerCellIndex"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    set w $data(hdrTxt).img_$key,$col
    if {[winfo exists $w]} {
	return $w
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::header_indexSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_indexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header index headerIndex"
    }

    return [hdr_rowIndex $win [lindex $argList 0] 1]
}

#------------------------------------------------------------------------------
# tablelist::header_insertSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_insertSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win header insert headerIndex ?item item ...?"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    set index [hdr_rowIndex $win [lindex $argList 0] 1]
    return [hdr_insertRows $win $index [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::header_insertlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_insertlistSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header insertlist headerIndex itemList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    set index [hdr_rowIndex $win [lindex $argList 0] 1]
    return [hdr_insertRows $win $index [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::header_iselemsnippedSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_iselemsnippedSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs \
		"$win header iselemsnipped headerCellIndex fullTextName"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    set fullTextName [lindex $argList 1]
    upvar 3 $fullTextName fullText

    upvar ::tablelist::ns${win}::data data
    set item [lindex $data(hdr_itemList) $row]
    set key [lindex $item end]
    set fullText [lindex $item $col]
    if {[lindex $data(fmtCmdFlagList) $col]} {
	set fullText [formatElem $win $key $row $col $fullText]
    }
    if {[string match "*\t*" $fullText]} {
	set fullText [mapTabs $fullText]
    }

    set pixels [lindex $data(colList) [expr {2*$col}]]
    if {$pixels == 0} {				;# convention: dynamic width
	if {$data($col-maxPixels) > 0 &&
	    $data($col-reqPixels) > $data($col-maxPixels)} {
	    set pixels $data($col-maxPixels)
	}
    }
    if {$pixels == 0 || $data($col-wrap)} {
	return 0
    }

    set text $fullText
    getAuxData $win $key $col auxType auxWidth $pixels
    set indentWidth 0
    set cellFont [getCellFont $win $key $col]
    incr pixels $data($col-delta)

    if {[string match "*\n*" $text]} {
	set list [split $text "\n"]
	adjustMlElem $win list auxWidth indentWidth $cellFont $pixels "r" ""
	set text [join $list "\n"]
    } else {
	adjustElem $win text auxWidth indentWidth $cellFont $pixels "r" ""
    }

    return [expr {[string compare $text $fullText] != 0}]
}

#------------------------------------------------------------------------------
# tablelist::header_itemlistvarSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_itemlistvarSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win header itemlistvar"
    }

    return ::tablelist::ns${win}::data(hdr_itemList)
}

#------------------------------------------------------------------------------
# tablelist::header_nearestSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_nearestSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header nearest y"
    }

    set y [format "%d" [lindex $argList 0]]
    return [hdr_rowIndex $win @0,$y 0]
}

#------------------------------------------------------------------------------
# tablelist::header_nearestcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_nearestcellSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header nearestcell x y"
    }

    set x [format "%d" [lindex $argList 0]]
    set y [format "%d" [lindex $argList 1]]
    return [join [hdr_cellIndex $win @$x,$y 0] ","]
}

#------------------------------------------------------------------------------
# tablelist::header_rowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_rowattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win header rowattrib headerIndex ?name? ?value\
		 name value ...?"
    }

    set row [hdr_rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    return [mwutil::attribSubCmd $win $key [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::header_rowcgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_rowcgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header rowcget headerIndex option"
    }

    set row [hdr_rowIndex $win [lindex $argList 0] 0 1]
    variable hdr_rowConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] hdr_rowConfigSpecs]
    return [doRowCget h$row $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::header_rowconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_rowconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win header rowconfigure headerIndex ?option? ?value\
		 option value ...?"
    }

    variable hdr_rowConfigSpecs
    set row [hdr_rowIndex $win [lindex $argList 0] 0 1]
    return [mwutil::configureSubCmd $win hdr_rowConfigSpecs \
	    "tablelist::doRowConfig h$row" "tablelist::doRowCget h$row" \
	    [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::header_sizeSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_sizeSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win header size"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(hdr_itemCount)
}

#------------------------------------------------------------------------------
# tablelist::header_unsetcellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_unsetcellattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header unsetcellattrib headerCellIndex name"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    return [mwutil::unsetattribSubCmd $win $key,$col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::header_unsetrowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_unsetrowattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win header unsetrowattrib headerIndex name"
    }

    set row [hdr_rowIndex $win [lindex $argList 0] 0]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    return [mwutil::unsetattribSubCmd $win $key [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::header_windowpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::header_windowpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win header windowpath headerCellIndex"
    }

    foreach {row col} [hdr_cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(hdr_keyList) $row]
    set w $data(hdrTxt).frm_$key,$col.w
    if {[winfo exists $w]} {
	return $w
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::headerpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::headerpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win headerpath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(hdrTxt)
}

#------------------------------------------------------------------------------
# tablelist::headertagSubCmd
#------------------------------------------------------------------------------
proc tablelist::headertagSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win headertag"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(headerTag)
}

#------------------------------------------------------------------------------
# tablelist::hidetargetmarkSubCmd
#------------------------------------------------------------------------------
proc tablelist::hidetargetmarkSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win hidetargetmark"
    }

    upvar ::tablelist::ns${win}::data data
    place forget $data(rowGap)
    return ""
}

#------------------------------------------------------------------------------
# tablelist::imagelabelpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::imagelabelpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win imagelabelpath cellIndex"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set w $data(body).img_$key,$col
    if {[winfo exists $w]} {
	return $w
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::indexSubCmd
#------------------------------------------------------------------------------
proc tablelist::indexSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win index index"
    }

    synchronize $win
    return [rowIndex $win [lindex $argList 0] 1]
}

#------------------------------------------------------------------------------
# tablelist::insertSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs "$win insert index ?item item ...?"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    set index [rowIndex $win [lindex $argList 0] 1]
    return [insertRows $win $index [lrange $argList 1 end] \
	    $data(hasListVar) root $index]
}

#------------------------------------------------------------------------------
# tablelist::insertchildlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertchildlistSubCmd {win argList} {
    if {[llength $argList] != 3} {
	mwutil::wrongNumArgs \
		"$win insertchildlist parentNodeIndex childIndex itemList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    set parentKey [nodeIndexToKey $win [lindex $argList 0]]
    set childIdx [lindex $argList 1]
    set listIdx [nodeRow $win $parentKey $childIdx]
    set itemList [lindex $argList 2]
    set result [insertRows $win $listIdx $itemList $data(hasListVar) \
		$parentKey $childIdx]

    if {$data(colCount) == 0} {
	return $result
    }

    displayItems $win
    set treeCol $data(treeCol)
    set treeStyle $data(-treestyle)

    #
    # Mark the parent item as expanded if it was just indented
    #
    set depth [depth $win $parentKey]
    if {[info exists data($parentKey,$treeCol-indent)] &&
	[string compare $data($parentKey,$treeCol-indent) \
	 tablelist_${treeStyle}_indentedImg$depth] == 0} {
	set data($parentKey,$treeCol-indent) \
	    tablelist_${treeStyle}_expandedImg$depth
	if {[winfo exists $data(body).ind_$parentKey,$treeCol]} {
	    $data(body).ind_$parentKey,$treeCol configure -image \
		$data($parentKey,$treeCol-indent)
	}
    }

    #
    # Elide the new items if the parent is collapsed or non-viewable
    #
    set itemCount [llength $itemList]
    if {[string compare $parentKey $data(keyBeingExpanded)] != 0 &&
	(([info exists data($parentKey,$treeCol-indent)] && \
	  [string compare $data($parentKey,$treeCol-indent) \
	   tablelist_${treeStyle}_collapsedImg$depth] == 0) || \
	 [info exists data($parentKey-elide)] || \
	 [info exists data($parentKey-hide)])} {
	for {set n 0; set row $listIdx} {$n < $itemCount} {incr n; incr row} {
	    doRowConfig $row $win -elide 1
	}
    }

    #
    # Mark the new items as indented
    #
    incr depth
    variable maxIndentDepths
    if {$depth > $maxIndentDepths($treeStyle)} {
	createTreeImgs $treeStyle $depth
	set maxIndentDepths($treeStyle) $depth
    }
    for {set n 0; set row $listIdx} {$n < $itemCount} {incr n; incr row} {
	doCellConfig $row $treeCol $win -indent \
		     tablelist_${treeStyle}_indentedImg$depth
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::insertchildrenSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertchildrenSubCmd {win argList} {
    if {[llength $argList] < 2} {
	mwutil::wrongNumArgs \
		"$win insertchildren parentNodeIndex childIndex ?item item ...?"
    }

    return [insertchildlistSubCmd $win [list [lindex $argList 0] \
	    [lindex $argList 1] [lrange $argList 2 end]]]
}

#------------------------------------------------------------------------------
# tablelist::insertcolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertcolumnlistSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win insertcolumnlist columnIndex columnList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set arg0 [lindex $argList 0]
    if {[string first $arg0 "end"] == 0 || $arg0 == $data(colCount)} {
	set col $data(colCount)
    } else {
	set col [colIndex $win $arg0 1]
    }

    return [insertCols $win $col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::insertcolumnsSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertcolumnsSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win insertcolumns columnIndex ?width title ?alignment?\
		 width title ?alignment? ...?"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    displayItems $win
    set arg0 [lindex $argList 0]
    if {[string first $arg0 "end"] == 0 || $arg0 == $data(colCount)} {
	set col $data(colCount)
    } else {
	set col [colIndex $win $arg0 1]
    }

    return [insertCols $win $col [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::insertlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::insertlistSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win insertlist index itemList"
    }

    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled)} {
	return ""
    }

    synchronize $win
    set index [rowIndex $win [lindex $argList 0] 1]
    return [insertRows $win $index [lindex $argList 1] \
	    $data(hasListVar) root $index]
}

#------------------------------------------------------------------------------
# tablelist::iselemsnippedSubCmd
#------------------------------------------------------------------------------
proc tablelist::iselemsnippedSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win iselemsnipped cellIndex fullTextName"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    set fullTextName [lindex $argList 1]
    upvar 2 $fullTextName fullText

    upvar ::tablelist::ns${win}::data data
    set item [lindex $data(itemList) $row]
    set key [lindex $item end]
    set fullText [lindex $item $col]
    if {[lindex $data(fmtCmdFlagList) $col]} {
	set fullText [formatElem $win $key $row $col $fullText]
    }
    if {[string match "*\t*" $fullText]} {
	set fullText [mapTabs $fullText]
    }

    set pixels [lindex $data(colList) [expr {2*$col}]]
    if {$pixels == 0} {				;# convention: dynamic width
	if {$data($col-maxPixels) > 0 &&
	    $data($col-reqPixels) > $data($col-maxPixels)} {
	    set pixels $data($col-maxPixels)
	}
    }
    if {$pixels == 0 || $data($col-wrap)} {
	return 0
    }

    set text $fullText
    getAuxData $win $key $col auxType auxWidth $pixels
    getIndentData $win $key $col indentWidth
    set cellFont [getCellFont $win $key $col]
    incr pixels $data($col-delta)

    if {[string match "*\n*" $text]} {
	set list [split $text "\n"]
	adjustMlElem $win list auxWidth indentWidth $cellFont $pixels "r" ""
	set text [join $list "\n"]
    } else {
	adjustElem $win text auxWidth indentWidth $cellFont $pixels "r" ""
    }

    return [expr {[string compare $text $fullText] != 0}]
}

#------------------------------------------------------------------------------
# tablelist::isexpandedSubCmd
#------------------------------------------------------------------------------
proc tablelist::isexpandedSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win isexpanded index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set treeCol $data(treeCol)
    if {[info exists data($key,$treeCol-indent)]} {
	return [string match "*expanded*" $data($key,$treeCol-indent)]
    } else {
	return 0
    }
}

#------------------------------------------------------------------------------
# tablelist::istitlesnippedSubCmd
#------------------------------------------------------------------------------
proc tablelist::istitlesnippedSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win istitlesnipped columnIndex fullTextName"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    set fullTextName [lindex $argList 1]
    upvar 2 $fullTextName fullText

    upvar ::tablelist::ns${win}::data data
    set fullText [lindex $data(-columns) [expr {3*$col + 1}]]
    return $data($col-isSnipped)
}

#------------------------------------------------------------------------------
# tablelist::isviewableSubCmd
#------------------------------------------------------------------------------
proc tablelist::isviewableSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win isviewable index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    return [isRowViewable $win $row]
}

#------------------------------------------------------------------------------
# tablelist::itemlistvarSubCmd
#------------------------------------------------------------------------------
proc tablelist::itemlistvarSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win itemlistvar"
    }

    return ::tablelist::ns${win}::data(itemList)
}

#------------------------------------------------------------------------------
# tablelist::itemtodictSubCmd
#------------------------------------------------------------------------------
proc tablelist::itemtodictSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win itemtodict item"
    }

    set item [lindex $argList 0]
    set dictionary {}
    upvar ::tablelist::ns${win}::data data
    for {set col 0} {$col < $data(colCount)} {incr col} {
	if {[info exists data($col-name)]} {
	    set key $data($col-name)
	} else {
	    set key $col
	}
	dict set dictionary $key [lindex $item $col]
    }
    return $dictionary
}

#------------------------------------------------------------------------------
# tablelist::labelpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::labelpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win labelpath columnIndex"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    upvar ::tablelist::ns${win}::data data
    return $data(hdrTxtFrmLbl)$col
}

#------------------------------------------------------------------------------
# tablelist::labelsSubCmd
#------------------------------------------------------------------------------
proc tablelist::labelsSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win labels"
    }

    upvar ::tablelist::ns${win}::data data
    set labelList {}
    for {set col 0} {$col < $data(colCount)} {incr col} {
	lappend labelList $data(hdrTxtFrmLbl)$col
    }
    return $labelList
}

#------------------------------------------------------------------------------
# tablelist::labeltagSubCmd
#------------------------------------------------------------------------------
proc tablelist::labeltagSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win labeltag"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(labelTag)
}

#------------------------------------------------------------------------------
# tablelist::moveSubCmd
#------------------------------------------------------------------------------
proc tablelist::moveSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2 || $argCount > 3} {
	mwutil::wrongNumArgs \
		"$win move sourceIndex targetIndex" \
		"$win move sourceIndex targetParentNodeIndex targetChildIndex"
    }

    synchronize $win
    displayItems $win
    set source [rowIndex $win [lindex $argList 0] 0]
    if {$argCount == 2} {
	set target [rowIndex $win [lindex $argList 1] 1]
	return [moveRow $win $source $target]
    } else {
	set targetParentKey [nodeIndexToKey $win [lindex $argList 1]]
	set targetChildIdx [lindex $argList 2]
	return [moveNode $win $source $targetParentKey $targetChildIdx]
    }
}

#------------------------------------------------------------------------------
# tablelist::movecolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::movecolumnSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs \
		"$win movecolumn sourceColumnIndex targetColumnIndex"
    }

    synchronize $win
    displayItems $win
    set arg0 [lindex $argList 0]
    set source [colIndex $win $arg0 1]
    set arg1 [lindex $argList 1]
    upvar ::tablelist::ns${win}::data data
    if {[string first $arg1 "end"] == 0 || $arg1 == $data(colCount)} {
	set target $data(colCount)
    } else {
	set target [colIndex $win $arg1 1]
    }

    return [moveCol $win $source $target]
}

#------------------------------------------------------------------------------
# tablelist::nearestSubCmd
#------------------------------------------------------------------------------
proc tablelist::nearestSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win nearest y"
    }

    set y [format "%d" [lindex $argList 0]]
    synchronize $win
    displayItems $win
    return [rowIndex $win @0,$y 0]
}

#------------------------------------------------------------------------------
# tablelist::nearestcellSubCmd
#------------------------------------------------------------------------------
proc tablelist::nearestcellSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win nearestcell x y"
    }

    set x [format "%d" [lindex $argList 0]]
    set y [format "%d" [lindex $argList 1]]
    synchronize $win
    displayItems $win
    return [join [cellIndex $win @$x,$y 0] ","]
}

#------------------------------------------------------------------------------
# tablelist::nearestcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::nearestcolumnSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win nearestcolumn x"
    }

    set x [format "%d" [lindex $argList 0]]
    return [colIndex $win @$x,0 0]
}

#------------------------------------------------------------------------------
# tablelist::noderowSubCmd
#------------------------------------------------------------------------------
proc tablelist::noderowSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win noderow parentNodeIndex childIndex"
    }

    synchronize $win
    set parentKey [nodeIndexToKey $win [lindex $argList 0]]
    set childIdx [lindex $argList 1]
    return [nodeRow $win $parentKey $childIdx]
}

#------------------------------------------------------------------------------
# tablelist::parentkeySubCmd
#------------------------------------------------------------------------------
proc tablelist::parentkeySubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win parentkey nodeIndex"
    }

    synchronize $win
    set key [nodeIndexToKey $win [lindex $argList 0]]
    upvar ::tablelist::ns${win}::data data
    return $data($key-parent)
}

#------------------------------------------------------------------------------
# tablelist::refreshsortingSubCmd
#------------------------------------------------------------------------------
proc tablelist::refreshsortingSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win refreshsorting ?parentNodeIndex?"
    }

    synchronize $win
    displayItems $win
    if {$argCount == 0} {
	set parentKey root
    } else {
	set parentKey [nodeIndexToKey $win [lindex $argList 0]]
    }

    upvar ::tablelist::ns${win}::data data
    set sortOrderList {}
    foreach col $data(sortColList) {
	lappend sortOrderList $data($col-sortOrder)
    }

    return [sortItems $win $parentKey $data(sortColList) $sortOrderList]
}

#------------------------------------------------------------------------------
# tablelist::rejectinputSubCmd
#------------------------------------------------------------------------------
proc tablelist::rejectinputSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win rejectinput"
    }

    upvar ::tablelist::ns${win}::data data
    set data(rejected) 1
    return ""
}

#------------------------------------------------------------------------------
# tablelist::resetsortinfoSubCmd
#------------------------------------------------------------------------------
proc tablelist::resetsortinfoSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win resetsortinfo"
    }

    upvar ::tablelist::ns${win}::data data

    foreach col $data(sortColList) {
	set data($col-sortRank) 0
	set data($col-sortOrder) ""
    }

    set whichWidths {}
    foreach col $data(arrowColList) {
	lappend whichWidths l$col
    }

    set data(sortColList) {}
    set data(arrowColList) {}
    set data(sortOrder) {}

    if {[llength $whichWidths] > 0} {
	synchronize $win
	displayItems $win
	adjustColumns $win $whichWidths 1
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::rowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::rowattribSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win rowattrib index ?name? ?value name value ...?"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::attribSubCmd $win $key [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::rowcgetSubCmd
#------------------------------------------------------------------------------
proc tablelist::rowcgetSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win rowcget index option"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    variable rowConfigSpecs
    set opt [mwutil::fullConfigOpt [lindex $argList 1] rowConfigSpecs]
    return [doRowCget $row $win $opt]
}

#------------------------------------------------------------------------------
# tablelist::rowconfigureSubCmd
#------------------------------------------------------------------------------
proc tablelist::rowconfigureSubCmd {win argList} {
    if {[llength $argList] < 1} {
	mwutil::wrongNumArgs \
		"$win rowconfigure index ?option? ?value option value ...?"
    }

    synchronize $win
    displayItems $win
    variable rowConfigSpecs
    set row [rowIndex $win [lindex $argList 0] 0 1]
    return [mwutil::configureSubCmd $win rowConfigSpecs \
	    "tablelist::doRowConfig $row" "tablelist::doRowCget $row" \
	    [lrange $argList 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::scanSubCmd
#------------------------------------------------------------------------------
proc tablelist::scanSubCmd {win argList} {
    if {[llength $argList] != 3} {
	mwutil::wrongNumArgs "$win scan mark|dragto x y"
    }

    set x [format "%d" [lindex $argList 1]]
    set y [format "%d" [lindex $argList 2]]
    variable scanOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $scanOpts]
    synchronize $win
    displayItems $win
    return [doScan $win $opt $x $y]
}

#------------------------------------------------------------------------------
# tablelist::searchcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::searchcolumnSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2} {
	mwutil::wrongNumArgs "$win searchcolumn columnIndex pattern ?options?"
    }

    synchronize $win
    set col [colIndex $win [lindex $argList 0] 1]
    set pattern [lindex $argList 1]

    #
    # Initialize some processing parameters
    #
    set mode -glob		;# possible values: -exact, -glob, -regexp
    set checkCmd ""
    set parentKey root
    set allMatches 0						;# boolean
    set backwards 0						;# boolean
    set descend 0						;# boolean
    set formatted 0						;# boolean
    set noCase 0						;# boolean
    set negated 0						;# boolean
    set numeric 0						;# boolean
    set gotStartRow 0						;# boolean

    #
    # Parse the argument list
    #
    variable searchOpts
    for {set n 2} {$n < $argCount} {incr n} {
	set arg [lindex $argList $n]
	set opt [mwutil::fullOpt "option" $arg $searchOpts]
	switch -- $opt {
	    -all	{ set allMatches 1}
	    -backwards	{ set backwards 1 }
	    -check {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set checkCmd [lindex $argList $n]
	    }
	    -descend	{ set descend 1 }
	    -exact	{ set mode -exact }
	    -formatted	{ set formatted 1 }
	    -glob	{ set mode -glob }
	    -nocase	{ set noCase 1 }
	    -not	{ set negated 1 }
	    -numeric	{ set numeric 1 }
	    -parent {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set parentKey [nodeIndexToKey $win [lindex $argList $n]]
	    }
	    -regexp	{ set mode -regexp }
	    -start {
		if {$n == $argCount - 1} {
		    return -code error "value for \"$arg\" missing"
		}

		incr n
		set startRow [rowIndex $win [lindex $argList $n] 0]
		set gotStartRow 1
	    }
	}
    }

    if {([string compare $mode "-exact"] == 0 && !$numeric && $noCase) ||
	([string compare $mode "-glob"] == 0 && $noCase)} {
	set pattern [string tolower $pattern]
    }

    upvar ::tablelist::ns${win}::data data
    if {[string length $data(-populatecommand)] != 0} {
	#
	# Populate the relevant subtree(s) if necessary
	#
	if {[string compare $parentKey "root"] == 0} {
	    if {$descend} {
		for {set row 0} {$row < $data(itemCount)} {incr row} {
		    populate $win $row 1
		}
	    }
	} else {
	    populate $win [keyToRow $win $parentKey] $descend
	}
    }

    #
    # Build the list of row indices of the matching elements
    #
    set rowList {}
    set useFormatCmd [expr {$formatted && [lindex $data(fmtCmdFlagList) $col]}]
    set childCount [llength $data($parentKey-children)]
    if {$childCount != 0} {
	if {$backwards} {
	    set childIdx [expr {$childCount - 1}]
	    if {$descend} {
		set childKey [lindex $data($parentKey-children) $childIdx]
		set maxRow [expr {[nodeRow $win $childKey end] - 1}]
		if {$gotStartRow && $maxRow > $startRow} {
		    set maxRow $startRow
		}
		set minRow [nodeRow $win $parentKey 0]
		for {set row $maxRow} {$row >= $minRow} {incr row -1} {
		    set item [lindex $data(itemList) $row]
		    set elem [lindex $item $col]
		    if {$useFormatCmd} {
			set key [lindex $item end]
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    } else {
		for {} {$childIdx >= 0} {incr childIdx -1} {
		    set key [lindex $data($parentKey-children) $childIdx]
		    set row [keyToRow $win $key]
		    if {$gotStartRow && $row > $startRow} {
			continue
		    }
		    set elem [lindex [lindex $data(itemList) $row] $col]
		    if {$useFormatCmd} {
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    }
	} else {
	    set childIdx 0
	    if {$descend} {
		set childKey [lindex $data($parentKey-children) $childIdx]
		set fromRow [keyToRow $win $childKey]
		if {$gotStartRow && $fromRow < $startRow} {
		    set fromRow $startRow
		}
		set toRow [nodeRow $win $parentKey end]
		for {set row $fromRow} {$row < $toRow} {incr row} {
		    set item [lindex $data(itemList) $row]
		    set elem [lindex $item $col]
		    if {$useFormatCmd} {
			set key [lindex $item end]
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    } else {
		for {} {$childIdx < $childCount} {incr childIdx} {
		    set key [lindex $data($parentKey-children) $childIdx]
		    set row [keyToRow $win $key]
		    if {$gotStartRow && $row < $startRow} {
			continue
		    }
		    set elem [lindex [lindex $data(itemList) $row] $col]
		    if {$useFormatCmd} {
			set elem [formatElem $win $key $row $col $elem]
		    }
		    if {[doesMatch $win $row $col $pattern $elem $mode \
			 $numeric $noCase $checkCmd] != $negated} {
			lappend rowList $row
			if {!$allMatches} {
			    break
			}
		    }
		}
	    }
	}
    }

    if {$allMatches} {
	return $rowList
    } elseif {[llength $rowList] == 0} {
	return -1
    } else {
	return [lindex $rowList 0]
    }
}

#------------------------------------------------------------------------------
# tablelist::seeSubCmd
#------------------------------------------------------------------------------
proc tablelist::seeSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win see index"
    }

    synchronize $win
    displayItems $win
    set index [rowIndex $win [lindex $argList 0] 0]
    if {[winfo viewable $win] ||
	[llength [$win.body tag nextrange elidedWin 1.0]] == 0} {
	return [seeRow $win $index]
    } else {
	after 0 [list tablelist::seeRow $win $index]
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::seecellSubCmd
#------------------------------------------------------------------------------
proc tablelist::seecellSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win seecell cellIndex"
    }

    synchronize $win
    displayItems $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 0] {}
    if {[winfo viewable $win] &&
	[llength [$win.body tag nextrange elidedWin 1.0]] == 0} {
	return [seeCell $win $row $col]
    } else {
	after 0 [list tablelist::seeCell $win $row $col]
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::seecolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::seecolumnSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win seecolumn columnIndex"
    }

    synchronize $win
    displayItems $win
    set col [colIndex $win [lindex $argList 0] 0]
    if {[winfo viewable $win] &&
	[llength [$win.body tag nextrange elidedWin 1.0]] == 0} {
	return [seeCell $win [rowIndex $win @0,0 0] $col]
    } else {
	after 0 [list tablelist::seeCell $win [rowIndex $win @0,0 0] $col]
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::selectionSubCmd
#------------------------------------------------------------------------------
proc tablelist::selectionSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 2 || $argCount > 3} {
	mwutil::wrongNumArgs \
		"$win selection option firstIndex lastIndex" \
		"$win selection option indexList"
    }

    synchronize $win
    displayItems $win
    variable selectionOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $selectionOpts]
    set first [lindex $argList 1]

    switch $opt {
	anchor -
	includes {
	    if {$argCount != 2} {
		mwutil::wrongNumArgs "$win selection $opt index"
	    }
	    set index [rowIndex $win $first 0]
	    return [rowSelection $win $opt $index $index]
	}

	clear -
	set {
	    if {$argCount == 2} {
		foreach elem $first {
		    set index [rowIndex $win $elem 0]
		    rowSelection $win $opt $index $index
		}
	    } else {
		set first [rowIndex $win $first 0]
		set last [rowIndex $win [lindex $argList 2] 0]
		rowSelection $win $opt $first $last
	    }

	    updateColors $win
	    invokeMotionHandler $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::separatorpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::separatorpathSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win separatorpath ?columnIndex?"
    }

    upvar ::tablelist::ns${win}::data data
    if {$argCount == 0} {
	if {[winfo exists $data(vsep)]} {
	    return $data(vsep)
	} else {
	    return ""
	}
    } else {
	set col [colIndex $win [lindex $argList 0] 1]
	if {$data(-showseparators)} {
	    return $data(vsep)$col
	} else {
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::separatorsSubCmd
#------------------------------------------------------------------------------
proc tablelist::separatorsSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win separators"
    }

    set sepList {}
    foreach w [winfo children $win] {
	if {[regexp {^vsep([0-9]+)?$} [winfo name $w]]} {
	    lappend sepList $w
	}
    }
    return [lsort -dictionary $sepList]
}

#------------------------------------------------------------------------------
# tablelist::showtargetmarkSubCmd
#------------------------------------------------------------------------------
proc tablelist::showtargetmarkSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win showtargetmark before|inside index"
    }

    variable targetOpts
    set opt [mwutil::fullOpt "option" [lindex $argList 0] $targetOpts]
    set index [lindex $argList 1]

    upvar ::tablelist::ns${win}::data data
    set w $data(body)

    switch $opt {
	before {
	    set row [rowIndex $win $index 1]
	    if {$data(itemCount) == 0} {
		set y 0
	    } elseif {$row >= $data(itemCount)} {
		set dlineinfo [$w dlineinfo $data(itemCount).0]
		if {[llength $dlineinfo] == 0} {
		    return ""
		}

		set lineY [lindex $dlineinfo 1]
		set lineHeight [lindex $dlineinfo 3]
		set y [expr {$lineY + $lineHeight}]
	    } else {
		if {$row < 0} {
		    set row 0
		}
		set dlineinfo [$w dlineinfo [expr {$row + 1}].0]
		if {[llength $dlineinfo] == 0} {
		    return ""
		}

		set y [lindex $dlineinfo 1]
	    }

	    place $data(rowGap) -anchor w -y $y -height 4 \
				-width [winfo width $data(hdrTxtFrm)]
	}

	inside {
	    set row [rowIndex $win $index 0 1]
	    set dlineinfo [$w dlineinfo [expr {$row + 1}].0]
	    if {[llength $dlineinfo] == 0} {
		return ""
	    }

	    set lineY [lindex $dlineinfo 1]
	    set lineHeight [lindex $dlineinfo 3]
	    set y [expr {$lineY + $lineHeight/2}]

	    place $data(rowGap) -anchor w -y $y -height $lineHeight -width 6
	}
    }

    raise $data(rowGap)
    return ""
}

#------------------------------------------------------------------------------
# tablelist::sizeSubCmd
#------------------------------------------------------------------------------
proc tablelist::sizeSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win size"
    }

    synchronize $win
    upvar ::tablelist::ns${win}::data data
    return $data(itemCount)
}

#------------------------------------------------------------------------------
# tablelist::sortSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount > 1} {
	mwutil::wrongNumArgs "$win sort ?-increasing|-decreasing?"
    }

    if {$argCount == 0} {
	set order -increasing
    } else {
	variable sortOpts
	set order [mwutil::fullOpt "option" [lindex $argList 0] $sortOpts]
    }

    synchronize $win
    displayItems $win
    return [sortItems $win root -1 [string range $order 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::sortbycolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortbycolumnSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win sortbycolumn columnIndex ?-increasing|-decreasing?"
    }

    synchronize $win
    displayItems $win
    set col [colIndex $win [lindex $argList 0] 1]
    if {$argCount == 1} {
	set order -increasing
    } else {
	variable sortOpts
	set order [mwutil::fullOpt "option" [lindex $argList 1] $sortOpts]
    }
    return [sortItems $win root $col [string range $order 1 end]]
}

#------------------------------------------------------------------------------
# tablelist::sortbycolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortbycolumnlistSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win sortbycolumnlist columnIndexList ?sortOrderList?"
    }

    synchronize $win
    displayItems $win
    set sortColList {}
    foreach elem [lindex $argList 0] {
	set col [colIndex $win $elem 1]
	if {[lsearch -exact $sortColList $col] >= 0} {
	    return -code error "duplicate column index \"$elem\""
	}
	lappend sortColList $col
    }

    set sortOrderList {}
    if {$argCount == 2} {
	variable sortOrders
	foreach elem [lindex $argList 1] {
	    lappend sortOrderList [mwutil::fullOpt "option" $elem $sortOrders]
	}
    }

    return [sortItems $win root $sortColList $sortOrderList]
}

#------------------------------------------------------------------------------
# tablelist::sortcolumnSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortcolumnSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortcolumn"
    }

    upvar ::tablelist::ns${win}::data data
    if {[llength $data(sortColList)] == 0} {
	return -1
    } else {
	return [lindex $data(sortColList) 0]
    }
}

#------------------------------------------------------------------------------
# tablelist::sortcolumnlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortcolumnlistSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortcolumnlist"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(sortColList)
}

#------------------------------------------------------------------------------
# tablelist::sortorderSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortorderSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortorder"
    }

    upvar ::tablelist::ns${win}::data data
    if {[llength $data(sortColList)] == 0} {
	return $data(sortOrder)
    } else {
	set col [lindex $data(sortColList) 0]
	return $data($col-sortOrder)
    }
}

#------------------------------------------------------------------------------
# tablelist::sortorderlistSubCmd
#------------------------------------------------------------------------------
proc tablelist::sortorderlistSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win sortorderlist"
    }

    upvar ::tablelist::ns${win}::data data
    set sortOrderList {}
    foreach col $data(sortColList) {
	lappend sortOrderList $data($col-sortOrder)
    }
    return $sortOrderList
}

#------------------------------------------------------------------------------
# tablelist::targetmarkpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::targetmarkpathSubCmd {win argList} {
    if {[llength $argList] != 0} {
	mwutil::wrongNumArgs "$win targetmarkpath"
    }

    upvar ::tablelist::ns${win}::data data
    return $data(rowGap)
}

#------------------------------------------------------------------------------
# tablelist::targetmarkposSubCmd
#------------------------------------------------------------------------------
proc tablelist::targetmarkposSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs "$win targetmarkpos y ?-any|-horizontal|-vertical?"
    }

    set y [format "%d" [lindex $argList 0]]
    if {$argCount == 1} {
	set opt -any
    } else {
	variable gapTypeOpts
	set opt [mwutil::fullOpt "option" [lindex $argList 1] $gapTypeOpts]
    }

    synchronize $win
    displayItems $win

    switch -- $opt {
	-any {
	    set row [containingRow $win $y relOffset]
	    if {$row < 0} {
		set place before
		upvar ::tablelist::ns${win}::data data
		set row [expr {
		    ($y < [winfo y $data(body)]) ? 0 : $data(itemCount)
		}]
	    } elseif {$relOffset < 0.25} {
		set place before
	    } elseif {$relOffset < 0.75} {
		set place inside
	    } else {
		set place before
		if {[isexpandedSubCmd $win $row]} {
		    incr row
		} else {
		    #
		    # Get the containing row's next sibling
		    #
		    set childIdx [childindexSubCmd $win $row]
		    set row [noderowSubCmd $win [list \
			     [parentkeySubCmd $win $row] [incr childIdx]]]
		}
	    }

	    return [list $place $row]
	}

	-horizontal {
	    set row [containingRow $win $y relOffset]
	    if {$row < 0} {
		upvar ::tablelist::ns${win}::data data
		set row [expr {
		    ($y < [winfo y $data(body)]) ? 0 : $data(itemCount)
		}]
	    } elseif {$relOffset >= 0.5} {
		if {[isexpandedSubCmd $win $row]} {
		    incr row
		} else {
		    #
		    # Get the containing row's next sibling
		    #
		    set childIdx [childindexSubCmd $win $row]
		    set row [noderowSubCmd $win [list \
			     [parentkeySubCmd $win $row] [incr childIdx]]]
		}
	    }

	    return [list before $row]
	}

	-vertical {
	    set row [containingRow $win $y]
	    return [list inside $row]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::togglecolumnhideSubCmd
#------------------------------------------------------------------------------
proc tablelist::togglecolumnhideSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win togglecolumnhide firstColumn lastColumn" \
		"$win togglecolumnhide columnIndexList"
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    #
    # Toggle the value of the -hide option of the specified columns
    #
    variable canElide
    if {!$canElide} {
	set selCells [curCellSelection $win]
    }
    upvar ::tablelist::ns${win}::data data
    set colIdxList {}
    if {$argCount == 1} {
	foreach elem $first {
	    set col [colIndex $win $elem 1]
	    set data($col-hide) [expr {!$data($col-hide)}]
	    if {$data($col-hide)} {
		incr data(hiddenColCount)
		if {$col == $data(editCol)} {
		    doCancelEditing $win
		}
	    } else {
		incr data(hiddenColCount) -1
	    }
	    lappend colIdxList $col
	}
    } else {
	set first [colIndex $win $first 1]
	set last [colIndex $win [lindex $argList 1] 1]

	for {set col $first} {$col <= $last} {incr col} {
	    set data($col-hide) [expr {!$data($col-hide)}]
	    if {$data($col-hide)} {
		incr data(hiddenColCount)
		if {$col == $data(editCol)} {
		    doCancelEditing $win
		}
	    } else {
		incr data(hiddenColCount) -1
	    }
	    lappend colIdxList $col
	}
    }

    if {[llength $colIdxList] == 0} {
	return ""
    }

    #
    # Adjust the columns and redisplay the items
    #
    makeColFontAndTagLists $win
    adjustColumns $win $colIdxList 1
    adjustColIndex $win data(anchorCol) 1
    adjustColIndex $win data(activeCol) 1
    if {!$canElide} {
	redisplay $win 0 $selCells
    }
    if {[string compare $data(-selecttype) "row"] == 0} {
	foreach row [curSelection $win] {
	    rowSelection $win set $row $row
	}
    }

    updateViewWhenIdle $win
    genVirtualEvent $win <<TablelistColHiddenStateChanged>> $colIdxList
    return ""
}

#------------------------------------------------------------------------------
# tablelist::togglerowhideSubCmd
#------------------------------------------------------------------------------
proc tablelist::togglerowhideSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount < 1 || $argCount > 2} {
	mwutil::wrongNumArgs \
		"$win togglerowhide firstIndex lastIndex" \
		"$win togglerowhide indexList"
    }

    synchronize $win
    displayItems $win
    set first [lindex $argList 0]

    #
    # Toggle the value of the -hide option of the specified rows
    #
    set rowIdxList {}
    set count 0
    if {$argCount == 1} {
	foreach elem $first {
	    set row [rowIndex $win $elem 0 1]
	    doRowConfig $row $win -hide [expr {![doRowCget $row $win -hide]}]
	    incr count
	    lappend rowIdxList $row
	}
    } else {
	set firstRow [rowIndex $win $first 0 1]
	set lastRow [rowIndex $win [lindex $argList 1] 0 1]
	for {set row $firstRow} {$row <= $lastRow} {incr row} {
	    doRowConfig $row $win -hide [expr {![doRowCget $row $win -hide]}]
	    incr count
	    lappend rowIdxList $row
	}
    }

    if {$count != 0} {
	makeStripesWhenIdle $win
	showLineNumbersWhenIdle $win
	updateViewWhenIdle $win
	genVirtualEvent $win <<TablelistRowHiddenStateChanged>> $rowIdxList
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::toplevelkeySubCmd
#------------------------------------------------------------------------------
proc tablelist::toplevelkeySubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win toplevelkey index"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0 1]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [topLevelKey $win $key]
}

#------------------------------------------------------------------------------
# tablelist::unsetattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetattribSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win unsetattrib name"
    }

    return [mwutil::unsetattribSubCmd $win "widget" [lindex $argList 0]]
}

#------------------------------------------------------------------------------
# tablelist::unsetcellattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetcellattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win unsetcellattrib cellIndex name"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::unsetattribSubCmd $win $key,$col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::unsetcolumnattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetcolumnattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win unsetcolumnattrib columnIndex name"
    }

    set col [colIndex $win [lindex $argList 0] 1]
    return [mwutil::unsetattribSubCmd $win $col [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::unsetrowattribSubCmd
#------------------------------------------------------------------------------
proc tablelist::unsetrowattribSubCmd {win argList} {
    if {[llength $argList] != 2} {
	mwutil::wrongNumArgs "$win unsetrowattrib index name"
    }

    synchronize $win
    set row [rowIndex $win [lindex $argList 0] 0]
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    return [mwutil::unsetattribSubCmd $win $key [lindex $argList 1]]
}

#------------------------------------------------------------------------------
# tablelist::viewablerowcountSubCmd
#------------------------------------------------------------------------------
proc tablelist::viewablerowcountSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount != 0 && $argCount != 2} {
	mwutil::wrongNumArgs "$win viewablerowcount ?firstIndex lastIndex?"
    }

    synchronize $win
    upvar ::tablelist::ns${win}::data data
    if {$argCount == 0} {
	set first 0
	set last $data(lastRow)
    } else {
	set first [rowIndex $win [lindex $argList 0] 0]
	set last [rowIndex $win [lindex $argList 1] 0]
    }
    if {$last < $first} {
	return 0
    }

    #
    # Adjust the range to fit within the existing items
    #
    if {$first < 0} {
	set first 0
    }
    if {$last > $data(lastRow)} {
	set last $data(lastRow)
    }

    return [getViewableRowCount $win $first $last]
}

#------------------------------------------------------------------------------
# tablelist::windowpathSubCmd
#------------------------------------------------------------------------------
proc tablelist::windowpathSubCmd {win argList} {
    if {[llength $argList] != 1} {
	mwutil::wrongNumArgs "$win windowpath cellIndex"
    }

    synchronize $win
    foreach {row col} [cellIndex $win [lindex $argList 0] 1] {}
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    set w $data(body).frm_$key,$col.w
    if {[winfo exists $w]} {
	return $w
    } else {
	return ""
    }
}

#------------------------------------------------------------------------------
# tablelist::xviewSubCmd
#------------------------------------------------------------------------------
proc tablelist::xviewSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount != 1 || [lindex $argList 0] != 0} {
	synchronize $win
	displayItems $win
    }
    upvar ::tablelist::ns${win}::data data

    switch $argCount {
	0 {
	    #
	    # Command: $win xview
	    #
	    if {$data(-titlecolumns) == 0} {
		return [$data(hdrTxt) xview]
	    } else {
		set scrlWindowWidth [getScrlWindowWidth $win]
		if {$scrlWindowWidth <= 0} {
		    return [list 0 0]
		}

		set scrlContentWidth [getScrlContentWidth $win 0 $data(lastCol)]
		if {$scrlContentWidth == 0} {
		    return [list 0 1]
		}

		set scrlXOffset \
		    [scrlColOffsetToXOffset $win $data(scrlColOffset)]
		set fraction1 [expr {$scrlXOffset/double($scrlContentWidth)}]
		set fraction2 [expr {($scrlXOffset + $scrlWindowWidth)/
				     double($scrlContentWidth)}]
		if {$fraction2 > 1.0} {
		    set fraction2 1.0
		}
		return [list $fraction1 $fraction2]
	    }
	}

	1 {
	    #
	    # Command: $win xview <units>
	    #
	    set units [format "%d" [lindex $argList 0]]
	    if {$data(-titlecolumns) == 0} {
		foreach w [list $data(hdrTxt) $data(body)] {
		    $w xview moveto 0
		    $w xview scroll $units units
		}
		redisplayVisibleItems $win
	    } else {
		changeScrlColOffset $win $units
	    }
	    hdr_updateColors $win
	    updateColors $win
	    return ""
	}

	default {
	    #
	    # Command: $win xview moveto <fraction>
	    #	       $win xview scroll <number> units|pages
	    #
	    set argList [mwutil::getScrollInfo $argList]
	    if {$data(-titlecolumns) == 0} {
		if {[string compare [lindex $argList 0] "moveto"] == 0} {
		    set data(fraction) [lindex $argList 1]
		    if {![info exists data(moveToId)]} {
			variable winSys
			if {[string compare $winSys "x11"] == 0} {
			    set delay [expr {($data(colCount) + 7) / 8}]
			} else {
			    set delay [expr {($data(colCount) + 1) / 2}]
			}
			set data(moveToId) \
			    [after $delay [list tablelist::horizMoveTo $win]]
		    }
		    return ""
		} else {
		    foreach w [list $data(hdrTxt) $data(body)] {
			eval [list $w xview] $argList
		    }
		    redisplayVisibleItems $win
		    hdr_updateColors $win
		    updateColors $win
		}
	    } else {
		if {[string compare [lindex $argList 0] "moveto"] == 0} {
		    #
		    # Compute the new scrolled column offset
		    #
		    set fraction [lindex $argList 1]
		    set scrlContentWidth \
			[getScrlContentWidth $win 0 $data(lastCol)]
		    set pixels [expr {int($fraction*$scrlContentWidth + 0.5)}]
		    set scrlColOffset [scrlXOffsetToColOffset $win $pixels]

		    #
		    # Increase the new scrolled column offset if necessary
		    #
		    if {$pixels + [getScrlWindowWidth $win] >=
			$scrlContentWidth} {
			incr scrlColOffset
		    }

		    changeScrlColOffset $win $scrlColOffset
		} else {
		    set number [lindex $argList 1]
		    if {[string compare [lindex $argList 2] "units"] == 0} {
			changeScrlColOffset $win \
			    [expr {$data(scrlColOffset) + $number}]
		    } else {
			#
			# Compute the new scrolled column offset
			#
			set scrlXOffset \
			    [scrlColOffsetToXOffset $win $data(scrlColOffset)]
			set scrlWindowWidth [getScrlWindowWidth $win]
			set deltaPixels [expr {$number*$scrlWindowWidth}]
			set pixels [expr {$scrlXOffset + $deltaPixels}]
			set scrlColOffset [scrlXOffsetToColOffset $win $pixels]

			#
			# Adjust the new scrolled column offset if necessary
			#
			if {$number < 0 &&
			    [getScrlContentWidth $win $scrlColOffset \
			     $data(lastCol)] -
			    [getScrlContentWidth $win $data(scrlColOffset) \
			     $data(lastCol)] > -$deltaPixels} {
			    incr scrlColOffset
			}
			if {$scrlColOffset == $data(scrlColOffset)} {
			    if {$number < 0} {
				incr scrlColOffset -1
			    } elseif {$number > 0} {
				incr scrlColOffset
			    }
			}

			changeScrlColOffset $win $scrlColOffset
		    }
		}
		hdr_updateColors $win
		updateColors $win
	    }
	    variable winSys
	    if {[string compare $winSys "aqua"] == 0 && [winfo viewable $win]} {
		#
		# Work around a Tk bug on Mac OS X Aqua
		#
		if {[winfo exists $data(bodyFrm)]} {
		    lower $data(bodyFrm)
		    raise $data(bodyFrm)
		}
	    }
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::yviewSubCmd
#------------------------------------------------------------------------------
proc tablelist::yviewSubCmd {win argList} {
    set argCount [llength $argList]
    if {$argCount != 1 || [lindex $argList 0] != 0} {
	synchronize $win
	displayItems $win
    }
    upvar ::tablelist::ns${win}::data data
    set w $data(body)

    switch $argCount {
	0 {
	    #
	    # Command: $win yview
	    #
	    set totalViewableCount [getViewableRowCount $win 0 $data(lastRow)]
	    if {$totalViewableCount == 0} {
		return [list 0 1]
	    }
	    set topRow [getVertComplTopRow $win]
	    set btmRow [getVertComplBtmRow $win]
	    set upperViewableCount \
		[getViewableRowCount $win 0 [expr {$topRow - 1}]]
	    set winViewableCount [getViewableRowCount $win $topRow $btmRow]
	    set fraction1 [expr {$upperViewableCount/
				 double($totalViewableCount)}]
	    set fraction2 [expr {($upperViewableCount + $winViewableCount)/
				 double($totalViewableCount)}]
	    return [list $fraction1 $fraction2]
	}

	1 {
	    #
	    # Command: $win yview <units>
	    #
	    set units [format "%d" [lindex $argList 0]]
	    set row [viewableRowOffsetToRowIndex $win $units]
	    $w yview $row
	    adjustElidedText $win
	    redisplayVisibleItems $win
	    updateColors $win
	    adjustSepsWhenIdle $win
	    updateVScrlbarWhenIdle $win
	    updateIdletasksDelayed 
	    return ""
	}

	default {
	    #
	    # Command: $win yview moveto <fraction>
	    #	       $win yview scroll <number> units|pages
	    #
	    set argList [mwutil::getScrollInfo $argList]
	    if {[string compare [lindex $argList 0] "moveto"] == 0} {
		set data(fraction) [lindex $argList 1]
		if {![info exists data(moveToId)]} {
		    variable winSys
		    if {[string compare $winSys "x11"] == 0} {
			set delay [expr {($data(colCount) + 3) / 4}]
		    } else {
			set delay [expr {$data(colCount) * 2}]
		    }
		    set data(moveToId) \
			[after $delay [list tablelist::vertMoveTo $win]]
		}
		return ""
	    } else {
		set number [lindex $argList 1]
		if {[string compare [lindex $argList 2] "units"] == 0} {
		    set topRow [getVertComplTopRow $win]
		    set upperViewableCount \
			[getViewableRowCount $win 0 [expr {$topRow - 1}]]
		    set offset [expr {$upperViewableCount + $number}]
		    set row [viewableRowOffsetToRowIndex $win $offset]
		    $w yview $row
		} else {
		    set absNumber [expr {abs($number)}]
		    for {set n 0} {$n < $absNumber} {incr n} {
			set topRow [getVertComplTopRow $win]
			set btmRow [getVertComplBtmRow $win]
			set upperViewableCount \
			    [getViewableRowCount $win 0 [expr {$topRow - 1}]]
			set winViewableCount \
			    [getViewableRowCount $win $topRow $btmRow]
			set delta [expr {$winViewableCount - 2}]
			if {$delta <= 0} {
			    set delta 1
			}
			if {$number < 0} {
			    set delta [expr {(-1)*$delta}]
			}
			set offset [expr {$upperViewableCount + $delta}]
			set row [viewableRowOffsetToRowIndex $win $offset]
			$w yview $row
		    }
		}

		adjustElidedText $win
		redisplayVisibleItems $win
		updateColors $win
		adjustSepsWhenIdle $win
		updateVScrlbarWhenIdle $win
		updateIdletasksDelayed 
		return ""
	    }
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::cellSelection
#
# Processes the tablelist cellselection subcommand.
#------------------------------------------------------------------------------
proc tablelist::cellSelection {win opt firstRow firstCol lastRow lastCol} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) && [string compare $opt "includes"] != 0} {
	return ""
    }

    switch $opt {
	anchor {
	    #
	    # Adjust the row and column indices to fit
	    # within the existing viewable elements
	    #
	    adjustRowIndex $win firstRow 1
	    adjustColIndex $win firstCol 1

	    set data(anchorRow) $firstRow
	    set data(anchorCol) $firstCol
	    return ""
	}

	clear {
	    #
	    # Adjust the row and column indices
	    # to fit within the existing elements
	    #
	    if {$data(itemCount) == 0 || $data(colCount) == 0} {
		return ""
	    }
	    adjustRowIndex $win firstRow
	    adjustColIndex $win firstCol
	    adjustRowIndex $win lastRow
	    adjustColIndex $win lastCol

	    #
	    # Swap the indices if necessary
	    #
	    if {$lastRow < $firstRow} {
		set tmp $firstRow
		set firstRow $lastRow
		set lastRow $tmp
	    }
	    if {$lastCol < $firstCol} {
		set tmp $firstCol
		set firstCol $lastCol
		set lastCol $tmp
	    }

	    set fromTextIdx [expr {$firstRow + 1}].0
	    set toTextIdx [expr {$lastRow + 1}].end

	    #
	    # Find the (partly) selected lines of the body text widget
	    # in the text range specified by the two cell indices
	    #
	    set w $data(body)
	    variable canElide
	    variable elide
	    variable pu
	    set selRange [$w tag nextrange select $fromTextIdx $toTextIdx]
	    while {[llength $selRange] != 0} {
		set selStart [lindex $selRange 0]
		set line [expr {int($selStart)}]
		set row [expr {$line - 1}]
		set key [lindex $data(keyList) $row]

		#
		# Deselect the relevant elements of the row
		#
		findTabs $win $w $line $firstCol $lastCol firstTabIdx lastTabIdx
		set textIdx1 $firstTabIdx
		for {set col $firstCol} {$col <= $lastCol} {incr col} {
		    if {$data($col-hide) && !$canElide} {
			continue
		    }

		    set textIdx2 [$w search $elide "\t" $textIdx1+1$pu \
			$lastTabIdx+1$pu]+1$pu
		    $w tag remove select $textIdx1 $textIdx2
		    set textIdx1 $textIdx2
		}

		set selRange \
		    [$w tag nextrange select "$selStart lineend" $toTextIdx]
	    }

	    updateColorsWhenIdle $win
	    return ""
	}

	includes {
	    variable canElide
	    if {$firstRow < 0 || $firstRow > $data(lastRow) || \
		$firstCol < 0 || $firstCol > $data(lastCol) ||
		($data($firstCol-hide) && !$canElide)} {
		return 0
	    }

	    findTabs $win $data(body) [expr {$firstRow + 1}] \
		     $firstCol $firstCol tabIdx1 tabIdx2
	    if {[lsearch -exact [$data(body) tag names $tabIdx2] select] < 0} {
		return 0
	    } else {
		return 1
	    }
	}

	set {
	    #
	    # Adjust the row and column indices
	    # to fit within the existing elements
	    #
	    if {$data(itemCount) == 0 || $data(colCount) == 0} {
		return ""
	    }
	    adjustRowIndex $win firstRow
	    adjustColIndex $win firstCol
	    adjustRowIndex $win lastRow
	    adjustColIndex $win lastCol

	    #
	    # Swap the indices if necessary
	    #
	    if {$lastRow < $firstRow} {
		set tmp $firstRow
		set firstRow $lastRow
		set lastRow $tmp
	    }
	    if {$lastCol < $firstCol} {
		set tmp $firstCol
		set firstCol $lastCol
		set lastCol $tmp
	    }

	    set w $data(body)
	    variable canElide
	    variable elide
	    variable pu
	    for {set row $firstRow; set line [expr {$firstRow + 1}]} \
		{$row <= $lastRow} {set row $line; incr line} {
		#
		# Check whether the row is selectable
		#
		set key [lindex $data(keyList) $row]
		if {[info exists data($key-selectable)]} {
		    continue
		}

		#
		# Select the relevant elements of the row
		#
		findTabs $win $w $line $firstCol $lastCol firstTabIdx lastTabIdx
		set textIdx1 $firstTabIdx
		for {set col $firstCol} {$col <= $lastCol} {incr col} {
		    if {$data($col-hide) && !$canElide} {
			continue
		    }

		    set textIdx2 [$w search $elide "\t" $textIdx1+1$pu \
			$lastTabIdx+1$pu]+1$pu
		    $w tag add select $textIdx1 $textIdx2
		    set textIdx1 $textIdx2
		}
	    }

	    #
	    # If the selection is exported and there are any selected
	    # cells in the widget then make win the new owner of the
	    # PRIMARY selection and register a callback to be invoked
	    # when it loses ownership of the PRIMARY selection
	    #
	    if {$data(-exportselection) &&
		[llength [$w tag nextrange select 1.0]] != 0} {
		selection own -command \
		    [list ::tablelist::lostSelection $win] $win
	    }

	    updateColorsWhenIdle $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::colWidth
#
# Processes the tablelist columnwidth subcommand.
#------------------------------------------------------------------------------
proc tablelist::colWidth {win col opt} {
    upvar ::tablelist::ns${win}::data data
    set pixels [lindex $data(colList) [expr {2*$col}]]
    if {$pixels == 0} {				;# convention: dynamic width
	set pixels $data($col-reqPixels)
	if {$data($col-maxPixels) > 0} {
	    if {$pixels > $data($col-maxPixels)} {
		set pixels $data($col-maxPixels)
	    }
	}
    }

    switch -- $opt {
	-requested { return $pixels }
	-stretched { return [expr {$pixels + $data($col-delta)}] }
	-total {
	    return [expr {$pixels + $data($col-delta) + 2*$data(charWidth)}]
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::containingRow
#
# Processes the tablelist containing subcommand.
#------------------------------------------------------------------------------
proc tablelist::containingRow {win y {relOffsetName ""}} {
    upvar ::tablelist::ns${win}::data data
    if {$data(itemCount) == 0} {
	return -1
    }

    set row [rowIndex $win @0,$y 0]		;# before decrementing y !!!
    set w $data(body)
    incr y -[winfo y $w]
    if {$y < 0} {
	return -1
    }

    set dlineinfo [$w dlineinfo [expr {$row + 1}].0]
    set lineY [lindex $dlineinfo 1]
    set lineHeight [lindex $dlineinfo 3]
    if {[llength $dlineinfo] != 0 && $y < $lineY + $lineHeight} {
	if {[string length $relOffsetName] != 0} {
	    upvar $relOffsetName relOffset
	    if {$y == $lineY + $lineHeight -1} {
		set relOffset 1.0
	    } else {
		set relOffset [expr {double($y - $lineY) / $lineHeight}]
	    }
	}
	return $row
    } else {
	return -1
    }
}

#------------------------------------------------------------------------------
# tablelist::hdr_containingRow
#
# Processes the tablelist header containing subcommand.
#------------------------------------------------------------------------------
proc tablelist::hdr_containingRow {win y} {
    upvar ::tablelist::ns${win}::data data
    if {$data(hdr_itemCount) == 0} {
	return -1
    }

    set row [hdr_rowIndex $win @0,$y 0]		;# before decrementing y !!!
    if {$row < 0} {
	return -1
    }

    incr y -[winfo y $data(hdr)]
    if {!$data(-showlabels)} {
	incr y
    }
    if {$y < 0} {
	return -1
    }

    set dlineinfo [$data(hdrTxt) dlineinfo [expr {$row + 2}].0]
    set lineY [lindex $dlineinfo 1]
    set lineHeight [lindex $dlineinfo 3]
    if {[llength $dlineinfo] != 0 && $y >= $lineY &&
	$y < $lineY + $lineHeight} {
	return $row
    } else {
	return -1
    }
}

#------------------------------------------------------------------------------
# tablelist::containingCol
#
# Processes the tablelist containingcolumn subcommand.
#------------------------------------------------------------------------------
proc tablelist::containingCol {win x} {
    upvar ::tablelist::ns${win}::data data
    if {$x < [winfo x $data(body)]} {
	return -1
    }

    set col [colIndex $win @$x,0 0]
    if {$col < 0} {
	return -1
    }

    set lbl $data(hdrTxtFrmLbl)$col
    if {$x + [winfo rootx $win] < [winfo width $lbl] + [winfo rootx $lbl]} {
	return $col
    } else {
	return -1
    }
}

#------------------------------------------------------------------------------
# tablelist::curCellSelection
#
# Processes the tablelist curcellselection subcommand.  Meaning of the last
# optional argument: 0: all; 1: nonhidden only; 2: viewable only.
#------------------------------------------------------------------------------
proc tablelist::curCellSelection {win {getKeys 0} {constraint 0}} {
    variable canElide
    variable elide
    variable pu
    upvar ::tablelist::ns${win}::data data

    #
    # Find the (partly) selected lines of the body text widget
    #
    set result {}
    set w $data(body)
    for {set selRange [$w tag nextrange select 1.0]} \
	{[llength $selRange] != 0} \
	{set selRange [$w tag nextrange select $selEnd]} {
	foreach {selStart selEnd} $selRange {}
	set line [expr {int($selStart)}]
	set row [expr {$line - 1}]
	if {$getKeys || $constraint != 0} {
	    set key [lindex $data(keyList) $row]
	}
	if {($constraint == 1 && [info exists data($key-hide)]) ||
	    ($constraint == 2 && ([info exists data($key-hide)] ||
	     [info exists data($key-elide)]))} {
	    continue
	}

	#
	# Get the index of the column containing the text position selStart
	#
	set tabIdx1 $line.0
	for {set col 0} {$col < $data(colCount)} {incr col} {
	    if {$data($col-hide) && !$canElide} {
		continue
	    }

	    set tabIdx2 [$w search $elide "\t" $tabIdx1+1$pu $selEnd]
	    if {[$w compare $selStart >= $tabIdx1] &&
		[$w compare $selStart <= $tabIdx2]} {
		set firstCol $col
		break
	    } else {
		set tabIdx1 [$w index $tabIdx2+1$pu]
	    }
	}

	#
	# Process the columns, starting at the found one
	# and ending just before the text position selEnd
	#
	set textIdx $tabIdx2+1$pu
	for {set col $firstCol} {$col < $data(colCount)} {incr col} {
	    if {$data($col-hide) && !$canElide} {
		continue
	    }

	    if {$constraint == 0 || !$data($col-hide)} {
		if {$getKeys} {
		    lappend result $key $col
		} else {
		    lappend result $row,$col
		}
	    }
	    if {[$w compare $textIdx == $selEnd]} {
		break
	    } else {
		set textIdx [$w search $elide "\t" $textIdx+1$pu $selEnd]+1$pu
	    }
	}
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::curSelection
#
# Processes the tablelist curselection subcommand.  Meaning of the optional
# argument: 0: all; 1: nonhidden only; 2: viewable only.
#------------------------------------------------------------------------------
proc tablelist::curSelection {win {constraint 0}} {
    #
    # Find the (partly) selected lines of the body text widget
    #
    set result {}
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    set selRange [$w tag nextrange select 1.0]
    while {[llength $selRange] != 0} {
	set selStart [lindex $selRange 0]
	set row [expr {int($selStart) - 1}]
	if {$constraint == 0} {
	    lappend result $row
	} else {
	    set key [lindex $data(keyList) $row]
	    if {($constraint == 1 && ![info exists data($key-hide)]) ||
		($constraint == 2 && ![info exists data($key-hide)] &&
		 ![info exists data($key-elide)])} {
		lappend result $row
	    }
	}

	set selRange [$w tag nextrange select "$selStart lineend"]
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::deleteRows
#
# Processes the tablelist delete subcommand.
#------------------------------------------------------------------------------
proc tablelist::deleteRows {win first last updateListVar} {
    #
    # Adjust the range to fit within the existing items
    #
    if {$first < 0} {
	set first 0
    }
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs
    if {$last > $data(lastRow)} {
	set last $data(lastRow)
    }
    if {$last < $first} {
	return ""
    }

    #
    # Increase the last index if necessary, to make sure that all
    # descendants of the corresponding item will get deleted, too
    #
    set lastKey [lindex $data(keyList) $last]
    set last [expr {[nodeRow $win $lastKey end] - 1}]
    set count [expr {$last - $first + 1}]

    #
    # Check whether the width of any dynamic-width
    # column might be affected by the deletion
    #
    set w $data(body)
    if {$count == $data(itemCount)} {
	set colWidthsChanged 1				;# just to save time
	set data(seqNum) -1
	set data(freeKeyList) {}
    } else {
	variable canElide
	set colWidthsChanged 0
	set snipStr $data(-snipstring)
	set row 0
	set itemListRange [lrange $data(itemList) $first $last]
	foreach item $itemListRange {
	    #
	    # Format the item
	    #
	    set key [lindex $item end]
	    set dispItem [lrange $item 0 $data(lastCol)]
	    if {$data(hasFmtCmds)} {
		set dispItem [formatItem $win $key $row $dispItem]
	    }
	    if {[string match "*\t*" $dispItem]} {
		set dispItem [mapTabs $dispItem]
	    }

	    set col 0
	    foreach text $dispItem {pixels alignment} $data(colList) {
		if {($data($col-hide) && !$canElide) || $pixels != 0} {
		    incr col
		    continue
		}

		getAuxData $win $key $col auxType auxWidth
		getIndentData $win $key $col indentWidth
		set cellFont [getCellFont $win $key $col]
		set elemWidth \
		    [getElemWidth $win $text $auxWidth $indentWidth $cellFont]
		if {$elemWidth == $data($col-elemWidth) &&
		    [incr data($col-widestCount) -1] == 0} {
		    set colWidthsChanged 1
		    break
		}

		incr col
	    }

	    if {$colWidthsChanged} {
		break
	    }

	    incr row
	}
    }

    #
    # Delete the given items from the body text widget.  Interestingly,
    # for a large number of items it is much more efficient to delete
    # the lines in chunks than to invoke a global delete command.
    #
    for {set toLine [expr {$last + 2}]; set fromLine [expr {$toLine - 50}]} \
	{$fromLine > $first} {set toLine $fromLine; incr fromLine -50} {
	$w delete $fromLine.0 $toLine.0
    }
    set rest [expr {$count % 50}]
    $w delete [expr {$first + 1}].0 [expr {$first + $rest + 1}].0

    if {$last == $data(lastRow)} {
	#
	# Delete the newline character that ends
	# the line preceding the first deleted one
	#
	$w delete $first.end

	#
	# Work around a peculiarity of the text widget:  Hide
	# the newline character that ends the line preceding
	# the first deleted one if it was hidden before
	#
	set textIdx $first.0
	foreach tag {elidedRow hiddenRow} {
	    if {[lsearch -exact [$w tag names $textIdx] $tag] >= 0} {
		$w tag add $tag $first.end
	    }
	}
    }

    #
    # Unset the elements of data corresponding to the deleted items
    #
    if {$count == $data(itemCount)} {
	foreach name [array names data {k[0-9]*}] {
	    unset data($name)
	}
	array set data {rowTagRefCount 0  nonViewableRowCount 0
	    cellTagRefCount 0  imgCount 0  winCount 0  indentCount 0
	    root-children {}}

	foreach name [array names attrib {k[0-9]*}] {
	    unset attrib($name)
	}
    } else {
	for {set row $first} {$row <= $last} {incr row} {
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    lappend data(freeKeyList) $key

	    foreach opt {-background -foreground -name -selectable
			 -selectbackground -selectforeground} {
		if {[info exists data($key$opt)]} {
		    unset data($key$opt)
		}
	    }

	    if {[info exists data($key-font)]} {
		unset data($key-font)
		incr data(rowTagRefCount) -1
	    }

	    set isElided [info exists data($key-elide)]
	    set isHidden [info exists data($key-hide)]
	    if {$isElided} {
		unset data($key-elide)
	    }
	    if {$isHidden} {
		unset data($key-hide)
	    }
	    if {$isElided || $isHidden} {
		incr data(nonViewableRowCount) -1
	    }

	    #
	    # Remove the key from the list of children of its parent
	    #
	    set parentKey $data($key-parent)
	    if {[info exists data($parentKey-children)]} {
		set childIdx [lsearch -exact $data($parentKey-children) $key]
		set data($parentKey-children) \
		    [lreplace $data($parentKey-children) $childIdx $childIdx]

		#
		# If the parent's list of children has become empty
		# then set its indentation image to the indented one
		#
		set col $data(treeCol)
		if {[llength $data($parentKey-children)] == 0 &&
		    [info exists data($parentKey,$col-indent)]} {
		    collapseSubCmd $win [list $parentKey -partly]
		    set data($parentKey,$col-indent) [strMap \
			{"collapsed" "indented" "expanded" "indented"
			 "Act" "" "Sel" ""} $data($parentKey,$col-indent)]
		    if {[winfo exists $data(body).ind_$parentKey,$col]} {
			$data(body).ind_$parentKey,$col configure -image \
			    $data($parentKey,$col-indent)
		    }
		}
	    }

	    foreach prop {-row -parent -children} {
		unset data($key$prop)
	    }

	    foreach name [array names attribs $key-*] {
		unset attribs($name)
	    }

	    for {set col 0} {$col < $data(colCount)} {incr col} {
		foreach opt {-background -foreground -editable -editwindow
			     -selectbackground -selectforeground -valign
			     -windowdestroy -windowupdate} {
		    if {[info exists data($key,$col$opt)]} {
			unset data($key,$col$opt)
		    }
		}

		if {[info exists data($key,$col-font)]} {
		    unset data($key,$col-font)
		    incr data(cellTagRefCount) -1
		}

		if {[info exists data($key,$col-image)]} {
		    unset data($key,$col-image)
		    incr data(imgCount) -1
		}

		if {[info exists data($key,$col-window)]} {
		    unset data($key,$col-window)
		    unset data($key,$col-reqWidth)
		    unset data($key,$col-reqHeight)
		    incr data(winCount) -1
		}

		if {[info exists data($key,$col-indent)]} {
		    unset data($key,$col-indent)
		    incr data(indentCount) -1
		}
	    }

	    foreach name [array names attribs $key,*-*] {
		unset attribs($name)
	    }
	}
    }

    #
    # Delete the given items from the internal list
    #
    set data(itemList) [lreplace $data(itemList) $first $last]
    set data(keyList) [lreplace $data(keyList) $first $last]
    incr data(itemCount) -$count

    #
    # Delete the given items from the list variable if needed
    #
    if {$updateListVar} {
	upvar #0 $data(-listvariable) var
	trace vdelete var wu $data(listVarTraceCmd)
	set var [lreplace $var $first $last]
	trace variable var wu $data(listVarTraceCmd)
    }

    #
    # Update the key -> row mapping at idle time if needed
    #
    if {$last != $data(lastRow)} {
	set data(keyToRowMapValid) 0
	if {![info exists data(mapId)]} {
	    set data(mapId) \
		[after idle [list tablelist::updateKeyToRowMap $win]]
	}
    }

    incr data(lastRow) -$count

    #
    # Update the indices anchorRow and activeRow
    #
    if {$first <= $data(anchorRow)} {
	incr data(anchorRow) -$count
	if {$data(anchorRow) < $first} {
	    set data(anchorRow) $first
	}
	adjustRowIndex $win data(anchorRow) 1
    }
    if {$last < $data(activeRow)} {
	set activeRow $data(activeRow)
	incr activeRow -$count
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    } elseif {$first <= $data(activeRow)} {
	set activeRow $first
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    }

    #
    # Update data(editRow) if the edit window is present
    #
    if {$data(editRow) >= 0} {
	set data(editRow) [keyToRow $win $data(editKey)]
    }

    #
    # Adjust the heights of the body text widget
    # and of the listbox child, if necessary
    #
    if {$data(-height) <= 0} {
	set viewableRowCount \
	    [expr {$data(itemCount) - $data(nonViewableRowCount)}]
	$w configure -height $viewableRowCount
	$data(lb) configure -height $viewableRowCount
    }

    #
    # Invalidate the list of row indices indicating the
    # viewable rows, adjust the columns if necessary, and
    # schedule some operations for execution at idle time
    #
    set data(viewableRowList) {-1}
    if {$colWidthsChanged} {
	adjustColumns $win allCols 1
    }
    makeStripesWhenIdle $win
    showLineNumbersWhenIdle $win
    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::hdr_deleteRows
#
# Processes the tablelist header delete subcommand.
#------------------------------------------------------------------------------
proc tablelist::hdr_deleteRows {win first last} {
    #
    # Adjust the range to fit within the existing items
    #
    if {$first < 0} {
	set first 0
    }
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs
    if {$last > $data(hdr_lastRow)} {
	set last $data(hdr_lastRow)
    }
    if {$last < $first} {
	return ""
    }

    set count [expr {$last - $first + 1}]

    #
    # Check whether the width of any dynamic-width
    # column might be affected by the deletion
    #
    set w $data(hdrTxt)
    if {$count == $data(hdr_itemCount)} {
	set colWidthsChanged 1				;# just to save time
	set data(hdr_seqNum) -1
    } else {
	variable canElide
	set colWidthsChanged 0
	set snipStr $data(-snipstring)
	set row 0
	set hdr_itemList [lrange $data(hdr_itemList) $first $last]
	foreach item $hdr_itemList {
	    #
	    # Format the item
	    #
	    set key [lindex $item end]
	    set dispItem [lrange $item 0 $data(lastCol)]
	    if {$data(hasFmtCmds)} {
		set dispItem [formatItem $win $key $row $dispItem]
	    }
	    if {[string match "*\t*" $dispItem]} {
		set dispItem [mapTabs $dispItem]
	    }

	    set col 0
	    foreach text $dispItem {pixels alignment} $data(colList) {
		if {($data($col-hide) && !$canElide) || $pixels != 0} {
		    incr col
		    continue
		}

		getAuxData $win $key $col auxType auxWidth
		set cellFont [getCellFont $win $key $col]
		set elemWidth [getElemWidth $win $text $auxWidth 0 $cellFont]
		if {$elemWidth == $data($col-elemWidth) &&
		    [incr data($col-widestCount) -1] == 0} {
		    set colWidthsChanged 1
		    break
		}

		incr col
	    }

	    if {$colWidthsChanged} {
		break
	    }

	    incr row
	}
    }

    #
    # Delete the given items from the header text widget.
    #
    $w delete [expr {$first + 2}].0 [expr {$last + 3}].0

    if {$last == $data(hdr_lastRow)} {
	#
	# Delete the newline character that ends
	# the line preceding the first deleted one
	#
	$w delete [expr {$first + 1}].end
    }

    #
    # Unset the elements of data corresponding to the deleted items
    #
    for {set row $first} {$row <= $last} {incr row} {
	set item [lindex $data(hdr_itemList) $row]
	set key [lindex $item end]

	foreach opt {-background -foreground -font -name} {
	    if {[info exists data($key$opt)]} {
		unset data($key$opt)
	    }
	}

	foreach name [array names attribs $key-*] {
	    unset attribs($name)
	}

	for {set col 0} {$col < $data(colCount)} {incr col} {
	    foreach opt {-background -foreground -font -image
			 -valign -windowdestroy -windowupdate} {
		if {[info exists data($key,$col$opt)]} {
		    unset data($key,$col$opt)
		}
	    }

	    if {[info exists data($key,$col-window)]} {
		unset data($key,$col-window)
		unset data($key,$col-reqWidth)
		unset data($key,$col-reqHeight)
	    }
	}

	foreach name [array names attribs $key,*-*] {
	    unset attribs($name)
	}
    }

    #
    # Delete the given items from the internal list
    #
    set data(hdr_itemList) [lreplace $data(hdr_itemList) $first $last]
    set data(hdr_keyList) [lreplace $data(hdr_keyList) $first $last]
    incr data(hdr_itemCount) -$count
    incr data(hdr_lastRow) -$count

    #
    # Adjust the columns if necessary and schedule
    # some operations for execution at idle time
    #
    if {$colWidthsChanged} {
	adjustColumns $win allCols 1
    }
    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::deleteCols
#
# Processes the tablelist deletecolumns subcommand.
#------------------------------------------------------------------------------
proc tablelist::deleteCols {win first last selCellsName} {
    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs $selCellsName selCells

    #
    # Delete the data and attributes corresponding to the given range
    #
    for {set col $first} {$col <= $last} {incr col} {
	if {$data($col-hide)} {
	    incr data(hiddenColCount) -1
	}
	deleteColData $win $col
	deleteColAttribs $win $col
	set selCells [deleteColFromCellList $selCells $col]
    }

    #
    # Shift the elements of data and attribs corresponding to the
    # column indices > last to the left by last - first + 1 positions
    #
    for {set oldCol [expr {$last + 1}]; set newCol $first} \
	{$oldCol < $data(colCount)} {incr oldCol; incr newCol} {
	moveColData data data imgs $oldCol $newCol
	moveColAttribs attribs attribs $oldCol $newCol
	set selCells [replaceColInCellList $selCells $oldCol $newCol]
    }

    #
    # Update the item list
    #
    set newItemList {}
    foreach item $data(itemList) {
	set item [lreplace $item $first $last]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Set up and adjust the columns, and rebuild some columns-related lists
    #
    setupColumns $win \
	[lreplace $data(-columns) [expr {3*$first}] [expr {3*$last + 2}]] 1
    makeColFontAndTagLists $win
    makeSortAndArrowColLists $win
    adjustColumns $win {} 1
    updateViewWhenIdle $win

    #
    # Reconfigure the relevant column labels
    #
    for {set col $first} {$col < $data(colCount)} {incr col} {
	reconfigColLabels $win imgs $col
    }

    #
    # Update the indices anchorCol and activeCol
    #
    set count [expr {$last - $first + 1}]
    if {$first <= $data(anchorCol)} {
	incr data(anchorCol) -$count
	if {$data(anchorCol) < $first} {
	    set data(anchorCol) $first
	}
	adjustColIndex $win data(anchorCol) 1
    }
    if {$last < $data(activeCol)} {
	incr data(activeCol) -$count
	adjustColIndex $win data(activeCol) 1
    } elseif {$first <= $data(activeCol)} {
	set data(activeCol) $first
	adjustColIndex $win data(activeCol) 1
    }
}

#------------------------------------------------------------------------------
# tablelist::insertRows
#
# Processes the tablelist insert and insertlist subcommands.
#------------------------------------------------------------------------------
proc tablelist::insertRows {win index argList updateListVar parentKey \
			    childIdx} {
    set argCount [llength $argList]
    if {$argCount == 0} {
	return {}
    }

    upvar ::tablelist::ns${win}::data data
    if {$index < $data(itemCount)} {
	displayItems $win
    }

    if {$index < 0} {
	set index 0
    } elseif {$index > $data(itemCount)} {
	set index $data(itemCount)
    }

    set childCount [llength $data($parentKey-children)]
    if {$childIdx < 0} {
	set childIdx 0
    } elseif {$childIdx > $childCount} {	;# e.g., if $childIdx is "end"
	set childIdx $childCount
    }

    #
    # Insert the items into the internal list
    #
    set result {}
    set appendingItems [expr {$index == $data(itemCount)}]
    set appendingChildren [expr {$childIdx == $childCount}]
    set row $index
    foreach item $argList {
	#
	# Adjust the item
	#
	set item [adjustItem $item $data(colCount)]

	#
	# Insert the item into the list variable if needed
	#
	if {$updateListVar} {
	    upvar #0 $data(-listvariable) var
	    trace vdelete var wu $data(listVarTraceCmd)
	    if {$appendingItems} {
		lappend var $item    		;# this works much faster
	    } else {
		set var [linsert $var $row $item]
	    }
	    trace variable var wu $data(listVarTraceCmd)
	}

	#
	# Get a free key for the new item
	#
	if {[llength $data(freeKeyList)] == 0} {
	    set key k[incr data(seqNum)]
	} else {
	    set key [lindex $data(freeKeyList) 0]
	    set data(freeKeyList) [lrange $data(freeKeyList) 1 end]
	}

	#
	# Insert the extended item into the internal list
	#
	lappend item $key
	if {$appendingItems} {
	    lappend data(itemList) $item	;# this works much faster
	    lappend data(keyList) $key		;# this works much faster
	} else {
	    set data(itemList) [linsert $data(itemList) $row $item]
	    set data(keyList) [linsert $data(keyList) $row $key]
	}

	array set data \
	    [list $key-row $row  $key-parent $parentKey  $key-children {}]

	#
	# Insert the key into the parent's list of children
	#
	if {$appendingChildren} {
	    lappend data($parentKey-children) $key    ;# this works much faster
	} else {
	    set data($parentKey-children) \
		[linsert $data($parentKey-children) $childIdx $key]
	}

	lappend data(rowsToDisplay) $row
	lappend result $key

	incr row
	incr childIdx
    }
    incr data(itemCount) $argCount
    set data(lastRow) [expr {$data(itemCount) - 1}]

    #
    # Update the key -> row mapping at idle time if needed
    #
    if {!$appendingItems} {
	set data(keyToRowMapValid) 0
	if {![info exists data(mapId)]} {
	    set data(mapId) \
		[after idle [list tablelist::updateKeyToRowMap $win]]
	}
    }

    if {![info exists data(dispId)]} {
	#
	# Arrange for the inserted items to be displayed at idle time
	#
	set data(dispId) [after idle [list tablelist::displayItems $win]]
    }

    #
    # Update the indices anchorRow and activeRow
    #
    if {$index <= $data(anchorRow)} {
	incr data(anchorRow) $argCount
	adjustRowIndex $win data(anchorRow) 1
    }
    if {$index <= $data(activeRow)} {
	set activeRow $data(activeRow)
	incr activeRow $argCount
	adjustRowIndex $win activeRow 1
	set data(activeRow) $activeRow
    }

    #
    # Update data(editRow) if the edit window is present
    #
    if {$data(editRow) >= 0} {
	set data(editRow) [keyToRow $win $data(editKey)]
    }

    return $result
}

#------------------------------------------------------------------------------
# tablelist::hdr_insertRows
#
# Processes the tablelist header insert and insertlist subcommands.
#------------------------------------------------------------------------------
proc tablelist::hdr_insertRows {win index argList} {
    set argCount [llength $argList]
    if {$argCount == 0} {
	return {}
    }

    upvar ::tablelist::ns${win}::data data
    if {$index < 0} {
	set index 0
    } elseif {$index > $data(hdr_itemCount)} {
	set index $data(hdr_itemCount)
    }

    #
    # Insert the items into the internal list and the header text widget
    #
    set result {}
    variable canElide
    variable snipSides
    set w $data(hdrTxt)
    set widgetFont $data(-font)
    set snipStr $data(-snipstring)
    set padY [expr {[$w cget -spacing1] == 0}]
    set row $index
    set line [expr {$index + 2}]
    foreach item $argList {
	#
	# Adjust and extend the item, and insert
	# the extended item into the internal list
	#
	set item [adjustItem $item $data(colCount)]
	set key hk[incr data(hdr_seqNum)]
	set extItem $item
	lappend extItem $key
	set data(hdr_itemList) [linsert $data(hdr_itemList) $row $extItem]
	set data(hdr_keyList) [linsert $data(hdr_keyList) $row $key]

	if {$data(hasFmtCmds)} {
	    set item [formatItem $win $key $row $item]
	}
	if {[string match "*\t*" $item]} {
	    set item [mapTabs $item]
	}

	$w insert $line.0 "\n"

	set multilineData {}
	set col 0
	set insertArgs {}
	foreach text $item \
		colFont $data(colFontList) \
		colTags $data(colTagsList) \
		{pixels alignment} $data(colList) {
	    if {$data($col-hide) && !$canElide} {
		incr col
		continue
	    }

	    #
	    # Update the column width or clip the element if necessary
	    #
	    set multiline [string match "*\n*" $text]
	    if {$pixels == 0} {			;# convention: dynamic width
		if {$multiline} {
		    set list [split $text "\n"]
		    set textWidth [getListWidth $win $list $colFont]
		} else {
		    set textWidth \
			[font measure $colFont -displayof $win $text]
		}
		if {$data($col-maxPixels) > 0} {
		    if {$textWidth > $data($col-maxPixels)} {
			set pixels $data($col-maxPixels)
		    }
		}
		if {$textWidth == $data($col-elemWidth)} {
		    incr data($col-widestCount)
		} elseif {$textWidth > $data($col-elemWidth)} {
		    set data($col-elemWidth) $textWidth
		    set data($col-widestCount) 1
		}
	    }
	    if {$pixels != 0} {
		incr pixels $data($col-delta)

		if {$data($col-wrap) && !$multiline} {
		    if {[font measure $colFont -displayof $win $text] >
			$pixels} {
			set multiline 1
		    }
		}

		set snipSide \
		    $snipSides($alignment,$data($col-changesnipside))
		if {$multiline} {
		    set list [split $text "\n"]
		    if {$data($col-wrap)} {
			set snipSide ""
		    }
		    set text [joinList $win $list $colFont \
			      $pixels $snipSide $snipStr]
		} else {
		    set text [strRange $win $text $colFont \
			      $pixels $snipSide $snipStr]
		}
	    }

	    if {$multiline} {
		lappend insertArgs "\t\t" $colTags
		lappend multilineData $col $text $colFont $pixels $alignment
	    } else {
		lappend insertArgs "\t$text\t" $colTags
	    }
	    incr col
	}

	#
	# Insert the item into the header text widget
	#
	if {[llength $insertArgs] != 0} {
	    eval [list $w insert $line.0] $insertArgs
	}

	#
	# Embed the message widgets displaying multiline elements
	#
	foreach {col text font pixels alignment} $multilineData {
	    findTabs $w $win $win $line $col $col tabIdx1 tabIdx2
	    set msgScript [list ::tablelist::displayText $win $key \
			   $col $text $font $pixels $alignment]
	    $w window create $tabIdx2 -align top -pady $padY -create $msgScript
	}

	lappend result $key

	incr row
	incr line
    }
    incr data(hdr_itemCount) $argCount
    set data(hdr_lastRow) [expr {$data(hdr_itemCount) - 1}]

    #
    # Check whether the width of any column has changed
    #
    set colWidthsChanged 0
    set col 0
    foreach {pixels alignment} $data(colList) {
	if {$pixels == 0} {			;# convention: dynamic width
	    if {$data($col-elemWidth) > $data($col-reqPixels)} {
		set data($col-reqPixels) $data($col-elemWidth)
		set colWidthsChanged 1
	    }
	}
	incr col
    }

    #
    # Adjust the columns if necessary and schedule
    # some operations for execution at idle time
    #
    if {$colWidthsChanged} {
	adjustColumns $win {} 1
    }
    updateViewWhenIdle $win

    return $result
}

#------------------------------------------------------------------------------
# tablelist::displayItems
#
# This procedure is invoked either as an idle callback after inserting some
# items into the internal list of the tablelist widget win, or directly, upon
# execution of some widget commands.  It displays the inserted items.
#------------------------------------------------------------------------------
proc tablelist::displayItems win {
    #
    # Nothing to do if there are no items to display
    #
    upvar ::tablelist::ns${win}::data data
    if {![info exists data(dispId)]} {
	return ""
    }

    #
    # Here we are in the case that the procedure was scheduled for
    # execution at idle time.  However, it might have been invoked
    # directly, before the idle time occured; in this case we should
    # cancel the execution of the previously scheduled idle callback.
    #
    after cancel $data(dispId)	;# no harm if data(dispId) is no longer valid
    unset data(dispId)

    #
    # Insert the items into the body text widget
    #
    variable canElide
    variable snipSides
    set w $data(body)
    set widgetFont $data(-font)
    set snipStr $data(-snipstring)
    set padY [expr {[$w cget -spacing1] == 0}]
    set wasEmpty [expr {[llength $data(rowsToDisplay)] == $data(itemCount)}]
    set isEmpty $wasEmpty
    foreach row $data(rowsToDisplay) {
	set line [expr {$row + 1}]
	set item [lindex $data(itemList) $row]
	set key [lindex $item end]

	#
	# Format the item
	#
	set dispItem [lrange $item 0 $data(lastCol)]
	if {$data(hasFmtCmds)} {
	    set dispItem [formatItem $win $key $row $dispItem]
	}
	if {[string match "*\t*" $dispItem]} {
	    set dispItem [mapTabs $dispItem]
	}

	if {$isEmpty} {
	    set isEmpty 0
	} else {
	    $w insert $line.0 "\n"
	}
	if {$data(nonViewableRowCount) != 0} {
	    $w tag remove elidedRow $line.0
	    $w tag remove hiddenRow $line.0
	}
	set multilineData {}
	set col 0
	if {$data(hasColTags)} {
	    set insertArgs {}
	    foreach text $dispItem \
		    colFont $data(colFontList) \
		    colTags $data(colTagsList) \
		    {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Update the column width or clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$multiline} {
			set list [split $text "\n"]
			set textWidth [getListWidth $win $list $colFont]
		    } else {
			set textWidth \
			    [font measure $colFont -displayof $win $text]
		    }
		    if {$data($col-maxPixels) > 0} {
			if {$textWidth > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		    if {$textWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$textWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $textWidth
			set data($col-widestCount) 1
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $colFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    set snipSide \
			$snipSides($alignment,$data($col-changesnipside))
		    if {$multiline} {
			set list [split $text "\n"]
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $colFont \
				  $pixels $snipSide $snipStr]
		    } elseif {$data(-displayondemand)} {
			set text ""
		    } else {
			set text [strRange $win $text $colFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		if {$multiline} {
		    lappend insertArgs "\t\t" $colTags
		    lappend multilineData $col $text $colFont $pixels $alignment
		} else {
		    lappend insertArgs "\t$text\t" $colTags
		}
		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    if {[llength $insertArgs] != 0} {
		eval [list $w insert $line.0] $insertArgs
	    }

	} else {
	    set insertStr ""
	    foreach text $dispItem {pixels alignment} $data(colList) {
		if {$data($col-hide) && !$canElide} {
		    incr col
		    continue
		}

		#
		# Update the column width or clip the element if necessary
		#
		set multiline [string match "*\n*" $text]
		if {$pixels == 0} {		;# convention: dynamic width
		    if {$multiline} {
			set list [split $text "\n"]
			set textWidth [getListWidth $win $list $widgetFont]
		    } else {
			set textWidth \
			    [font measure $widgetFont -displayof $win $text]
		    }
		    if {$data($col-maxPixels) > 0} {
			if {$textWidth > $data($col-maxPixels)} {
			    set pixels $data($col-maxPixels)
			}
		    }
		    if {$textWidth == $data($col-elemWidth)} {
			incr data($col-widestCount)
		    } elseif {$textWidth > $data($col-elemWidth)} {
			set data($col-elemWidth) $textWidth
			set data($col-widestCount) 1
		    }
		}
		if {$pixels != 0} {
		    incr pixels $data($col-delta)

		    if {$data($col-wrap) && !$multiline} {
			if {[font measure $widgetFont -displayof $win $text] >
			    $pixels} {
			    set multiline 1
			}
		    }

		    set snipSide \
			$snipSides($alignment,$data($col-changesnipside))
		    if {$multiline} {
			set list [split $text "\n"]
			if {$data($col-wrap)} {
			    set snipSide ""
			}
			set text [joinList $win $list $widgetFont \
				  $pixels $snipSide $snipStr]
		    } elseif {$data(-displayondemand)} {
			set text ""
		    } else {
			set text [strRange $win $text $widgetFont \
				  $pixels $snipSide $snipStr]
		    }
		}

		if {$multiline} {
		    append insertStr "\t\t"
		    lappend multilineData $col $text $widgetFont \
					  $pixels $alignment
		} else {
		    append insertStr "\t$text\t"
		}
		incr col
	    }

	    #
	    # Insert the item into the body text widget
	    #
	    $w insert $line.0 $insertStr
	}

	#
	# Embed the message widgets displaying multiline elements
	#
	foreach {col text font pixels alignment} $multilineData {
	    findTabs $win $w $line $col $col tabIdx1 tabIdx2
	    set msgScript [list ::tablelist::displayText $win $key \
			   $col $text $font $pixels $alignment]
	    $w window create $tabIdx2 -align top -pady $padY -create $msgScript
	    $w tag add elidedWin $tabIdx2
	}
    }
    unset data(rowsToDisplay)

    #
    # Adjust the heights of the body text widget
    # and of the listbox child, if necessary
    #
    if {$data(-height) <= 0} {
	set viewableRowCount \
	    [expr {$data(itemCount) - $data(nonViewableRowCount)}]
	$w configure -height $viewableRowCount
	$data(lb) configure -height $viewableRowCount
    }

    #
    # Check whether the width of any column has changed
    #
    set colWidthsChanged 0
    set col 0
    foreach {pixels alignment} $data(colList) {
	if {$pixels == 0} {			;# convention: dynamic width
	    if {$data($col-elemWidth) > $data($col-reqPixels)} {
		set data($col-reqPixels) $data($col-elemWidth)
		set colWidthsChanged 1
	    }
	}
	incr col
    }

    #
    # Invalidate the list of row indices indicating the
    # viewable rows, adjust the columns if necessary, and
    # schedule some operations for execution at idle time
    #
    set data(viewableRowList) {-1}
    if {$colWidthsChanged} {
	adjustColumns $win {} 1
    }
    makeStripesWhenIdle $win
    showLineNumbersWhenIdle $win
    updateViewWhenIdle $win

    if {$wasEmpty} {
	$w xview moveto [lindex [$data(hdrTxt) xview] 0]
    }
}

#------------------------------------------------------------------------------
# tablelist::insertCols
#
# Processes the tablelist insertcolumns and insertcolumnlist subcommands.
#------------------------------------------------------------------------------
proc tablelist::insertCols {win colIdx argList} {
    set argCount [llength $argList]
    if {$argCount == 0} {
	return ""
    }

    upvar ::tablelist::ns${win}::data data \
	  ::tablelist::ns${win}::attribs attribs

    #
    # Check the syntax of argList and get the number of columns to be inserted
    #
    variable alignments
    set count 0
    for {set n 0} {$n < $argCount} {incr n} {
	#
	# Check the column width
	#
	format "%d" [lindex $argList $n]    ;# integer check with error message

	#
	# Check whether the column title is present
	#
	if {[incr n] == $argCount} {
	    return -code error "column title missing"
	}

	#
	# Check the column alignment
	#
	set alignment left
	if {[incr n] < $argCount} {
	    set next [lindex $argList $n]
	    if {[isInteger $next]} {
		incr n -1
	    } else {
		mwutil::fullOpt "alignment" $next $alignments
	    }
	}

	incr count
    }

    #
    # Shift the elements of data and attribs corresponding to the
    # column indices >= colIdx to the right by count positions
    #
    set selCells [curCellSelection $win]
    for {set oldCol $data(lastCol); set newCol [expr {$oldCol + $count}]} \
	{$oldCol >= $colIdx} {incr oldCol -1; incr newCol -1} {
	moveColData data data imgs $oldCol $newCol
	moveColAttribs attribs attribs $oldCol $newCol
	set selCells [replaceColInCellList $selCells $oldCol $newCol]
    }

    #
    # Update the item list
    #
    set emptyStrs {}
    for {set n 0} {$n < $count} {incr n} {
	lappend emptyStrs ""
    }
    set newItemList {}
    foreach item $data(itemList) {
	set item [eval [list linsert $item $colIdx] $emptyStrs]
	lappend newItemList $item
    }
    set data(itemList) $newItemList

    #
    # Update the list variable if present
    #
    condUpdateListVar $win

    #
    # Set up and adjust the columns, and rebuild some columns-related lists
    #
    setupColumns $win \
	[eval [list linsert $data(-columns) [expr {3*$colIdx}]] $argList] 1
    makeColFontAndTagLists $win
    makeSortAndArrowColLists $win
    set limit [expr {$colIdx + $count}]
    set colIdxList {}
    for {set col $colIdx} {$col < $limit} {incr col} {
	lappend colIdxList $col
    }
    adjustColumns $win $colIdxList 1

    #
    # Redisplay the items
    #
    redisplay $win 0 $selCells

    #
    # Reconfigure the relevant column labels
    #
    for {set col $limit} {$col < $data(colCount)} {incr col} {
	reconfigColLabels $win imgs $col
    }

    #
    # Update the indices anchorCol and activeCol
    #
    if {$colIdx <= $data(anchorCol)} {
	incr data(anchorCol) $argCount
	adjustColIndex $win data(anchorCol) 1
    }
    if {$colIdx <= $data(activeCol)} {
	incr data(activeCol) $argCount
	adjustColIndex $win data(activeCol) 1
    }

    updateViewWhenIdle $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::doScan
#
# Processes the tablelist scan subcommand.
#------------------------------------------------------------------------------
proc tablelist::doScan {win opt x y} {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    incr x -[winfo x $w]
    incr y -[winfo y $w]

    if {$data(-titlecolumns) == 0} {
	set textIdx [$data(body) index @0,$y]
	set row [expr {int($textIdx) - 1}]
	$w scan $opt $x $y
	$data(hdrTxt) scan $opt $x 0

	if {[string compare $opt "dragto"] == 0} {
	    hdr_adjustElidedText $win
	    hdr_updateColors $win
	    adjustElidedText $win
	    redisplayVisibleItems $win
	    updateColors $win
	    adjustSepsWhenIdle $win
	    updateVScrlbarWhenIdle $win
	    updateIdletasksDelayed 
	}
    } elseif {[string compare $opt "mark"] == 0} {
	$w scan mark 0 $y

	set data(scanMarkX) $x
	set data(scanMarkXOffset) \
	    [scrlColOffsetToXOffset $win $data(scrlColOffset)]
    } else {
	set textIdx [$data(body) index @0,$y]
	set row [expr {int($textIdx) - 1}]
	$w scan dragto 0 $y

	#
	# Compute the new scrolled x offset by amplifying the
	# difference between the current horizontal position and
	# the place where the scan started (the "mark" position)
	#
	set scrlXOffset \
	    [expr {$data(scanMarkXOffset) - 10*($x - $data(scanMarkX))}]
	set maxScrlXOffset [scrlColOffsetToXOffset $win \
			    [getMaxScrlColOffset $win]]
	if {$scrlXOffset > $maxScrlXOffset} {
	    set scrlXOffset $maxScrlXOffset
	    set data(scanMarkX) $x
	    set data(scanMarkXOffset) $maxScrlXOffset
	} elseif {$scrlXOffset < 0} {
	    set scrlXOffset 0
	    set data(scanMarkX) $x
	    set data(scanMarkXOffset) 0
	}

	#
	# Change the scrolled column offset and adjust the elided text
	#
	changeScrlColOffset $win [scrlXOffsetToColOffset $win $scrlXOffset]
	hdr_adjustElidedText $win
	hdr_updateColors $win
	adjustElidedText $win
	redisplayVisibleItems $win
	updateColors $win
	adjustSepsWhenIdle $win
	updateVScrlbarWhenIdle $win
	updateIdletasksDelayed 
    }

    return ""
}

#------------------------------------------------------------------------------
# tablelist::populate
#
# Helper procedure invoked in searchcolumnSubCmd.
#------------------------------------------------------------------------------
proc tablelist::populate {win index fully} {
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    set col $data(treeCol)
    if {![info exists data($key,$col-indent)] ||
	[string match "*indented*" $data($key,$col-indent)]} {
	return ""
    }

    if {[llength $data($key-children)] == 0} {
	uplevel #0 $data(-populatecommand) [list $win $index]
    }

    if {$fully} {
	#
	# Invoke this procedure recursively on the children
	#
	foreach childKey $data($key-children) {
	    populate $win [keyToRow $win $childKey] 1
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::doesMatch
#
# Helper procedure invoked in searchcolumnSubCmd.
#------------------------------------------------------------------------------
proc doesMatch {win row col pattern value mode numeric noCase checkCmd} {
    switch -- $mode {
	-exact {
	    if {$numeric} {
		set result [expr {$pattern == $value}]
	    } else {
		if {$noCase} {
		    set value [string tolower $value]
		}
		set result [expr {[string compare $pattern $value] == 0}]
	    }
	}

	-glob {
	    if {$noCase} {
		set value [string tolower $value]
	    }
	    set result [string match $pattern $value]
	}

	-regexp {
	    if {$noCase} {
		set result [regexp -nocase $pattern $value]
	    } else {
		set result [regexp $pattern $value]
	    }
	}
    }

    if {!$result || [string length $checkCmd] == 0} {
	return $result
    } else {
	return [uplevel #0 $checkCmd [list $win $row $col $value]]
    }
}

#------------------------------------------------------------------------------
# tablelist::seeRow
#
# Processes the tablelist see subcommand.
#------------------------------------------------------------------------------
proc tablelist::seeRow {win index} {
    #
    # This might be an "after 0" callback; check whether the window exists
    #
    if {[destroyed $win]} {
	return ""
    }

    #
    # Adjust the index to fit within the existing items
    #
    adjustRowIndex $win index
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $index]
    if {$data(itemCount) == 0 || [info exists data($key-hide)]} {
	return ""
    }

    #
    # Expand as many ancestors as needed
    #
    while {[info exists data($key-elide)]} {
	set key $data($key-parent)
	expandSubCmd $win [list $key -partly]
    }

    #
    # Bring the given row into the window and restore
    # the horizontal view in the body text widget
    #
    if {![seeTextIdx $win [expr {$index + 1}].0]} {
	return ""
    }
    $data(body) xview moveto [lindex [$data(hdrTxt) xview] 0]

    updateView $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::seeCell
#
# Processes the tablelist seecell subcommand.
#------------------------------------------------------------------------------
proc tablelist::seeCell {win row col} {
    #
    # This might be an "after 0" callback; check whether the window exists
    #
    if {[destroyed $win]} {
	return ""
    }

    #
    # Adjust the row and column indices to fit within the existing elements
    #
    adjustRowIndex $win row
    adjustColIndex $win col
    upvar ::tablelist::ns${win}::data data
    set key [lindex $data(keyList) $row]
    if {[info exists data($key-hide)] ||
	($data(colCount) != 0 && $data($col-hide))} {
	return ""
    }

    #
    # Expand as many ancestors as needed
    #
    while {[info exists data($key-elide)]} {
	set key $data($key-parent)
	expandSubCmd $win [list $key -partly]
    }

    set b $data(body)
    if {$data(colCount) == 0} {
	$b see [expr {$row + 1}].0
	return ""
    }

    #
    # Force any geometry manager calculations to be completed first
    #
    update idletasks
    if {[destroyed $win]} {
	return ""
    }

    #
    # If the tablelist is empty then insert a temporary row
    #
    set h $data(hdrTxt)
    if {$data(itemCount) == 0} {
	variable canElide
	for {set n 0} {$n < $data(colCount)} {incr n} {
	    if {!$data($n-hide) || $canElide} {
		$b insert end "\t\t"
	    }
	}

	$b xview moveto [lindex [$h xview] 0]
    }

    if {$data(-titlecolumns) == 0} {
	findTabs $win $b [expr {$row + 1}] $col $col tabIdx1 tabIdx2
	variable pu
	set nextIdx [$b index $tabIdx2+1$pu]
	set alignment [lindex $data(colList) [expr {2*$col + 1}]]
	set lX [winfo x $data(hdrTxtFrmLbl)$col]
	set rX [expr {$lX + [winfo width $data(hdrTxtFrmLbl)$col] - 1}]

	switch $alignment {
	    left {
		#
		# Bring the cell's left edge into view
		#
		if {![seeTextIdx $win $tabIdx1]} {
		    return ""
		}
		$h xview moveto [lindex [$b xview] 0]

		#
		# Shift the view in the header text widget until the right
		# edge of the cell becomes visible but finish the scrolling
		# before the cell's left edge would become invisible
		#
		while {![isHdrTxtFrXPosVisible $win $rX]} {
		    $h xview scroll 1 units
		    if {![isHdrTxtFrXPosVisible $win $lX]} {
			$h xview scroll -1 units
			break
		    }
		}
	    }

	    center {
		#
		# Bring the cell's left edge into view
		#
		if {![seeTextIdx $win $tabIdx1]} {
		    return ""
		}
		set winWidth [winfo width $h]
		if {[winfo width $data(hdrTxtFrmLbl)$col] > $winWidth} {
		    #
		    # The cell doesn't fit into the window:  Bring its
		    # center into the window's middle horizontal position
		    #
		    $h xview moveto \
		       [expr {double($lX + $rX - $winWidth)/2/$data(hdrWidth)}]
		} else {
		    #
		    # Shift the view in the header text widget until
		    # the right edge of the cell becomes visible
		    #
		    $h xview moveto [lindex [$b xview] 0]
		    while {![isHdrTxtFrXPosVisible $win $rX]} {
			$h xview scroll 1 units
		    }
		}
	    }

	    right {
		#
		# Bring the cell's right edge into view
		#
		if {![seeTextIdx $win $nextIdx]} {
		    return ""
		}
		$h xview moveto [lindex [$b xview] 0]

		#
		# Shift the view in the header text widget until the left
		# edge of the cell becomes visible but finish the scrolling
		# before the cell's right edge would become invisible
		#
		while {![isHdrTxtFrXPosVisible $win $lX]} {
		    $h xview scroll -1 units
		    if {![isHdrTxtFrXPosVisible $win $rX]} {
			$h xview scroll 1 units
			break
		    }
		}
	    }
	}

	$b xview moveto [lindex [$h xview] 0]

    } else {
	#
	# Bring the cell's row into view
	#
	if {![seeTextIdx $win [expr {$row + 1}].0]} {
	    return ""
	}

	set scrlWindowWidth [getScrlWindowWidth $win]

	if {($col < $data(-titlecolumns)) ||
	    (!$data($col-elide) &&
	     [getScrlContentWidth $win $data(scrlColOffset) $col] <=
	     $scrlWindowWidth)} {
	    #
	    # The given column index specifies either a title column or
	    # one that is fully visible; restore the horizontal view
	    #
	    $b xview moveto [lindex [$h xview] 0]
	} elseif {$data($col-elide) ||
		  [winfo width $data(hdrTxtFrmLbl)$col] > $scrlWindowWidth} {
	    #
	    # The given column index specifies either an elided column or one
	    # that doesn't fit into the window; shift the horizontal view to
	    # make the column the first visible one among all scrollable columns
	    #
	    set scrlColOffset 0
	    for {incr col -1} {$col >= $data(-titlecolumns)} {incr col -1} {
		if {!$data($col-hide)} {
		    incr scrlColOffset
		}
	    }
	    changeScrlColOffset $win $scrlColOffset
	} else {
	    #
	    # The given column index specifies a non-elided
	    # scrollable column; shift the horizontal view
	    # repeatedly until the column becomes visible
	    #
	    set scrlColOffset [expr {$data(scrlColOffset) + 1}]
	    while {[getScrlContentWidth $win $scrlColOffset $col] >
		   $scrlWindowWidth} {
		incr scrlColOffset
	    }
	    changeScrlColOffset $win $scrlColOffset
	}
    }

    #
    # Delete the temporary row if any
    #
    if {$data(itemCount) == 0} {
	$b delete 1.0 end
    }

    updateView $win
    return ""
}

#------------------------------------------------------------------------------
# tablelist::rowSelection
#
# Processes the tablelist selection subcommand.
#------------------------------------------------------------------------------
proc tablelist::rowSelection {win opt first last} {
    upvar ::tablelist::ns${win}::data data
    if {$data(isDisabled) && [string compare $opt "includes"] != 0} {
	return ""
    }

    switch $opt {
	anchor {
	    #
	    # Adjust the index to fit within the existing viewable items
	    #
	    adjustRowIndex $win first 1

	    set data(anchorRow) $first
	    return ""
	}

	clear {
	    #
	    # Swap the indices if necessary
	    #
	    if {$last < $first} {
		set tmp $first
		set first $last
		set last $tmp
	    }

	    set fromTextIdx [expr {$first + 1}].0
	    set toTextIdx [expr {$last + 1}].end
	    $data(body) tag remove select $fromTextIdx $toTextIdx

	    updateColorsWhenIdle $win
	    return ""
	}

	includes {
	    set w $data(body)
	    set line [expr {$first + 1}]
	    set selRange [$w tag nextrange select $line.0 $line.end]
	    return [expr {[llength $selRange] > 0}]
	}

	set {
	    #
	    # Swap the indices if necessary and adjust
	    # the range to fit within the existing items
	    #
	    if {$last < $first} {
		set tmp $first
		set first $last
		set last $tmp
	    }
	    if {$first < 0} {
		set first 0
	    }
	    if {$last > $data(lastRow)} {
		set last $data(lastRow)
	    }

	    set w $data(body)
	    variable canElide
	    variable elide
	    for {set row $first; set line [expr {$first + 1}]} \
		{$row <= $last} {set row $line; incr line} {
		#
		# Check whether the row is selectable
		#
		set key [lindex $data(keyList) $row]
		if {![info exists data($key-selectable)]} {
		    $w tag add select $line.0 $line.end
		}
	    }

	    #
	    # If the selection is exported and there are any selected
	    # cells in the widget then make win the new owner of the
	    # PRIMARY selection and register a callback to be invoked
	    # when it loses ownership of the PRIMARY selection
	    #
	    if {$data(-exportselection) &&
		[llength [$w tag nextrange select 1.0]] != 0} {
		selection own -command \
		    [list ::tablelist::lostSelection $win] $win
	    }

	    updateColorsWhenIdle $win
	    return ""
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::horizMoveTo
#
# Adjusts the view in the tablelist window win so that data(fraction) of the
# horizontal span of the text is off-screen to the left.
#------------------------------------------------------------------------------
proc tablelist::horizMoveTo win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(moveToId)]} {
	after cancel $data(moveToId)
	unset data(moveToId)
    }

    foreach w [list $data(hdrTxt) $data(body)] {
	$w xview moveto $data(fraction)
    }

    redisplayVisibleItems $win
    updateColors $win
}

#------------------------------------------------------------------------------
# tablelist::vertMoveTo
#
# Adjusts the view in the tablelist window win so that the non-hidden item
# given by data(fraction) appears at the top of the window.
#------------------------------------------------------------------------------
proc tablelist::vertMoveTo win {
    upvar ::tablelist::ns${win}::data data
    if {[info exists data(moveToId)]} {
	after cancel $data(moveToId)
	unset data(moveToId)
    }

    set totalViewableCount [getViewableRowCount $win 0 $data(lastRow)]
    set offset [expr {int($data(fraction)*$totalViewableCount + 0.5)}]
    set row [viewableRowOffsetToRowIndex $win $offset]

    set w $data(body)
    set topRow [getVertComplTopRow $win]

    if {$row != $topRow} {
	$w yview $row
	updateView $win
	updateIdletasksDelayed 
    }
}

#------------------------------------------------------------------------------
# tablelist::seeTextIdx
#
# Wraps the "see" command of the body text widget of the tablelist widget win.
#------------------------------------------------------------------------------
proc tablelist::seeTextIdx {win textIdx} {
    upvar ::tablelist::ns${win}::data data
    set w $data(body)
    $w see $textIdx

    if {[llength [$w tag nextrange elidedWin 1.0]] == 0} {
	return 1
    }

    set fromTextIdx "[$w index @0,0] linestart"
    set toTextIdx "[$w index @0,$data(btmY)] lineend"
    $w tag remove elidedWin $fromTextIdx $toTextIdx
    update idletasks
    if {[destroyed $win]} {
	return 0
    }

    $w see $textIdx
    return 1
}

#------------------------------------------------------------------------------
# tablelist::updateIdletasksDelayed
#
# Schedules the execution of "update idletasks" 100 ms later.
#------------------------------------------------------------------------------
proc tablelist::updateIdletasksDelayed {} {
    variable idletasksId
    if {![info exists idletasksId]} {
	set idletasksId [after 100 [list tablelist::updateIdletasks]]
    }
}

#------------------------------------------------------------------------------
# tablelist::updateIdletasks
#
# Invokes "update idletasks".
#------------------------------------------------------------------------------
proc tablelist::updateIdletasks {} {
    variable idletasksId
    if {[info exists idletasksId]} {
	after cancel $idletasksId
	unset idletasksId
    }

    update idletasks
}

#
# Private callback procedures
# ===========================
#

#------------------------------------------------------------------------------
# tablelist::hdrConfigure
#
# <Configure> callback for the header component of a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::hdrConfigure {w width} {
    set win [winfo parent $w]
    upvar ::tablelist::ns${win}::data data

    if {$width - 1 != $data(rightX)} {
	stretchColumnsWhenIdle $win
	updateScrlColOffsetWhenIdle $win
	updateHScrlbarWhenIdle $win
    }
}

#------------------------------------------------------------------------------
# tablelist::bodyConfigure
#
# <Configure> callback for the body component of a tablelist widget.
#------------------------------------------------------------------------------
proc tablelist::bodyConfigure {w width height} {
    set win [winfo parent $w]
    upvar ::tablelist::ns${win}::data data

    set rightX [expr {$width - 1}]
    set btmY [expr {$height - 1}]
    if {$rightX != $data(rightX) || $btmY != $data(btmY)} {
	set data(gotResizeEvent) 1
	set data(rightX) $rightX
	set data(btmY) $btmY

	makeColFontAndTagLists $win
	updateViewWhenIdle $win
    }
}

#------------------------------------------------------------------------------
# tablelist::fetchSelection
#
# This procedure is invoked when the PRIMARY selection is owned by the
# tablelist widget win and someone attempts to retrieve it as a STRING.  It
# returns part or all of the selection, as given by offset and maxChars.  The
# string which is to be (partially) returned is built by joining all of the
# selected viewable elements of the (partly) selected viewable rows together
# with tabs and the rows themselves with newlines.
#------------------------------------------------------------------------------
proc tablelist::fetchSelection {win offset maxChars} {
    upvar ::tablelist::ns${win}::data data
    if {!$data(-exportselection)} {
	return ""
    }

    set selection ""
    set prevRow -1
    foreach cellIdx [curCellSelection $win 0 2] {
	scan $cellIdx "%d,%d" row col
	if {$row != $prevRow} {
	    if {$prevRow != -1} {
		append selection "\n"
	    }

	    set prevRow $row
	    set item [lindex $data(itemList) $row]
	    set key [lindex $item end]
	    set isFirstCol 1
	}

	set text [lindex $item $col]
	if {[lindex $data(fmtCmdFlagList) $col]} {
	    set text [formatElem $win $key $row $col $text]
	}

	if {!$isFirstCol} {
	    append selection "\t"
	}
	append selection $text

	set isFirstCol 0
    }

    return [string range $selection $offset [expr {$offset + $maxChars - 1}]]
}

#------------------------------------------------------------------------------
# tablelist::lostSelection
#
# This procedure is invoked when the tablelist widget win loses ownership of
# the PRIMARY selection.  It deselects all items of the widget with the aid of
# the rowSelection procedure if the selection is exported.
#------------------------------------------------------------------------------
proc tablelist::lostSelection win {
    upvar ::tablelist::ns${win}::data data
    if {$data(-exportselection)} {
	rowSelection $win clear 0 $data(lastRow)
	event generate $win <<TablelistSelectionLost>>
    }
}

#------------------------------------------------------------------------------
# tablelist::activeTrace
#
# This procedure is executed whenever the array element data(activeRow),
# data(activeCol), or data(-selecttype) is written.  It moves the "active" tag
# to the line or cell that displays the active item or element of the widget in
# its body text child if the latter has the keyboard focus.
#------------------------------------------------------------------------------
proc tablelist::activeTrace {win varName arrIndex op} {
    #
    # Conditionally move the "active" tag to the line
    # or cell that displays the active item or element
    #
    upvar ::tablelist::ns${win}::data data
    if {$data(ownsFocus) && ![info exists data(dispId)]} {
	moveActiveTag $win
    }
}

#------------------------------------------------------------------------------
# tablelist::listVarTrace
#
# This procedure is executed whenever the global variable specified by varName
# is written or unset.  It makes sure that the content of the widget will be
# synchronized with the value of the variable at idle time, and that the
# variable is recreated if it was unset.
#------------------------------------------------------------------------------
proc tablelist::listVarTrace {win varName arrIndex op} {
    upvar ::tablelist::ns${win}::data data
    switch $op {
	w {
	    if {![info exists data(syncId)]} {
		#
		# Arrange for the content of the widget to be synchronized
		# with the value of the variable ::$varName at idle time
		#
		set data(syncId) [after idle [list tablelist::synchronize $win]]
	    }
	}

	u {
	    #
	    # Recreate the variable ::$varName by setting it according to
	    # the value of data(itemList), and set the trace on it again
	    #
	    if {[string length $arrIndex] != 0} {
		set varName ${varName}($arrIndex)
	    }
	    set ::$varName {}
	    foreach item $data(itemList) {
		lappend ::$varName [lrange $item 0 $data(lastCol)]
	    }
	    trace variable ::$varName wu $data(listVarTraceCmd)
	}
    }
}

#------------------------------------------------------------------------------
# tablelist::checkStatesTrace
#
# This procedure is executed whenever an element of the array checkStates is
# written.  It updates the corresponding tablelist element at idle time.
#------------------------------------------------------------------------------
proc tablelist::checkStatesTrace {win varName arrIndex op} {
    #
    # $arrIndex is is a cell index of the form <key>,<col>
    #
    upvar $varName var
    if {[string match "h*" $arrIndex]} {
	after idle \
	    [list ::$win header cellconfigure $arrIndex -text $var($arrIndex)]
    } else {
	after idle [list ::$win cellconfigure $arrIndex -text $var($arrIndex)]
    }
}

Added libs/tablelist6.0/scripts/tclIndex.

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
# Tcl autoload index file, version 2.0
# This file is generated by the "auto_mkindex" command
# and sourced to set up indexing information for one or
# more commands.  Typically each line is a command that
# sets an element in the auto_index array, where the
# element name is the name of a command and the value is
# a script that loads the command.

set auto_index(::tablelist::addTkCoreWidgets) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addTileWidgets) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addBWidgetEntry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addBWidgetSpinBox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addBWidgetComboBox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrEntryfield) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrDateTimeWidget) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrSpinner) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrSpinint) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIncrCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addCtext) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addOakleyCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addDateMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addTimeMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addDateTimeMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addFixedPointMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIPAddrMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::addIPv6AddrMentry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::checkEditWinName) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createCheckbutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createMenubutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::postMenuCmd) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileEntry) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileSpinbox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileCheckbutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createTileMenubutton) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createBWidgetComboBox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createIncrCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::createOakleyCombobox) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::doEditCell) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::doCancelEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::doFinishEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::clearTakefocusOpt) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::adjustTextHeight) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::setMentryCursor) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::adjustEditWindow) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::setEditWinFont) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::saveEditData) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::saveEditConfigOpts) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::restoreEditData) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::restoreEditConfigOpts) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::defineTablelistEdit) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::insertChar) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::cancelEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::finishEditing) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goToNextPrevCell) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goLeftRight) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goUpDown) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goToPrevNextLine) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::goToPriorNextPage) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::genMouseWheelEvent) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::genOptionMouseWheelEvent) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::isKeyReserved) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::hasMouseWheelBindings) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::isComboTopMapped) [list source [file join $dir tablelistEdit.tcl]]
set auto_index(::tablelist::setThemeDefaults) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::altTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::aquaTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::AquativoTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::aquativoTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::ArcTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::blueTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::clamTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::classicTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::clearlooksTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::defaultTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::keramikTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::keramik_altTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::krocTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::plastikTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::srivTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::srivlgTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::stepTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::tileqtTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::vistaTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::winnativeTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::winxpblueTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::xpnativeTheme) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::rgb2hsv) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::hsv2rgb) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::getKdeConfigVal) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::makeKdeDirList) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::readKdeConfigVal) [list source [file join $dir tablelistThemes.tcl]]
set auto_index(::tablelist::sortByColumn) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::addToSortColumns) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::sortItems) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::sortChildren) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::sortList) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::compareNoCase) [list source [file join $dir tablelistSort.tcl]]
set auto_index(::tablelist::moveRow) [list source [file join $dir tablelistMove.tcl]]
set auto_index(::tablelist::moveNode) [list source [file join $dir tablelistMove.tcl]]
set auto_index(::tablelist::moveCol) [list source [file join $dir tablelistMove.tcl]]
set auto_index(::mwutil::makeFocusProcs) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::getChildren) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::wrongNumArgs) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::getAncestorByClass) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::convEventFields) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::defineKeyNav) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::processTraversal) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::configureWidget) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::fullConfigOpt) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::fullOpt) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::enumOpts) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::configureSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::attribSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::hasattribSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::unsetattribSubCmd) [list source [file join $dir mwutil.tcl]]
set auto_index(::mwutil::getScrollInfo) [list source [file join $dir mwutil.tcl]]
set auto_index(::tablelist::getCurrentTheme) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::destroyed) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::rowIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_rowIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::colIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::cellIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_cellIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustRowIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustColIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::nodeIndexToKey) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::depth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::topLevelKey) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::descCount) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::nodeRow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::keyToRow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_keyToRow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateKeyToRowMap) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::findTabs) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::sortStretchableColList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::deleteColData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::deleteColAttribs) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::moveColData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::moveColAttribs) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::deleteColFromCellList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::extractColFromCellList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::replaceColInCellList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::condUpdateListVar) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::reconfigColLabels) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::charsToPixels) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::strRange) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustItem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::formatElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::formatItem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hasChars) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getListWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::joinList) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::displayIndent) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::displayImage) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::displayText) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getAuxData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getIndentData) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getMaxTextWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustMlElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getElemWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::insertOrUpdateIndent) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::insertElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::insertMlElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateCell) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateMlCell) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::setImgLabelWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::setImgLabelAnchor) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::appendComplexElem) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeColFontAndTagLists) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeSortAndArrowColLists) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::setupColumns) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::createSeps) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustSepsWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustSeps) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getSepX) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustColumns) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustLabel) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::computeColWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::computeLabelWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustHeaderHeight) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::stretchColumnsWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::stretchColumns) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::moveActiveTag) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateColorsWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateColors) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_updateColorsWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_updateColors) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateScrlColOffsetWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateScrlColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateHScrlbarWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateHScrlbar) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateVScrlbarWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateVScrlbar) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::forceRedraw) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::purgeWidgets) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::adjustElidedText) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_adjustElidedText) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplay) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayVisibleItems) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayColWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::redisplayCol) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeStripesWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeStripes) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::showLineNumbersWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::showLineNumbers) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateViewWhenIdle) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::updateView) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::destroyWidgets) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::synchronize) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getSublabels) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::parseLabelPath) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::configLabel) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::createArrows) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::configCanvas) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::fillArrows) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getShadows) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::raiseArrow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::isHdrTxtFrXPosVisible) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getScrlContentWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getScrlWindowWidth) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getMaxScrlColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::changeScrlColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::scrlXOffsetToColOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::scrlColOffsetToXOffset) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getVertComplTopRow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getVertComplBtmRow) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getViewableRowCount) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::viewableRowOffsetToRowIndex) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::createFrameWithCheckbutton) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_createFrameWithCheckbutton) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeCheckbutton) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::createFrameWithTileCheckbutton) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::hdr_createFrameWithTileCheckbutton) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::makeTileCheckbutton) [list source [file join $dir tablelistUtil.tcl]]
set auto_index(::tablelist::getTablelistColumn) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::getTablelistPath) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::convEventFields) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::delaySashPosUpdates) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::addActiveTag) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::removeActiveTag) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cleanup) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateCanvases) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateConfigSpecs) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cleanupWindow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistBody) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::invokeMotionHandler) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::handleMotionDelayed) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::handleMotion) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::showOrHideTooltip) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateExpCollCtrl) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::updateCursor) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::makeEditCursor) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::wasExpCollCtrlClicked) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condEditContainingCell) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condBeginMove) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::beginSelect) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condAutoScan) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::autoScan) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::minScrollableX) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::motion) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condShowTarget) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::moveOrActivate) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condEvalInvokeCmd) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cancelMove) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::beginExtend) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::beginToggle) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condEditActiveCell) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::plusMinus) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::nextPrevCell) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::upDown) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::leftRight) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::priorNext) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::homeEnd) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::firstLast) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendUpDown) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendLeftRight) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendToHomeEnd) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendToFirstLast) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cancelSelection) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::selectAll) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::isDragSrc) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::normalizedRect) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::cellInRect) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::firstViewableRow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::lastViewableRow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::firstViewableCol) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::lastViewableCol) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::condChangeSelection) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::changeSelection) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistHeader) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::hdr_handleMotionDelayed) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::hdr_handleMotion) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::hdr_showOrHideTooltip) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistLabel) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistSubLabel) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::defineTablelistArrow) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelEnter) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelLeave) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Down) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Motion) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Enter) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Leave) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB1Up) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelB3Down) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::labelDblB1) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::escape) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::horizAutoScan) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::inResizeArea) [list source [file join $dir tablelistBind.tcl]]
set auto_index(::tablelist::extendConfigSpecs) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doColConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doColCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doRowConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doRowCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doCellConfig) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::doCellCget) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::makeListVar) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::isRowViewable) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::getCellFont) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::reconfigWindows) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::isCellEditable) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::getEditWindow) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::getVAlignment) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::getConfigParams) [list source [file join $dir tablelistConfig.tcl]]
set auto_index(::tablelist::flat5x3Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat5x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat6x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat7x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat7x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat7x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat8x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat8x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat9x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat9x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat11x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flat15x8Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle7x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle7x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle9x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle9x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle9x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle10x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle10x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle11x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::flatAngle15x8Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo7x4Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo7x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo9x5Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo11x6Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::photo15x8Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::sunken8x7Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::sunken10x9Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::sunken12x11Arrows) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createSortRankImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createCheckbuttonImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::adwaitaTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ambianceTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::aquaTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::arcTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::baghiraTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor3TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::bicolor4TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::blueMentaTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic3TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::classic4TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::dustTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::dustSandTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::gtkTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::klearlooksTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::mateTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::mentaTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::mintTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::mint2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::newWaveTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::oxygen1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::oxygen2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::phaseTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain1TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain3TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plain4TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plastikTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::plastiqueTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::radianceTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ubuntuTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ubuntu2TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ubuntu3TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::ubuntuMateTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_100) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_125) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_150) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaAeroTreeImgs_200) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_100) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_125) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_150) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::vistaClassicTreeImgs_200) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win7AeroTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win7ClassicTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_100) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_125) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_150) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::win10TreeImgs_200) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winnativeTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winxpBlueTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winxpOliveTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::winxpSilverTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::yuyoTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createTreeImgs) [list source [file join $dir tablelistImages.tcl]]
set auto_index(::tablelist::createTileAliases) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::restrictCmdOpts) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::restrictArrowStyles) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::createBindings) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::tablelist) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::tablelistWidgetCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::activateSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::activatecellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::applysortingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::attribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::bboxSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::bodypathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::bodytagSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cancelededitingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::canceleditingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellbboxSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellcgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellindexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellselectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::childcountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::childindexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::childkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::collapseSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::collapseallSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columncgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columncountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnindexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::columnwidthSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcelllistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configrowlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configrowsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::configureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cornerlabelpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cornerpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curcellselectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curselectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deleteSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deletecolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::depthSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::descendantcountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::dicttoitemSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editinfoSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editwinpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::editwintagSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::embedcheckbuttonSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::embedcheckbuttonsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::embedttkcheckbuttonSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::embedttkcheckbuttonsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::entrypathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::expandSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::expandallSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::expandedkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::fillcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::findcolumnnameSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::findrownameSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::finisheditingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::formatinfoSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getformattedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getformattedcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getformattedcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getfullkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::getkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hasattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hascellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hascolumnattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hasrowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::headerSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_bboxSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_cellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_cellbboxSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_cellcgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_cellconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_cellindexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_configcelllistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_configcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_configrowlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_configrowsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_containingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_containingcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_deleteSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_embedcheckbuttonSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_embedcheckbuttonsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_embedttkcheckbuttonSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_embedttkcheckbuttonsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_fillcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_findrownameSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getformattedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getformattedcellsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getformattedcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getfullkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_getkeysSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_hascellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_hasrowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_imagelabelpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_indexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_insertSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_insertlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_iselemsnippedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_itemlistvarSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_nearestSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_nearestcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_rowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_rowcgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_rowconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_sizeSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_unsetcellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_unsetrowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::header_windowpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::headerpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::headertagSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hidetargetmarkSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::imagelabelpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::indexSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertchildlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertchildrenSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertcolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertcolumnsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::iselemsnippedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::isexpandedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::istitlesnippedSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::isviewableSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::itemlistvarSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::itemtodictSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::labelpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::labelsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::labeltagSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::moveSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::movecolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::nearestSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::nearestcellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::nearestcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::noderowSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::parentkeySubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::refreshsortingSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rejectinputSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::resetsortinfoSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowcgetSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowconfigureSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::scanSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::searchcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seecellSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seecolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::selectionSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::separatorpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::separatorsSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::showtargetmarkSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sizeSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortbycolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortbycolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortcolumnSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortcolumnlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortorderSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::sortorderlistSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::targetmarkpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::targetmarkposSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::togglecolumnhideSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::togglerowhideSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::toplevelkeySubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetcellattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetcolumnattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::unsetrowattribSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::viewablerowcountSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::windowpathSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::xviewSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::yviewSubCmd) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::cellSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::colWidth) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingRow) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hdr_containingRow) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::containingCol) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curCellSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::curSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deleteRows) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hdr_deleteRows) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::deleteCols) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertRows) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hdr_insertRows) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::displayItems) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::insertCols) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::doScan) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::populate) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(doesMatch) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeRow) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeCell) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::rowSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::horizMoveTo) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::vertMoveTo) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::seeTextIdx) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::updateIdletasksDelayed) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::updateIdletasks) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::hdrConfigure) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::bodyConfigure) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::fetchSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::lostSelection) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::activeTrace) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::listVarTrace) [list source [file join $dir tablelistWidget.tcl]]
set auto_index(::tablelist::checkStatesTrace) [list source [file join $dir tablelistWidget.tcl]]

Added libs/tablelist6.0/tablelist.tcl.































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#==============================================================================
# Main Tablelist package module.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tcl 8
package require Tk  8
package require -exact tablelist::common 6.0

package provide tablelist $::tablelist::version
package provide Tablelist $::tablelist::version

::tablelist::useTile 0
::tablelist::createBindings

Added libs/tablelist6.0/tablelistPublic.tcl.











































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Main Tablelist and Tablelist_tile package module.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

namespace eval ::tablelist {
    #
    # Gets the scaling percentage (100, 125, 150, or 200).
    #
    proc scalingPercentage {} {
	set factor [tk scaling]
	if {$factor < 1.50} {
	    return 100 
	} elseif {$factor < 1.83} {
	    return 125 
	} elseif {$factor < 2.33} {
	    return 150 
	} else {
	    return 200
	}
    }

    #
    # Public variables:
    #
    variable version	6.0
    variable library
    if {$tcl_version >= 8.4} {
	set library	[file normalize [DIR]]
    } else {
	set library	[DIR]			;# no "file normalize" yet
    }
    variable scalingpct	[scalingPercentage]

    #
    # Creates a new tablelist widget:
    #
    namespace export	tablelist

    #
    # Sort the items of a tablelist widget by one or more of its columns:
    #
    namespace export	sortByColumn addToSortColumns

    #
    # Helper procedures used in binding scripts:
    #
    namespace export	convEventFields getTablelistPath getTablelistColumn \
			delaySashPosUpdates

    #
    # Register various widgets for interactive cell editing:
    #
    namespace export	addBWidgetEntry addBWidgetSpinBox addBWidgetComboBox
    namespace export    addIncrEntryfield addIncrDateTimeWidget \
			addIncrSpinner addIncrSpinint addIncrCombobox
    namespace export	addCtext addOakleyCombobox
    namespace export	addDateMentry addTimeMentry addDateTimeMentry \
			addFixedPointMentry addIPAddrMentry addIPv6AddrMentry
}

package provide tablelist::common $::tablelist::version

#
# The following procedure, invoked in "tablelist.tcl" and "tablelist_tile.tcl",
# sets the variable ::tablelist::usingTile to the given value and sets a trace
# on this variable.
#
proc ::tablelist::useTile {bool} {
    variable usingTile $bool
    trace variable usingTile wu [list ::tablelist::restoreUsingTile $bool]
}

#
# The following trace procedure is executed whenever the variable
# ::tablelist::usingTile is written or unset.  It restores the variable to its
# original value, given by the first argument.
#
proc ::tablelist::restoreUsingTile {origVal varName index op} {
    variable usingTile $origVal
    switch $op {
	w {
	    return -code error "it is not allowed to use both Tablelist and\
				Tablelist_tile in the same application"
	}
	u {
	    trace variable usingTile wu \
		  [list ::tablelist::restoreUsingTile $origVal]
	}
    }
}

interp alias {} ::tk::frame {} ::frame
interp alias {} ::tk::label {} ::label

#
# Everything else needed is lazily loaded on demand, via the dispatcher
# set up in the subdirectory "scripts" (see the file "tclIndex").
#
lappend auto_path [file join $::tablelist::library scripts]

Added libs/tablelist6.0/tablelist_tile.tcl.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#==============================================================================
# Main Tablelist_tile package module.
#
# Copyright (c) 2000-2017  Csaba Nemethi (E-mail: csaba.nemethi@t-online.de)
#==============================================================================

package require Tcl 8.4
package require Tk  8.4
if {$::tk_version < 8.5 || [regexp {^8\.5a[1-5]$} $::tk_patchLevel]} {
    package require tile 0.6
}
package require -exact tablelist::common 6.0

package provide tablelist_tile $::tablelist::version
package provide Tablelist_tile $::tablelist::version

::tablelist::useTile 1
::tablelist::createBindings

namespace eval ::tablelist {
    #
    # Commands related to tile themes:
    #
    namespace export	getThemes getCurrentTheme setTheme setThemeDefaults
}