pytktable-binaries 2.12.2__py3-none-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,165 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytktable-binaries
3
+ Version: 2.12.2
4
+ Summary: Prebuilt Tktable, the Tcl/Tk table widget, for pytktable.
5
+ License-File: LICENSE.md
6
+ License-File: tktable-src/license.txt
7
+ Keywords: tkinter,tk,tcl,table,tktable,widget,gui
8
+ Author: nbro
9
+ Author-email: nbrosoftware@outlook.com
10
+ Requires-Python: >=3.11
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: User Interfaces
14
+ Classifier: Topic :: Software Development :: Libraries :: Tcl Extensions
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Programming Language :: Python :: 3.15
24
+ Classifier: Typing :: Typed
25
+ Project-URL: Homepage, https://github.com/nbro/pytktable-binaries
26
+ Project-URL: Tktable source, https://github.com/bohagan1/TkTable
27
+ Project-URL: pytktable, https://github.com/nbro/tktable
28
+ Description-Content-Type: text/markdown
29
+
30
+ # pytktable-binaries
31
+
32
+ [![PyPI](https://img.shields.io/pypi/v/pytktable-binaries)](https://pypi.org/project/pytktable-binaries/)
33
+ [![Python](https://img.shields.io/pypi/pyversions/pytktable-binaries)](https://pypi.org/project/pytktable-binaries/)
34
+ [![OS](https://img.shields.io/badge/os-Linux%20%7C%20macOS%20%7C%20Windows-blue)](#pytktable-binaries)
35
+ [![Architectures](https://img.shields.io/badge/arch-x86__64%20%7C%20arm64%20%7C%20x86-blue)](#pytktable-binaries)
36
+ [![Build](https://github.com/nbro/pytktable-binaries/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/nbro/pytktable-binaries/actions/workflows/build.yml)
37
+ [![Checks](https://github.com/nbro/pytktable-binaries/actions/workflows/checks.yml/badge.svg?branch=main)](https://github.com/nbro/pytktable-binaries/actions/workflows/checks.yml)
38
+ [![License](https://img.shields.io/badge/license-BSD%202--Clause-orange.svg)](LICENSE.md)
39
+
40
+ Prebuilt [Tktable](https://github.com/bohagan1/TkTable), the Tcl/Tk table widget, for
41
+ [pytktable](https://github.com/nbro/tktable), so that Python users don't need to install Tktable
42
+ with their operating system's package manager.
43
+
44
+ Each wheel contains Tktable compiled for Tcl/Tk 8.6 and for Tcl/Tk 9.0; Tcl loads the one matching
45
+ the Tcl/Tk of the Python that runs it. The libraries don't depend on the Python version, so one
46
+ wheel per platform works with every Python 3.
47
+
48
+ | Platform | Wheel tags |
49
+ |----------------------------------|----------------------------------------------------|
50
+ | Linux with glibc (most distros) | `manylinux_2_28_x86_64`, `manylinux_2_28_aarch64` |
51
+ | Linux with musl (e.g. Alpine) | `musllinux_1_2_x86_64`, `musllinux_1_2_aarch64` |
52
+ | macOS 11+, Intel and Apple silicon | `macosx_11_0_universal2` |
53
+ | Windows | `win_amd64`, `win32`, `win_arm64` |
54
+
55
+ ### Possible future platforms
56
+
57
+ - Linux on other CPUs: 32-bit ARM (`armv7l`, older Raspberry Pi OS), `ppc64le`, `s390x`,
58
+ `riscv64`. They would be compiled under emulation, which is slow.
59
+ - Linux with glibc older than 2.28 (`manylinux2014`): only end-of-life distributions, e.g. CentOS 7.
60
+ - macOS older than 11.
61
+ - PyPy: the wheels don't depend on the Python version, so they should already work; it would need
62
+ a test job.
63
+
64
+ ## Usage
65
+
66
+ `library_dir()` returns the folder to add to Tcl's `auto_path`. For example, with pytktable:
67
+
68
+ ```python
69
+ import os
70
+
71
+ import tktable_binaries
72
+
73
+ os.environ["TKTABLE_LIBRARY"] = str(tktable_binaries.library_dir())
74
+ ```
75
+
76
+ ## How it is built
77
+
78
+ - `tktable-src` is a Git submodule pinned to a Tktable release tag.
79
+ - `versions.env` pins the Tcl/Tk sources it is compiled against (only their headers and stub
80
+ libraries are used, so the result works with any Tcl/Tk 8.6.x or 9.0.x).
81
+ - `scripts/build-unix.sh` (Linux, macOS) and `scripts/build-windows.ps1` (Windows) compile Tktable
82
+ against Tcl/Tk 8.6 and 9.0, and `scripts/collect.py` puts both in one `Tktable<version>` folder.
83
+ - `scripts/make_wheel.py` builds the wheel of one platform from that folder.
84
+ - The `Build` workflow (`.github/workflows/build.yml`) does all of this on GitHub Actions: it calls
85
+ `compile-linux.yml`, `compile-macos.yml` and `compile-windows.yml`, builds the wheels, then calls
86
+ `test.yml`, which tests them with pytktable's tests on each platform, and on Fedora and Alpine
87
+ (`scripts/test-distro.sh`).
88
+
89
+ To update Tktable, check out another tag in the submodule, and set `version` in `pyproject.toml`
90
+ to its version:
91
+
92
+ ```sh
93
+ git -C tktable-src fetch --tags
94
+ ```
95
+
96
+ ```sh
97
+ git -C tktable-src checkout <tag>
98
+ ```
99
+
100
+ ## Versioning
101
+
102
+ The version is the version of Tktable it contains, plus a fourth number for the releases of this
103
+ package with the same Tktable (e.g. a build fix or a new platform):
104
+
105
+ | Change | Version |
106
+ |-----------------------------------------|--------------------------|
107
+ | First release with Tktable 2.12.2 | `2.12.2` |
108
+ | A fix of this package, same Tktable | `2.12.2.1`, `2.12.2.2` |
109
+ | Tktable 2.12.3 | `2.12.3` |
110
+
111
+ [PEP 440](https://peps.python.org/pep-0440/) allows any number of version components, so
112
+ `2.12.2` < `2.12.2.1` < `2.12.3`.
113
+
114
+ ## Development
115
+
116
+ Install [Poetry](https://python-poetry.org/docs/#installation), then the dev dependencies and the
117
+ [pre-commit](https://pre-commit.com/) hooks, which format and lint Python, YAML, shell and
118
+ PowerShell files, and scan for secrets, on every `git commit`:
119
+
120
+ ```sh
121
+ poetry install
122
+ ```
123
+
124
+ ```sh
125
+ poetry run pre-commit install
126
+ ```
127
+
128
+ The PowerShell hook needs [PowerShell 7](https://learn.microsoft.com/powershell/scripting/install/installing-powershell)
129
+ (`pwsh`) and PSScriptAnalyzer. Save PSScriptAnalyzer once inside the repository, in `.tools/Modules`
130
+ (not in Git), so nothing changes outside the repository:
131
+
132
+ ```powershell
133
+ New-Item -ItemType Directory -Force .tools/Modules
134
+ ```
135
+
136
+ ```powershell
137
+ Save-PSResource PSScriptAnalyzer -Path .tools/Modules -TrustRepository
138
+ ```
139
+
140
+ To run all hooks on all files, as the `Checks` workflow does:
141
+
142
+ ```sh
143
+ poetry run pre-commit run --all-files
144
+ ```
145
+
146
+ ## Releasing
147
+
148
+ 1. Set `version` in `pyproject.toml` (see [Versioning](#versioning)) and commit it to `main`.
149
+ 2. Push a tag with the same version, e.g. `2.12.2`.
150
+
151
+ The `Release` workflow (`.github/workflows/release.yml`) then checks that the tag and the version
152
+ are equal, builds and tests the wheels, publishes them to PyPI with
153
+ [Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (no API token), and creates a
154
+ GitHub release with them.
155
+
156
+ ## AI assistance
157
+
158
+ This repository was created with the help of [Claude](https://claude.ai) (Anthropic). The
159
+ maintainer reviewed the changes, but not always thoroughly. Please report any problem you find.
160
+
161
+ ## License
162
+
163
+ The build scripts: [BSD 2-Clause](LICENSE.md). Tktable: its own
164
+ [license](https://github.com/bohagan1/TkTable/blob/master/license.txt), included in the wheels.
165
+
@@ -0,0 +1,12 @@
1
+ pytktable_binaries-2.12.2.dist-info/licenses/LICENSE.md,sha256=3C1isGfpn2AQLJ3tNXr9Z587dCnzrMNyIlx8EBmwxzY,1370
2
+ pytktable_binaries-2.12.2.dist-info/licenses/tktable-src/license.txt,sha256=P47Z8SmtAGpFpmLqxahtEf5ZwiRFJqtN2SkVWbb6O2s,2731
3
+ tktable_binaries/__init__.py,sha256=1l5IjrzUrxUeJgJ1zjARDW2asvRlzVlq_xoOvj2WR_s,554
4
+ tktable_binaries/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ tktable_binaries/Tktable2.12.2/Tktable2122t.dll,sha256=_Gq8NgAD7niuVuBwj2vUfo_STW5XIGasRmdWPXqWKU8,119808
6
+ tktable_binaries/Tktable2.12.2/license.txt,sha256=P47Z8SmtAGpFpmLqxahtEf5ZwiRFJqtN2SkVWbb6O2s,2731
7
+ tktable_binaries/Tktable2.12.2/pkgIndex.tcl,sha256=r4q7rrTVYmqiyik0-UegrjYJzXYNYv-oiMmNNYGDnkE,1000
8
+ tktable_binaries/Tktable2.12.2/tcl9Tktable2122.dll,sha256=qhpknCFiDR5YfkechCQW6_jBzNrokHH22X-RycFr6gQ,119296
9
+ tktable_binaries/Tktable2.12.2/tkTable.tcl,sha256=ByVD50CdQiu72WDZv_rU6SsJEjm_NTkYFNmyEtNloDM,25531
10
+ pytktable_binaries-2.12.2.dist-info/METADATA,sha256=Ij7dcj2jngM8gfRMCSyUky7p_BSS6xwhp3o6xYpAz4Q,7254
11
+ pytktable_binaries-2.12.2.dist-info/WHEEL,sha256=l4RVwKcQgveIMj2vKIPPeLsJ-6S-k0K95mSKUCi1gyo,91
12
+ pytktable_binaries-2.12.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.5.0
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-win32
@@ -0,0 +1,17 @@
1
+ # [The BSD 2-Clause License](https://opensource.org/licenses/BSD-2-Clause)
2
+
3
+ Copyright (c) 2026, nbro
4
+
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright notice,
14
+ this list of conditions and the following disclaimer in the documentation
15
+ and/or other materials provided with the distribution.
16
+
17
+ > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,51 @@
1
+ * COPYRIGHT AND LICENSE TERMS *
2
+
3
+ (This file blatantly stolen from Tcl/Tk license and adapted - thus assume
4
+ it falls under similar license terms).
5
+
6
+ This software is copyrighted by Jeffrey Hobbs <jeff at hobbs org>. The
7
+ following terms apply to all files associated with the software unless
8
+ explicitly disclaimed in individual files.
9
+
10
+ The authors hereby grant permission to use, copy, modify, distribute, and
11
+ license this software and its documentation for any purpose, provided that
12
+ existing copyright notices are retained in all copies and that this notice
13
+ is included verbatim in any distributions. No written agreement, license,
14
+ or royalty fee is required for any of the authorized uses. Modifications
15
+ to this software may be copyrighted by their authors and need not follow
16
+ the licensing terms described here, provided that the new terms are clearly
17
+ indicated on the first page of each file where they apply.
18
+
19
+ IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
20
+ DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
21
+ OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
22
+ EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
+
24
+ THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
25
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS
27
+ PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
28
+ OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
29
+ MODIFICATIONS.
30
+
31
+ GOVERNMENT USE: If you are acquiring this software on behalf of the
32
+ U.S. government, the Government shall have only "Restricted Rights"
33
+ in the software and related documentation as defined in the Federal
34
+ Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
35
+ are acquiring the software on behalf of the Department of Defense, the
36
+ software shall be classified as "Commercial Computer Software" and the
37
+ Government shall have only "Restricted Rights" as defined in Clause
38
+ 252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the
39
+ authors grant the U.S. Government and others acting in its behalf
40
+ permission to use and distribute the software in accordance with the
41
+ terms specified in this license.
42
+
43
+ SPECIAL NOTES:
44
+
45
+ This software is also falls under the bourbon_ware clause v2:
46
+
47
+ This software is free, but should you find this software useful in your
48
+ daily work and would like to compensate the author, donations in the form
49
+ of aged bourbon and scotch are welcome by the author. The user may feel
50
+ exempt from this clause if they are below drinking age or think the author
51
+ has already partaken of too many drinks.
@@ -0,0 +1,51 @@
1
+ * COPYRIGHT AND LICENSE TERMS *
2
+
3
+ (This file blatantly stolen from Tcl/Tk license and adapted - thus assume
4
+ it falls under similar license terms).
5
+
6
+ This software is copyrighted by Jeffrey Hobbs <jeff at hobbs org>. The
7
+ following terms apply to all files associated with the software unless
8
+ explicitly disclaimed in individual files.
9
+
10
+ The authors hereby grant permission to use, copy, modify, distribute, and
11
+ license this software and its documentation for any purpose, provided that
12
+ existing copyright notices are retained in all copies and that this notice
13
+ is included verbatim in any distributions. No written agreement, license,
14
+ or royalty fee is required for any of the authorized uses. Modifications
15
+ to this software may be copyrighted by their authors and need not follow
16
+ the licensing terms described here, provided that the new terms are clearly
17
+ indicated on the first page of each file where they apply.
18
+
19
+ IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
20
+ DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
21
+ OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
22
+ EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
+
24
+ THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
25
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS
27
+ PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
28
+ OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
29
+ MODIFICATIONS.
30
+
31
+ GOVERNMENT USE: If you are acquiring this software on behalf of the
32
+ U.S. government, the Government shall have only "Restricted Rights"
33
+ in the software and related documentation as defined in the Federal
34
+ Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
35
+ are acquiring the software on behalf of the Department of Defense, the
36
+ software shall be classified as "Commercial Computer Software" and the
37
+ Government shall have only "Restricted Rights" as defined in Clause
38
+ 252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the
39
+ authors grant the U.S. Government and others acting in its behalf
40
+ permission to use and distribute the software in accordance with the
41
+ terms specified in this license.
42
+
43
+ SPECIAL NOTES:
44
+
45
+ This software is also falls under the bourbon_ware clause v2:
46
+
47
+ This software is free, but should you find this software useful in your
48
+ daily work and would like to compensate the author, donations in the form
49
+ of aged bourbon and scotch are welcome by the author. The user may feel
50
+ exempt from this clause if they are below drinking age or think the author
51
+ has already partaken of too many drinks.
@@ -0,0 +1,33 @@
1
+ # -*- tcl -*-
2
+ # Tcl package index file, version 1.1
3
+ #
4
+ if {[package vsatisfies [package provide Tcl] 9.0-]} {
5
+ package ifneeded Tktable 2.12.2 [list apply {{dir} {
6
+ # Load library
7
+ load [file join $dir tcl9Tktable2122.dll] [string totitle Tktable]
8
+
9
+ # Source init file
10
+ set initScript [file join $dir tkTable.tcl]
11
+ if {[file exists $initScript]} {
12
+ source -encoding utf-8 $initScript
13
+ }
14
+ }} $dir]
15
+ } else {
16
+ if {![package vsatisfies [package provide Tcl] 8.5]} {return}
17
+ package ifneeded Tktable 2.12.2 [list apply {{dir} {
18
+ # Load library
19
+ if {[string tolower [file extension Tktable2122t.dll]] in [list .dll .dylib .so]} {
20
+ # Load dynamic library
21
+ load [file join $dir Tktable2122t.dll] [string totitle Tktable]
22
+ } else {
23
+ # Static library
24
+ load {} [string totitle Tktable]
25
+ }
26
+
27
+ # Source init file
28
+ set initScript [file join $dir tkTable.tcl]
29
+ if {[file exists $initScript]} {
30
+ source -encoding utf-8 $initScript
31
+ }
32
+ }} $dir]
33
+ }
@@ -0,0 +1,882 @@
1
+ # table.tcl --
2
+ #
3
+ # Version align with tkTable 2.7, jeff at hobbs org
4
+ # This file defines the default bindings for Tk table widgets
5
+ # and provides procedures that help in implementing those bindings.
6
+ #
7
+
8
+ #--------------------------------------------------------------------------
9
+ # ::tktable::Priv elements used in this file:
10
+ #
11
+ # x && y - Coords in widget
12
+ # afterId - Token returned by "after" for autoscanning.
13
+ # tablePrev - The last element to be selected or deselected
14
+ # during a selection operation.
15
+ # mouseMoved - Boolean to indicate whether mouse moved while
16
+ # the button was pressed.
17
+ # borderInfo - Boolean to know if the user clicked on a border
18
+ # borderB1 - Boolean that set whether B1 can be used for the
19
+ # interactiving resizing
20
+ #--------------------------------------------------------------------------
21
+
22
+ namespace eval ::tktable {
23
+ # Ensure that a namespace is created for us
24
+ variable Priv
25
+ array set Priv [list x 0 y 0 afterId {} mouseMoved 0 \
26
+ borderInfo {} borderB1 1]
27
+ }
28
+
29
+ # ::tktable::ClipboardKeysyms --
30
+ # This procedure is invoked to identify the keys that correspond to
31
+ # the "copy", "cut", and "paste" functions for the clipboard.
32
+ #
33
+ # Arguments:
34
+ # copy - Name of the key (keysym name plus modifiers, if any,
35
+ # such as "Meta-y") used for the copy operation.
36
+ # cut - Name of the key used for the cut operation.
37
+ # paste - Name of the key used for the paste operation.
38
+
39
+ proc ::tktable::ClipboardKeysyms {copy cut paste} {
40
+ bind Table <$copy> {tk_tableCopy %W}
41
+ bind Table <$cut> {tk_tableCut %W}
42
+ bind Table <$paste> {tk_tablePaste %W}
43
+ }
44
+ ::tktable::ClipboardKeysyms <Copy> <Cut> <Paste>
45
+
46
+ ##
47
+ ## Interactive cell resizing, affected by -resizeborders option
48
+ ##
49
+ bind Table <3> {
50
+ ## You might want to check for cell returned if you want to
51
+ ## restrict the resizing of certain cells
52
+ %W border mark %x %y
53
+ }
54
+ bind Table <B3-Motion> { %W border dragto %x %y }
55
+
56
+ ## Button events
57
+
58
+ bind Table <1> { ::tktable::Button1 %W %x %y }
59
+ bind Table <B1-Motion> { ::tktable::B1Motion %W %x %y }
60
+
61
+ bind Table <ButtonRelease-1> {
62
+ if {$::tktable::Priv(borderInfo) eq "" && [winfo exists %W]} {
63
+ ::tktable::CancelRepeat
64
+ %W activate @%x,%y
65
+ }
66
+ }
67
+ bind Table <Double-1> {
68
+ # empty
69
+ }
70
+
71
+ bind Table <Shift-1> {::tktable::BeginExtend %W [%W index @%x,%y]}
72
+ bind Table <Control-1> {::tktable::BeginToggle %W [%W index @%x,%y]}
73
+ bind Table <B1-Enter> {::tktable::CancelRepeat}
74
+ bind Table <B1-Leave> {
75
+ if {$::tktable::Priv(borderInfo) eq ""} {
76
+ array set ::tktable::Priv {x %x y %y}
77
+ ::tktable::AutoScan %W
78
+ }
79
+ }
80
+ bind Table <2> {
81
+ %W scan mark %x %y
82
+ array set ::tktable::Priv {x %x y %y}
83
+ set ::tktable::Priv(mouseMoved) 0
84
+ }
85
+ bind Table <B2-Motion> {
86
+ if {(%x != $::tktable::Priv(x)) || (%y != $::tktable::Priv(y))} {
87
+ set ::tktable::Priv(mouseMoved) 1
88
+ }
89
+ if {$::tktable::Priv(mouseMoved)} { %W scan dragto %x %y }
90
+ }
91
+ bind Table <ButtonRelease-2> {
92
+ if {!$::tktable::Priv(mouseMoved)} { tk_tablePaste %W [%W index @%x,%y] }
93
+ }
94
+
95
+ ## Mouse wheel events
96
+
97
+ if {[package vcompare [package present Tk] 8.7] >= 0} {
98
+ bind Table <MouseWheel> {tk::MouseWheel %W y %D -40.0}
99
+ bind Table <Option-MouseWheel> {tk::MouseWheel %W y %D -12.0}
100
+ bind Table <Shift-MouseWheel> {tk::MouseWheel %W x %D -40.0}
101
+ bind Table <Shift-Option-MouseWheel> {tk::MouseWheel %W x %D -12.0}
102
+
103
+ } else {
104
+ if {[tk windowingsystem] eq "aqua"} {
105
+ bind Table <MouseWheel> {%W yview scroll [expr {-%D}] units}
106
+ bind Table <Shift-MouseWheel> {%W xview scroll [expr {-%D}] units}
107
+ bind Table <Option-MouseWheel> {%W yview scroll [expr {-10 * %D}] units}
108
+ bind Table <Shift-Option-MouseWheel> {%W xview scroll [expr {-10 * %D}] units}
109
+ } else {
110
+ bind Table <MouseWheel> {%W yview scroll [expr {-%D / 120}] units}
111
+ bind Table <Shift-MouseWheel> {%W xview scroll [expr {-%D / 120}] units}
112
+ }
113
+
114
+ if {[tk windowingsystem] eq "x11"} {
115
+ bind Table <Button-4> {%W yview scroll -5 units}
116
+ bind Table <Shift-Button-4> {%W xview scroll -5 units}
117
+ bind Table <Button-5> {%W yview scroll 5 units}
118
+ bind Table <Shift-Button-5> {%W xview scroll 5 units}
119
+ }
120
+ }
121
+
122
+ ## Touchpad scrolling
123
+ #
124
+ if {[package vcompare [package present Tk] 8.7] >= 0} {
125
+ bind Table <TouchpadScroll> {
126
+ if {%# %% 5 != 0} {
127
+ return
128
+ }
129
+ lassign [tk::PreciseScrollDeltas %D] tk::Priv(deltaX) tk::Priv(deltaY)
130
+ if {$tk::Priv(deltaX) != 0} {
131
+ %W xview scroll [expr {-$tk::Priv(deltaX)}] units
132
+ }
133
+ if {$tk::Priv(deltaY) != 0} {
134
+ %W yview scroll [expr {-$tk::Priv(deltaY)}] units
135
+ }
136
+ }
137
+ }
138
+
139
+ ## Key events
140
+
141
+ # This forces a cell commit if an active cell exists
142
+ bind Table <<Table_Commit>> {
143
+ catch {%W activate active}
144
+ }
145
+ # Remove this if you don't want cell commit to occur on every Leave for
146
+ # the table (via mouse) or FocusOut (loss of focus by table).
147
+ event add <<Table_Commit>> <Leave> <FocusOut>
148
+
149
+ bind Table <Shift-Up> {::tktable::ExtendSelect %W -1 0}
150
+ bind Table <Shift-Down> {::tktable::ExtendSelect %W 1 0}
151
+ bind Table <Shift-Left> {::tktable::ExtendSelect %W 0 -1}
152
+ bind Table <Shift-Right> {::tktable::ExtendSelect %W 0 1}
153
+ bind Table <Prior> {%W yview scroll -1 pages; %W activate topleft}
154
+ bind Table <Next> {%W yview scroll 1 pages; %W activate topleft}
155
+ bind Table <Control-Prior> {%W xview scroll -1 pages}
156
+ bind Table <Control-Next> {%W xview scroll 1 pages}
157
+ bind Table <Home> {%W see origin}
158
+ bind Table <End> {%W see end}
159
+ bind Table <Control-Home> {
160
+ %W selection clear all
161
+ %W activate origin
162
+ %W selection set active
163
+ %W see active
164
+ }
165
+ bind Table <Control-End> {
166
+ %W selection clear all
167
+ %W activate end
168
+ %W selection set active
169
+ %W see active
170
+ }
171
+ bind Table <Shift-Control-Home> {::tktable::DataExtend %W origin}
172
+ bind Table <Shift-Control-End> {::tktable::DataExtend %W end}
173
+ bind Table <Select> {::tktable::BeginSelect %W [%W index active]}
174
+ bind Table <Shift-Select> {::tktable::BeginExtend %W [%W index active]}
175
+ bind Table <Control-slash> {::tktable::SelectAll %W}
176
+ bind Table <Control-backslash> {
177
+ if {[string match browse [%W cget -selectmode]]} {%W selection clear all}
178
+ }
179
+ bind Table <Up> {::tktable::MoveCell %W -1 0}
180
+ bind Table <Down> {::tktable::MoveCell %W 1 0}
181
+ bind Table <Left> {::tktable::MoveCell %W 0 -1}
182
+ bind Table <Right> {::tktable::MoveCell %W 0 1}
183
+ bind Table <KeyPress> {::tktable::Insert %W %A}
184
+ bind Table <BackSpace> {::tktable::BackSpace %W}
185
+ bind Table <Delete> {%W delete active insert}
186
+ bind Table <Escape> {%W reread}
187
+
188
+ #bind Table <Return> {::tktable::MoveCell %W 1 0}
189
+ bind Table <Return> {::tktable::Insert %W "\n"}
190
+
191
+ bind Table <Control-Left> {%W icursor [expr {[%W icursor]-1}]}
192
+ bind Table <Control-Right> {%W icursor [expr {[%W icursor]+1}]}
193
+ bind Table <Control-e> {%W icursor end}
194
+ bind Table <Control-a> {%W icursor 0}
195
+ bind Table <Control-k> {%W delete active insert end}
196
+ bind Table <Control-equal> {::tktable::ChangeWidth %W active 1}
197
+ bind Table <Control-minus> {::tktable::ChangeWidth %W active -1}
198
+
199
+ # Ignore all Alt, Meta, and Control keypresses unless explicitly bound.
200
+ # Otherwise, if a widget binding for one of these is defined, the
201
+ # <KeyPress> class binding will also fire and insert the character,
202
+ # which is wrong. Ditto for Tab.
203
+
204
+ bind Table <Alt-KeyPress> {# nothing}
205
+ bind Table <Meta-KeyPress> {# nothing}
206
+ bind Table <Control-KeyPress> {# nothing}
207
+ bind Table <Any-Tab> {# nothing}
208
+ if {[string match "macintosh" $::tcl_platform(platform)]} {
209
+ bind Table <Command-KeyPress> {# nothing}
210
+ }
211
+
212
+ # ::tktable::GetSelection --
213
+ # This tries to obtain the default selection. On Unix, we first try
214
+ # and get a UTF8_STRING, a type supported by modern Unix apps for
215
+ # passing Unicode data safely. We fall back on the default STRING
216
+ # type otherwise. On Windows, only the STRING type is necessary.
217
+ # Arguments:
218
+ # w The widget for which the selection will be retrieved.
219
+ # Important for the -displayof property.
220
+ # sel The source of the selection (PRIMARY or CLIPBOARD)
221
+ # Results:
222
+ # Returns the selection, or an error if none could be found
223
+ #
224
+ if {$::tcl_platform(platform) ne "unix"} {
225
+ proc ::tktable::GetSelection {w {sel PRIMARY}} {
226
+ if {[catch {selection get -displayof $w -selection $sel} txt]} {
227
+ return -code error "could not find default selection"
228
+ } else {
229
+ return $txt
230
+ }
231
+ }
232
+ } else {
233
+ proc ::tktable::GetSelection {w {sel PRIMARY}} {
234
+ if {[catch {selection get -displayof $w -selection $sel \
235
+ -type UTF8_STRING} txt] \
236
+ && [catch {selection get -displayof $w -selection $sel} txt]} {
237
+ return -code error "could not find default selection"
238
+ } else {
239
+ return $txt
240
+ }
241
+ }
242
+ }
243
+
244
+ # ::tktable::CancelRepeat --
245
+ # A copy of tkCancelRepeat, just in case it's not available or changes.
246
+ # This procedure is invoked to cancel an auto-repeat action described
247
+ # by ::tktable::Priv(afterId). It's used by several widgets to auto-scroll
248
+ # the widget when the mouse is dragged out of the widget with a
249
+ # button pressed.
250
+ #
251
+ # Arguments:
252
+ # None.
253
+
254
+ proc ::tktable::CancelRepeat {} {
255
+ variable Priv
256
+ after cancel $Priv(afterId)
257
+ set Priv(afterId) {}
258
+ }
259
+
260
+ # ::tktable::Insert --
261
+ #
262
+ # Insert into the active cell
263
+ #
264
+ # Arguments:
265
+ # w - the table widget
266
+ # s - the string to insert
267
+ # Results:
268
+ # Returns nothing
269
+ #
270
+ proc ::tktable::Insert {w s} {
271
+ if {$s ne {}} {
272
+ $w insert active insert $s
273
+ }
274
+ }
275
+
276
+ # ::tktable::BackSpace --
277
+ #
278
+ # BackSpace in the current cell
279
+ #
280
+ # Arguments:
281
+ # w - the table widget
282
+ # Results:
283
+ # Returns nothing
284
+ #
285
+ proc ::tktable::BackSpace {w} {
286
+ set cur [$w icursor]
287
+ if {$cur ne {} && $cur > 0} {
288
+ $w delete active [expr {$cur-1}]
289
+ }
290
+ }
291
+
292
+ # ::tktable::Button1 --
293
+ #
294
+ # This procedure is called to handle selecting with mouse button 1.
295
+ # It will distinguish whether to start selection or mark a border.
296
+ #
297
+ # Arguments:
298
+ # w - the table widget
299
+ # x - x coord
300
+ # y - y coord
301
+ # Results:
302
+ # Returns nothing
303
+ #
304
+ proc ::tktable::Button1 {w x y} {
305
+ variable Priv
306
+ #
307
+ # $Priv(borderInfo) is null if the user did not click on a border
308
+ #
309
+ if {$Priv(borderB1) == 1} {
310
+ set Priv(borderInfo) [$w border mark $x $y]
311
+ # account for what resizeborders are set [Bug 876320] (ferenc)
312
+ set rbd [$w cget -resizeborders]
313
+ if {$rbd eq "none" || ![llength $Priv(borderInfo)]
314
+ || ($rbd eq "col" && [lindex $Priv(borderInfo) 1] eq "")
315
+ || ($rbd eq "row" && [lindex $Priv(borderInfo) 0] eq "")} {
316
+ set Priv(borderInfo) ""
317
+ }
318
+ } else {
319
+ set Priv(borderInfo) ""
320
+ }
321
+ if {$Priv(borderInfo) eq ""} {
322
+ #
323
+ # Only do this when a border wasn't selected
324
+ #
325
+ if {[winfo exists $w]} {
326
+ ::tktable::BeginSelect $w [$w index @$x,$y]
327
+ focus $w
328
+ }
329
+ array set Priv [list x $x y $y]
330
+ set Priv(mouseMoved) 0
331
+ }
332
+ }
333
+
334
+ # ::tktable::B1Motion --
335
+ #
336
+ # This procedure is called to start processing mouse motion events while
337
+ # button 1 moves while pressed. It will distinguish whether to change
338
+ # the selection or move a border.
339
+ #
340
+ # Arguments:
341
+ # w - the table widget
342
+ # x - x coord
343
+ # y - y coord
344
+ # Results:
345
+ # Returns nothing
346
+ #
347
+ proc ::tktable::B1Motion {w x y} {
348
+ variable Priv
349
+
350
+ # If we already had motion, or we moved more than 1 pixel,
351
+ # then we start the Motion routine
352
+ if {$Priv(borderInfo) ne ""} {
353
+ #
354
+ # If the motion is on a border, drag it and skip the rest
355
+ # of this binding.
356
+ #
357
+ $w border dragto $x $y
358
+ } else {
359
+ #
360
+ # If we already had motion, or we moved more than 1 pixel,
361
+ # then we start the Motion routine
362
+ #
363
+ if {
364
+ $::tktable::Priv(mouseMoved)
365
+ || abs($x-$::tktable::Priv(x)) > 1
366
+ || abs($y-$::tktable::Priv(y)) > 1
367
+ } {
368
+ set ::tktable::Priv(mouseMoved) 1
369
+ }
370
+ if {$::tktable::Priv(mouseMoved)} {
371
+ ::tktable::Motion $w [$w index @$x,$y]
372
+ }
373
+ }
374
+ }
375
+
376
+ # ::tktable::BeginSelect --
377
+ #
378
+ # This procedure is typically invoked on button-1 presses. It begins
379
+ # the process of making a selection in the table. Its exact behavior
380
+ # depends on the selection mode currently in effect for the table;
381
+ # see the Motif documentation for details.
382
+ #
383
+ # Arguments:
384
+ # w - The table widget.
385
+ # el - The element for the selection operation (typically the
386
+ # one under the pointer). Must be in row,col form.
387
+
388
+ proc ::tktable::BeginSelect {w el} {
389
+ variable Priv
390
+ if {[scan $el %d,%d r c] != 2} return
391
+ switch [$w cget -selectmode] {
392
+ multiple {
393
+ if {[$w tag includes title $el]} {
394
+ ## in the title area
395
+ if {$r < [$w cget -titlerows]+[$w cget -roworigin]} {
396
+ ## We're in a column header
397
+ if {$c < [$w cget -titlecols]+[$w cget -colorigin]} {
398
+ ## We're in the topleft title area
399
+ set inc topleft
400
+ set el2 end
401
+ } else {
402
+ set inc [$w index topleft row],$c
403
+ set el2 [$w index end row],$c
404
+ }
405
+ } else {
406
+ ## We're in a row header
407
+ set inc $r,[$w index topleft col]
408
+ set el2 $r,[$w index end col]
409
+ }
410
+ } else {
411
+ set inc $el
412
+ set el2 $el
413
+ }
414
+ if {[$w selection includes $inc]} {
415
+ $w selection clear $el $el2
416
+ } else {
417
+ $w selection set $el $el2
418
+ }
419
+ }
420
+ extended {
421
+ $w selection clear all
422
+ if {[$w tag includes title $el]} {
423
+ if {$r < [$w cget -titlerows]+[$w cget -roworigin]} {
424
+ ## We're in a column header
425
+ if {$c < [$w cget -titlecols]+[$w cget -colorigin]} {
426
+ ## We're in the topleft title area
427
+ $w selection set $el end
428
+ } else {
429
+ $w selection set $el [$w index end row],$c
430
+ }
431
+ } else {
432
+ ## We're in a row header
433
+ $w selection set $el $r,[$w index end col]
434
+ }
435
+ } else {
436
+ $w selection set $el
437
+ }
438
+ $w selection anchor $el
439
+ set Priv(tablePrev) $el
440
+ }
441
+ default {
442
+ if {![$w tag includes title $el]} {
443
+ $w selection clear all
444
+ $w selection set $el
445
+ set Priv(tablePrev) $el
446
+ }
447
+ $w selection anchor $el
448
+ }
449
+ }
450
+ }
451
+
452
+ # ::tktable::Motion --
453
+ #
454
+ # This procedure is called to process mouse motion events while
455
+ # button 1 is down. It may move or extend the selection, depending
456
+ # on the table's selection mode.
457
+ #
458
+ # Arguments:
459
+ # w - The table widget.
460
+ # el - The element under the pointer (must be in row,col form).
461
+
462
+ proc ::tktable::Motion {w el} {
463
+ variable Priv
464
+ if {![info exists Priv(tablePrev)]} {
465
+ set Priv(tablePrev) $el
466
+ return
467
+ }
468
+ if {[string match $Priv(tablePrev) $el]} return
469
+ switch [$w cget -selectmode] {
470
+ browse {
471
+ $w selection clear all
472
+ $w selection set $el
473
+ set Priv(tablePrev) $el
474
+ }
475
+ extended {
476
+ # avoid tables that have no anchor index yet.
477
+ if {[catch {$w index anchor}]} { return }
478
+ scan $Priv(tablePrev) %d,%d r c
479
+ scan $el %d,%d elr elc
480
+ if {[$w tag includes title $el]} {
481
+ if {$r < [$w cget -titlerows]+[$w cget -roworigin]} {
482
+ ## We're in a column header
483
+ if {$c < [$w cget -titlecols]+[$w cget -colorigin]} {
484
+ ## We're in the topleft title area
485
+ $w selection clear anchor end
486
+ } else {
487
+ $w selection clear anchor [$w index end row],$c
488
+ }
489
+ $w selection set anchor [$w index end row],$elc
490
+ } else {
491
+ ## We're in a row header
492
+ $w selection clear anchor $r,[$w index end col]
493
+ $w selection set anchor $elr,[$w index end col]
494
+ }
495
+ } else {
496
+ $w selection clear anchor $Priv(tablePrev)
497
+ $w selection set anchor $el
498
+ }
499
+ set Priv(tablePrev) $el
500
+ }
501
+ }
502
+ }
503
+
504
+ # ::tktable::BeginExtend --
505
+ #
506
+ # This procedure is typically invoked on shift-button-1 presses. It
507
+ # begins the process of extending a selection in the table. Its
508
+ # exact behavior depends on the selection mode currently in effect
509
+ # for the table; see the Motif documentation for details.
510
+ #
511
+ # Arguments:
512
+ # w - The table widget.
513
+ # el - The element for the selection operation (typically the
514
+ # one under the pointer). Must be in numerical form.
515
+
516
+ proc ::tktable::BeginExtend {w el} {
517
+ # avoid tables that have no anchor index yet.
518
+ if {[catch {$w index anchor}]} { return }
519
+ if {[string match extended [$w cget -selectmode]] &&
520
+ [$w selection includes anchor]} {
521
+ ::tktable::Motion $w $el
522
+ }
523
+ }
524
+
525
+ # ::tktable::BeginToggle --
526
+ #
527
+ # This procedure is typically invoked on control-button-1 presses. It
528
+ # begins the process of toggling a selection in the table. Its
529
+ # exact behavior depends on the selection mode currently in effect
530
+ # for the table; see the Motif documentation for details.
531
+ #
532
+ # Arguments:
533
+ # w - The table widget.
534
+ # el - The element for the selection operation (typically the
535
+ # one under the pointer). Must be in numerical form.
536
+
537
+ proc ::tktable::BeginToggle {w el} {
538
+ if {[string match extended [$w cget -selectmode]]} {
539
+ variable Priv
540
+ set Priv(tablePrev) $el
541
+ $w selection anchor $el
542
+ if {[$w tag includes title $el]} {
543
+ scan $el %d,%d r c
544
+ if {$r < [$w cget -titlerows]+[$w cget -roworigin]} {
545
+ ## We're in a column header
546
+ if {$c < [$w cget -titlecols]+[$w cget -colorigin]} {
547
+ ## We're in the topleft title area
548
+ set end end
549
+ } else {
550
+ set end [$w index end row],$c
551
+ }
552
+ } else {
553
+ ## We're in a row header
554
+ set end $r,[$w index end col]
555
+ }
556
+ } else {
557
+ ## We're in a non-title cell
558
+ set end $el
559
+ }
560
+ if {[$w selection includes $end]} {
561
+ $w selection clear $el $end
562
+ } else {
563
+ $w selection set $el $end
564
+ }
565
+ }
566
+ }
567
+
568
+ # ::tktable::AutoScan --
569
+ # This procedure is invoked when the mouse leaves an table window
570
+ # with button 1 down. It scrolls the window up, down, left, or
571
+ # right, depending on where the mouse left the window, and reschedules
572
+ # itself as an "after" command so that the window continues to scroll until
573
+ # the mouse moves back into the window or the mouse button is released.
574
+ #
575
+ # Arguments:
576
+ # w - The table window.
577
+
578
+ proc ::tktable::AutoScan {w} {
579
+ if {![winfo exists $w]} return
580
+ variable Priv
581
+ set x $Priv(x)
582
+ set y $Priv(y)
583
+ if {$y >= [winfo height $w]} {
584
+ $w yview scroll 1 units
585
+ } elseif {$y < 0} {
586
+ $w yview scroll -1 units
587
+ } elseif {$x >= [winfo width $w]} {
588
+ $w xview scroll 1 units
589
+ } elseif {$x < 0} {
590
+ $w xview scroll -1 units
591
+ } else {
592
+ return
593
+ }
594
+ ::tktable::Motion $w [$w index @$x,$y]
595
+ set Priv(afterId) [after 50 ::tktable::AutoScan $w]
596
+ }
597
+
598
+ # ::tktable::MoveCell --
599
+ #
600
+ # Moves the location cursor (active element) by the specified number
601
+ # of cells and changes the selection if we're in browse or extended
602
+ # selection mode. If the new cell is "hidden", we skip to the next
603
+ # visible cell if possible, otherwise just abort.
604
+ #
605
+ # Arguments:
606
+ # w - The table widget.
607
+ # x - +1 to move down one cell, -1 to move up one cell.
608
+ # y - +1 to move right one cell, -1 to move left one cell.
609
+
610
+ proc ::tktable::MoveCell {w x y} {
611
+ if {[catch {$w index active row} r]} return
612
+ set c [$w index active col]
613
+ set cell [$w index [incr r $x],[incr c $y]]
614
+ while {[set true [$w hidden $cell]] ne {}} {
615
+ # The cell is in some way hidden
616
+ if {[$w index active] ne $true} {
617
+ # The span cell wasn't the previous cell, so go to that
618
+ set cell $true
619
+ break
620
+ }
621
+ if {$x > 0} {incr r} elseif {$x < 0} {incr r -1}
622
+ if {$y > 0} {incr c} elseif {$y < 0} {incr c -1}
623
+ if {[$w index $r,$c] ne $cell} {
624
+ set cell [$w index $r,$c]
625
+ } else {
626
+ # We couldn't find a non-hidden cell, just don't move
627
+ return
628
+ }
629
+ }
630
+ $w activate $cell
631
+ $w see active
632
+ switch [$w cget -selectmode] {
633
+ browse {
634
+ $w selection clear all
635
+ $w selection set active
636
+ }
637
+ extended {
638
+ variable Priv
639
+ $w selection clear all
640
+ $w selection set active
641
+ $w selection anchor active
642
+ set Priv(tablePrev) [$w index active]
643
+ }
644
+ }
645
+ }
646
+
647
+ # ::tktable::ExtendSelect --
648
+ #
649
+ # Does nothing unless we're in extended selection mode; in this
650
+ # case it moves the location cursor (active element) by the specified
651
+ # number of cells, and extends the selection to that point.
652
+ #
653
+ # Arguments:
654
+ # w - The table widget.
655
+ # x - +1 to move down one cell, -1 to move up one cell.
656
+ # y - +1 to move right one cell, -1 to move left one cell.
657
+
658
+ proc ::tktable::ExtendSelect {w x y} {
659
+ if {[$w cget -selectmode] ne "extended" ||
660
+ [catch {$w index active row} r]} return
661
+ set c [$w index active col]
662
+ $w activate [incr r $x],[incr c $y]
663
+ $w see active
664
+ ::tktable::Motion $w [$w index active]
665
+ }
666
+
667
+ # ::tktable::DataExtend
668
+ #
669
+ # This procedure is called for key-presses such as Shift-KEndData.
670
+ # If the selection mode isnt multiple or extend then it does nothing.
671
+ # Otherwise it moves the active element to el and, if we're in
672
+ # extended mode, extends the selection to that point.
673
+ #
674
+ # Arguments:
675
+ # w - The table widget.
676
+ # el - An integer cell number.
677
+
678
+ proc ::tktable::DataExtend {w el} {
679
+ set mode [$w cget -selectmode]
680
+ if {[string match extended $mode]} {
681
+ $w activate $el
682
+ $w see $el
683
+ if {[$w selection includes anchor]} {::tktable::Motion $w $el}
684
+ } elseif {[string match multiple $mode]} {
685
+ $w activate $el
686
+ $w see $el
687
+ }
688
+ }
689
+
690
+ # ::tktable::SelectAll
691
+ #
692
+ # This procedure is invoked to handle the "select all" operation.
693
+ # For single and browse mode, it just selects the active element.
694
+ # Otherwise it selects everything in the widget.
695
+ #
696
+ # Arguments:
697
+ # w - The table widget.
698
+
699
+ proc ::tktable::SelectAll {w} {
700
+ if {[regexp {^(single|browse)$} [$w cget -selectmode]]} {
701
+ $w selection clear all
702
+ catch {$w selection set active}
703
+ } elseif {[$w cget -selecttitles]} {
704
+ $w selection set [$w cget -roworigin],[$w cget -colorigin] end
705
+ } else {
706
+ $w selection set origin end
707
+ }
708
+ }
709
+
710
+ # ::tktable::ChangeWidth --
711
+ #
712
+ # Adjust the widget of the specified cell by $a.
713
+ #
714
+ # Arguments:
715
+ # w - The table widget.
716
+ # i - cell index
717
+ # a - amount to adjust by
718
+
719
+ proc ::tktable::ChangeWidth {w i a} {
720
+ set tmp [$w index $i col]
721
+ if {[set width [$w width $tmp]] >= 0} {
722
+ $w width $tmp [incr width $a]
723
+ } else {
724
+ $w width $tmp [incr width [expr {-$a}]]
725
+ }
726
+ }
727
+
728
+ # tk_tableCopy --
729
+ #
730
+ # This procedure copies the selection from a table widget into the
731
+ # clipboard.
732
+ #
733
+ # Arguments:
734
+ # w - Name of a table widget.
735
+
736
+ proc tk_tableCopy w {
737
+ if {[selection own -displayof $w] eq $w} {
738
+ clipboard clear -displayof $w
739
+ catch {clipboard append -displayof $w [::tktable::GetSelection $w]}
740
+ }
741
+ }
742
+
743
+ # tk_tableCut --
744
+ #
745
+ # This procedure copies the selection from a table widget into the
746
+ # clipboard, then deletes the selection (if it exists in the given
747
+ # widget).
748
+ #
749
+ # Arguments:
750
+ # w - Name of a table widget.
751
+
752
+ proc tk_tableCut w {
753
+ if {[selection own -displayof $w] eq $w} {
754
+ clipboard clear -displayof $w
755
+ catch {
756
+ clipboard append -displayof $w [::tktable::GetSelection $w]
757
+ $w cursel {}
758
+ $w selection clear all
759
+ }
760
+ }
761
+ }
762
+
763
+ # tk_tablePaste --
764
+ #
765
+ # This procedure pastes the contents of the clipboard to the specified
766
+ # cell (active by default) in a table widget.
767
+ #
768
+ # Arguments:
769
+ # w - Name of a table widget.
770
+ # cell - Cell to start pasting in.
771
+ #
772
+ proc tk_tablePaste {w {cell {}}} {
773
+ if {$cell ne {}} {
774
+ if {[catch {::tktable::GetSelection $w} data]} return
775
+ } else {
776
+ if {[catch {::tktable::GetSelection $w CLIPBOARD} data]} {
777
+ return
778
+ }
779
+ set cell active
780
+ }
781
+ tk_tablePasteHandler $w [$w index $cell] $data
782
+ if {[$w cget -state] eq "normal"} {focus $w}
783
+ }
784
+
785
+ # tk_tablePasteHandler --
786
+ #
787
+ # This procedure handles how data is pasted into the table widget.
788
+ # This handles data in the default table selection form.
789
+ #
790
+ # NOTE: this allows pasting into all cells except title cells,
791
+ # even those with -state disabled
792
+ #
793
+ # Arguments:
794
+ # w - Name of a table widget.
795
+ # cell - Cell to start pasting in.
796
+ #
797
+ proc tk_tablePasteHandler {w cell data} {
798
+ #
799
+ # Don't allow pasting into the title cells
800
+ #
801
+ if {[$w tag includes title $cell]} {
802
+ return
803
+ }
804
+
805
+ set rows [expr {[$w cget -rows]-[$w cget -roworigin]}]
806
+ set cols [expr {[$w cget -cols]-[$w cget -colorigin]}]
807
+ set r [$w index $cell row]
808
+ set c [$w index $cell col]
809
+ set rsep [$w cget -rowseparator]
810
+ set csep [$w cget -colseparator]
811
+ set vcmd [$w cget -validatecommand]
812
+
813
+ ## Assume separate rows are split by row separator if specified
814
+ ## If you were to want multi-character row separators, you would need:
815
+ # regsub -all $rsep $data <newline> data
816
+ # set data [join $data <newline>]
817
+ if {$rsep ne {}} {
818
+ set data [split $data $rsep]
819
+ }
820
+ set row $r
821
+ foreach line $data {
822
+ if {$row > $rows} break
823
+ set col $c
824
+ ## Assume separate cols are split by col separator if specified
825
+ ## Unless a -separator was specified
826
+ if {$csep ne {}} {
827
+ set line [split $line $csep]
828
+ }
829
+ ## If you were to want multi-character col separators, you would need:
830
+ # regsub -all $csep $line <newline> line
831
+ # set line [join $line <newline>]
832
+ foreach item $line {
833
+ if {$col > $cols} break
834
+ set oldTxt [$w get $row,$col]
835
+ if {![string equal $item $oldTxt] && $vcmd ne ""} {
836
+ set vldCmd [string map [list %W $w %r $row %c $col %s $oldTxt %S $item] $vcmd]
837
+ if {![eval $vldCmd]} {
838
+ incr col
839
+ continue ;# skip update
840
+ }
841
+ }
842
+ $w set $row,$col $item
843
+ incr col
844
+ }
845
+ incr row
846
+ }
847
+ }
848
+
849
+ # tktable::Sort --
850
+ #
851
+ # This procedure handles how data is sorted in the table widget.
852
+ # This isn't currently used by tktable, but can be called by the user.
853
+ # It's behavior may change in the future.
854
+ #
855
+ # Arguments:
856
+ # w - Name of a table widget.
857
+ # start - start cell of rectangle to sort
858
+ # end - end cell of rectangle to sort
859
+ # col - column within rectangle to sort on
860
+ # args - passed to lsort proc (ie: -integer -decreasing)
861
+
862
+ proc ::tktable::Sort {w start end col args} {
863
+ set start [$w index $start]
864
+ set end [$w index $end]
865
+ scan $start %d,%d sr sc
866
+ scan $end %d,%d er ec
867
+ if {($col < $sc) || ($col > $ec)} {
868
+ return -code error "$col is not within sort range $sc to $ec"
869
+ }
870
+ set col [expr {$col - $sc}]
871
+
872
+ set data {}
873
+ for {set i $sr} {$i <= $er} {incr i} {
874
+ lappend data [$w get $i,$sc $i,$ec]
875
+ }
876
+
877
+ set i $sr
878
+ foreach row [eval [list lsort -index $col] $args [list $data]] {
879
+ $w set row $i,$sc $row
880
+ incr i
881
+ }
882
+ }
@@ -0,0 +1,16 @@
1
+ """Prebuilt Tktable, the Tcl/Tk table widget, for pytktable.
2
+
3
+ This package contains no Python API apart from :func:`library_dir`: it ships Tktable compiled for
4
+ Tcl/Tk 8.6 and 9.0, in a ``Tktable<version>`` folder that Tcl finds through its ``auto_path``.
5
+ """
6
+
7
+ from pathlib import Path
8
+
9
+
10
+ def library_dir() -> Path:
11
+ """Return the folder to add to Tcl's ``auto_path`` so that Tcl can find Tktable.
12
+
13
+ Tcl also searches the subfolders of each ``auto_path`` folder, where the ``pkgIndex.tcl``
14
+ of Tktable is.
15
+ """
16
+ return Path(__file__).parent
File without changes