diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2019-01-07 21:32:55 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2019-01-07 21:32:55 (GMT) |
commit | 1c463eec511ffd93b99d7de57821c018bbfc0b24 (patch) | |
tree | b34d0faae2ced49ed7963e43520511d8355441a4 /tktable/library | |
parent | c6415290e8f20f16e5a62350b9de153d2bdf29a6 (diff) | |
download | blt-1c463eec511ffd93b99d7de57821c018bbfc0b24.zip blt-1c463eec511ffd93b99d7de57821c018bbfc0b24.tar.gz blt-1c463eec511ffd93b99d7de57821c018bbfc0b24.tar.bz2 |
update TEA 3.13
Diffstat (limited to 'tktable/library')
-rwxr-xr-x | tktable/library/tkTable.tcl | 825 | ||||
-rwxr-xr-x | tktable/library/tktable.py | 651 |
2 files changed, 0 insertions, 1476 deletions
diff --git a/tktable/library/tkTable.tcl b/tktable/library/tkTable.tcl deleted file mode 100755 index 0343a43..0000000 --- a/tktable/library/tkTable.tcl +++ /dev/null @@ -1,825 +0,0 @@ -# table.tcl -- -# -# Version align with tkTable 2.7, jeff at hobbs org -# This file defines the default bindings for Tk table widgets -# and provides procedures that help in implementing those bindings. -# -# RCS: @(#) $Id: tkTable.tcl,v 1.1.1.1 2011/03/01 20:00:38 joye Exp $ - -#-------------------------------------------------------------------------- -# ::tk::table::Priv elements used in this file: -# -# x && y - Coords in widget -# afterId - Token returned by "after" for autoscanning. -# tablePrev - The last element to be selected or deselected -# during a selection operation. -# mouseMoved - Boolean to indicate whether mouse moved while -# the button was pressed. -# borderInfo - Boolean to know if the user clicked on a border -# borderB1 - Boolean that set whether B1 can be used for the -# interactiving resizing -#-------------------------------------------------------------------------- - -namespace eval ::tk::table { - # Ensure that a namespace is created for us - variable Priv - array set Priv [list x 0 y 0 afterId {} mouseMoved 0 \ - borderInfo {} borderB1 1] -} - -# ::tk::table::ClipboardKeysyms -- -# This procedure is invoked to identify the keys that correspond to -# the "copy", "cut", and "paste" functions for the clipboard. -# -# Arguments: -# copy - Name of the key (keysym name plus modifiers, if any, -# such as "Meta-y") used for the copy operation. -# cut - Name of the key used for the cut operation. -# paste - Name of the key used for the paste operation. - -proc ::tk::table::ClipboardKeysyms {copy cut paste} { - bind Table <$copy> {tk_tableCopy %W} - bind Table <$cut> {tk_tableCut %W} - bind Table <$paste> {tk_tablePaste %W} -} -::tk::table::ClipboardKeysyms <Copy> <Cut> <Paste> - -## -## Interactive cell resizing, affected by -resizeborders option -## -bind Table <3> { - ## You might want to check for cell returned if you want to - ## restrict the resizing of certain cells - %W border mark %x %y -} -bind Table <B3-Motion> { %W border dragto %x %y } - -## Button events - -bind Table <1> { ::tk::table::Button1 %W %x %y } -bind Table <B1-Motion> { ::tk::table::B1Motion %W %x %y } - -bind Table <ButtonRelease-1> { - if {$::tk::table::Priv(borderInfo) == "" && [winfo exists %W]} { - ::tk::table::CancelRepeat - %W activate @%x,%y - } -} -bind Table <Double-1> { - # empty -} - -bind Table <Shift-1> {::tk::table::BeginExtend %W [%W index @%x,%y]} -bind Table <Control-1> {::tk::table::BeginToggle %W [%W index @%x,%y]} -bind Table <B1-Enter> {::tk::table::CancelRepeat} -bind Table <B1-Leave> { - if {$::tk::table::Priv(borderInfo) == ""} { - array set ::tk::table::Priv {x %x y %y} - ::tk::table::AutoScan %W - } -} -bind Table <2> { - %W scan mark %x %y - array set ::tk::table::Priv {x %x y %y} - set ::tk::table::Priv(mouseMoved) 0 -} -bind Table <B2-Motion> { - if {(%x != $::tk::table::Priv(x)) || (%y != $::tk::table::Priv(y))} { - set ::tk::table::Priv(mouseMoved) 1 - } - if {$::tk::table::Priv(mouseMoved)} { %W scan dragto %x %y } -} -bind Table <ButtonRelease-2> { - if {!$::tk::table::Priv(mouseMoved)} { tk_tablePaste %W [%W index @%x,%y] } -} - -## Key events - -# This forces a cell commit if an active cell exists -bind Table <<Table_Commit>> { - catch {%W activate active} -} -# Remove this if you don't want cell commit to occur on every Leave for -# the table (via mouse) or FocusOut (loss of focus by table). -event add <<Table_Commit>> <Leave> <FocusOut> - -bind Table <Shift-Up> {::tk::table::ExtendSelect %W -1 0} -bind Table <Shift-Down> {::tk::table::ExtendSelect %W 1 0} -bind Table <Shift-Left> {::tk::table::ExtendSelect %W 0 -1} -bind Table <Shift-Right> {::tk::table::ExtendSelect %W 0 1} -bind Table <Prior> {%W yview scroll -1 pages; %W activate topleft} -bind Table <Next> {%W yview scroll 1 pages; %W activate topleft} -bind Table <Control-Prior> {%W xview scroll -1 pages} -bind Table <Control-Next> {%W xview scroll 1 pages} -bind Table <Home> {%W see origin} -bind Table <End> {%W see end} -bind Table <Control-Home> { - %W selection clear all - %W activate origin - %W selection set active - %W see active -} -bind Table <Control-End> { - %W selection clear all - %W activate end - %W selection set active - %W see active -} -bind Table <Shift-Control-Home> {::tk::table::DataExtend %W origin} -bind Table <Shift-Control-End> {::tk::table::DataExtend %W end} -bind Table <Select> {::tk::table::BeginSelect %W [%W index active]} -bind Table <Shift-Select> {::tk::table::BeginExtend %W [%W index active]} -bind Table <Control-slash> {::tk::table::SelectAll %W} -bind Table <Control-backslash> { - if {[string match browse [%W cget -selectmode]]} {%W selection clear all} -} -bind Table <Up> {::tk::table::MoveCell %W -1 0} -bind Table <Down> {::tk::table::MoveCell %W 1 0} -bind Table <Left> {::tk::table::MoveCell %W 0 -1} -bind Table <Right> {::tk::table::MoveCell %W 0 1} -bind Table <KeyPress> {::tk::table::Insert %W %A} -bind Table <BackSpace> {::tk::table::BackSpace %W} -bind Table <Delete> {%W delete active insert} -bind Table <Escape> {%W reread} - -#bind Table <Return> {::tk::table::MoveCell %W 1 0} -bind Table <Return> {::tk::table::Insert %W "\n"} - -bind Table <Control-Left> {%W icursor [expr {[%W icursor]-1}]} -bind Table <Control-Right> {%W icursor [expr {[%W icursor]+1}]} -bind Table <Control-e> {%W icursor end} -bind Table <Control-a> {%W icursor 0} -bind Table <Control-k> {%W delete active insert end} -bind Table <Control-equal> {::tk::table::ChangeWidth %W active 1} -bind Table <Control-minus> {::tk::table::ChangeWidth %W active -1} - -# Ignore all Alt, Meta, and Control keypresses unless explicitly bound. -# Otherwise, if a widget binding for one of these is defined, the -# <KeyPress> class binding will also fire and insert the character, -# which is wrong. Ditto for Tab. - -bind Table <Alt-KeyPress> {# nothing} -bind Table <Meta-KeyPress> {# nothing} -bind Table <Control-KeyPress> {# nothing} -bind Table <Any-Tab> {# nothing} -if {[string match "macintosh" $::tcl_platform(platform)]} { - bind Table <Command-KeyPress> {# nothing} -} - -# ::tk::table::GetSelection -- -# This tries to obtain the default selection. On Unix, we first try -# and get a UTF8_STRING, a type supported by modern Unix apps for -# passing Unicode data safely. We fall back on the default STRING -# type otherwise. On Windows, only the STRING type is necessary. -# Arguments: -# w The widget for which the selection will be retrieved. -# Important for the -displayof property. -# sel The source of the selection (PRIMARY or CLIPBOARD) -# Results: -# Returns the selection, or an error if none could be found -# -if {[string compare $::tcl_platform(platform) "unix"]} { - proc ::tk::table::GetSelection {w {sel PRIMARY}} { - if {[catch {selection get -displayof $w -selection $sel} txt]} { - return -code error "could not find default selection" - } else { - return $txt - } - } -} else { - proc ::tk::table::GetSelection {w {sel PRIMARY}} { - if {[catch {selection get -displayof $w -selection $sel \ - -type UTF8_STRING} txt] \ - && [catch {selection get -displayof $w -selection $sel} txt]} { - return -code error "could not find default selection" - } else { - return $txt - } - } -} - -# ::tk::table::CancelRepeat -- -# A copy of tkCancelRepeat, just in case it's not available or changes. -# This procedure is invoked to cancel an auto-repeat action described -# by ::tk::table::Priv(afterId). It's used by several widgets to auto-scroll -# the widget when the mouse is dragged out of the widget with a -# button pressed. -# -# Arguments: -# None. - -proc ::tk::table::CancelRepeat {} { - variable Priv - after cancel $Priv(afterId) - set Priv(afterId) {} -} - -# ::tk::table::Insert -- -# -# Insert into the active cell -# -# Arguments: -# w - the table widget -# s - the string to insert -# Results: -# Returns nothing -# -proc ::tk::table::Insert {w s} { - if {[string compare $s {}]} { - $w insert active insert $s - } -} - -# ::tk::table::BackSpace -- -# -# BackSpace in the current cell -# -# Arguments: -# w - the table widget -# Results: -# Returns nothing -# -proc ::tk::table::BackSpace {w} { - set cur [$w icursor] - if {[string compare {} $cur] && $cur} { - $w delete active [expr {$cur-1}] - } -} - -# ::tk::table::Button1 -- -# -# This procedure is called to handle selecting with mouse button 1. -# It will distinguish whether to start selection or mark a border. -# -# Arguments: -# w - the table widget -# x - x coord -# y - y coord -# Results: -# Returns nothing -# -proc ::tk::table::Button1 {w x y} { - variable Priv - # - # $Priv(borderInfo) is null if the user did not click on a border - # - if {$Priv(borderB1) == 1} { - set Priv(borderInfo) [$w border mark $x $y] - # account for what resizeborders are set [Bug 876320] (ferenc) - set rbd [$w cget -resizeborders] - if {$rbd == "none" || ![llength $Priv(borderInfo)] - || ($rbd == "col" && [lindex $Priv(borderInfo) 1] == "") - || ($rbd == "row" && [lindex $Priv(borderInfo) 0] == "")} { - set Priv(borderInfo) "" - } - } else { - set Priv(borderInfo) "" - } - if {$Priv(borderInfo) == ""} { - # - # Only do this when a border wasn't selected - # - if {[winfo exists $w]} { - ::tk::table::BeginSelect $w [$w index @$x,$y] - focus $w - } - array set Priv [list x $x y $y] - set Priv(mouseMoved) 0 - } -} - -# ::tk::table::B1Motion -- -# -# This procedure is called to start processing mouse motion events while -# button 1 moves while pressed. It will distinguish whether to change -# the selection or move a border. -# -# Arguments: -# w - the table widget -# x - x coord -# y - y coord -# Results: -# Returns nothing -# -proc ::tk::table::B1Motion {w x y} { - variable Priv - - # If we already had motion, or we moved more than 1 pixel, - # then we start the Motion routine - if {$Priv(borderInfo) != ""} { - # - # If the motion is on a border, drag it and skip the rest - # of this binding. - # - $w border dragto $x $y - } else { - # - # If we already had motion, or we moved more than 1 pixel, - # then we start the Motion routine - # - if { - $::tk::table::Priv(mouseMoved) - || abs($x-$::tk::table::Priv(x)) > 1 - || abs($y-$::tk::table::Priv(y)) > 1 - } { - set ::tk::table::Priv(mouseMoved) 1 - } - if {$::tk::table::Priv(mouseMoved)} { - ::tk::table::Motion $w [$w index @$x,$y] - } - } -} - -# ::tk::table::BeginSelect -- -# -# This procedure is typically invoked on button-1 presses. It begins -# the process of making a selection in the table. Its exact behavior -# depends on the selection mode currently in effect for the table; -# see the Motif documentation for details. -# -# Arguments: -# w - The table widget. -# el - The element for the selection operation (typically the -# one under the pointer). Must be in row,col form. - -proc ::tk::table::BeginSelect {w el} { - variable Priv - if {[scan $el %d,%d r c] != 2} return - switch [$w cget -selectmode] { - multiple { - if {[$w tag includes title $el]} { - ## in the title area - if {$r < [$w cget -titlerows]+[$w cget -roworigin]} { - ## We're in a column header - if {$c < [$w cget -titlecols]+[$w cget -colorigin]} { - ## We're in the topleft title area - set inc topleft - set el2 end - } else { - set inc [$w index topleft row],$c - set el2 [$w index end row],$c - } - } else { - ## We're in a row header - set inc $r,[$w index topleft col] - set el2 $r,[$w index end col] - } - } else { - set inc $el - set el2 $el - } - if {[$w selection includes $inc]} { - $w selection clear $el $el2 - } else { - $w selection set $el $el2 - } - } - extended { - $w selection clear all - if {[$w tag includes title $el]} { - if {$r < [$w cget -titlerows]+[$w cget -roworigin]} { - ## We're in a column header - if {$c < [$w cget -titlecols]+[$w cget -colorigin]} { - ## We're in the topleft title area - $w selection set $el end - } else { - $w selection set $el [$w index end row],$c - } - } else { - ## We're in a row header - $w selection set $el $r,[$w index end col] - } - } else { - $w selection set $el - } - $w selection anchor $el - set Priv(tablePrev) $el - } - default { - if {![$w tag includes title $el]} { - $w selection clear all - $w selection set $el - set Priv(tablePrev) $el - } - $w selection anchor $el - } - } -} - -# ::tk::table::Motion -- -# -# This procedure is called to process mouse motion events while -# button 1 is down. It may move or extend the selection, depending -# on the table's selection mode. -# -# Arguments: -# w - The table widget. -# el - The element under the pointer (must be in row,col form). - -proc ::tk::table::Motion {w el} { - variable Priv - if {![info exists Priv(tablePrev)]} { - set Priv(tablePrev) $el - return - } - if {[string match $Priv(tablePrev) $el]} return - switch [$w cget -selectmode] { - browse { - $w selection clear all - $w selection set $el - set Priv(tablePrev) $el - } - extended { - # avoid tables that have no anchor index yet. - if {[catch {$w index anchor}]} { return } - scan $Priv(tablePrev) %d,%d r c - scan $el %d,%d elr elc - if {[$w tag includes title $el]} { - if {$r < [$w cget -titlerows]+[$w cget -roworigin]} { - ## We're in a column header - if {$c < [$w cget -titlecols]+[$w cget -colorigin]} { - ## We're in the topleft title area - $w selection clear anchor end - } else { - $w selection clear anchor [$w index end row],$c - } - $w selection set anchor [$w index end row],$elc - } else { - ## We're in a row header - $w selection clear anchor $r,[$w index end col] - $w selection set anchor $elr,[$w index end col] - } - } else { - $w selection clear anchor $Priv(tablePrev) - $w selection set anchor $el - } - set Priv(tablePrev) $el - } - } -} - -# ::tk::table::BeginExtend -- -# -# This procedure is typically invoked on shift-button-1 presses. It -# begins the process of extending a selection in the table. Its -# exact behavior depends on the selection mode currently in effect -# for the table; see the Motif documentation for details. -# -# Arguments: -# w - The table widget. -# el - The element for the selection operation (typically the -# one under the pointer). Must be in numerical form. - -proc ::tk::table::BeginExtend {w el} { - # avoid tables that have no anchor index yet. - if {[catch {$w index anchor}]} { return } - if {[string match extended [$w cget -selectmode]] && - [$w selection includes anchor]} { - ::tk::table::Motion $w $el - } -} - -# ::tk::table::BeginToggle -- -# -# This procedure is typically invoked on control-button-1 presses. It -# begins the process of toggling a selection in the table. Its -# exact behavior depends on the selection mode currently in effect -# for the table; see the Motif documentation for details. -# -# Arguments: -# w - The table widget. -# el - The element for the selection operation (typically the -# one under the pointer). Must be in numerical form. - -proc ::tk::table::BeginToggle {w el} { - if {[string match extended [$w cget -selectmode]]} { - variable Priv - set Priv(tablePrev) $el - $w selection anchor $el - if {[$w tag includes title $el]} { - scan $el %d,%d r c - if {$r < [$w cget -titlerows]+[$w cget -roworigin]} { - ## We're in a column header - if {$c < [$w cget -titlecols]+[$w cget -colorigin]} { - ## We're in the topleft title area - set end end - } else { - set end [$w index end row],$c - } - } else { - ## We're in a row header - set end $r,[$w index end col] - } - } else { - ## We're in a non-title cell - set end $el - } - if {[$w selection includes $end]} { - $w selection clear $el $end - } else { - $w selection set $el $end - } - } -} - -# ::tk::table::AutoScan -- -# This procedure is invoked when the mouse leaves an table window -# with button 1 down. It scrolls the window up, down, left, or -# right, depending on where the mouse left the window, and reschedules -# itself as an "after" command so that the window continues to scroll until -# the mouse moves back into the window or the mouse button is released. -# -# Arguments: -# w - The table window. - -proc ::tk::table::AutoScan {w} { - if {![winfo exists $w]} return - variable Priv - set x $Priv(x) - set y $Priv(y) - if {$y >= [winfo height $w]} { - $w yview scroll 1 units - } elseif {$y < 0} { - $w yview scroll -1 units - } elseif {$x >= [winfo width $w]} { - $w xview scroll 1 units - } elseif {$x < 0} { - $w xview scroll -1 units - } else { - return - } - ::tk::table::Motion $w [$w index @$x,$y] - set Priv(afterId) [after 50 ::tk::table::AutoScan $w] -} - -# ::tk::table::MoveCell -- -# -# Moves the location cursor (active element) by the specified number -# of cells and changes the selection if we're in browse or extended -# selection mode. If the new cell is "hidden", we skip to the next -# visible cell if possible, otherwise just abort. -# -# Arguments: -# w - The table widget. -# x - +1 to move down one cell, -1 to move up one cell. -# y - +1 to move right one cell, -1 to move left one cell. - -proc ::tk::table::MoveCell {w x y} { - if {[catch {$w index active row} r]} return - set c [$w index active col] - set cell [$w index [incr r $x],[incr c $y]] - while {[string compare [set true [$w hidden $cell]] {}]} { - # The cell is in some way hidden - if {[string compare $true [$w index active]]} { - # The span cell wasn't the previous cell, so go to that - set cell $true - break - } - if {$x > 0} {incr r} elseif {$x < 0} {incr r -1} - if {$y > 0} {incr c} elseif {$y < 0} {incr c -1} - if {[string compare $cell [$w index $r,$c]]} { - set cell [$w index $r,$c] - } else { - # We couldn't find a non-hidden cell, just don't move - return - } - } - $w activate $cell - $w see active - switch [$w cget -selectmode] { - browse { - $w selection clear all - $w selection set active - } - extended { - variable Priv - $w selection clear all - $w selection set active - $w selection anchor active - set Priv(tablePrev) [$w index active] - } - } -} - -# ::tk::table::ExtendSelect -- -# -# Does nothing unless we're in extended selection mode; in this -# case it moves the location cursor (active element) by the specified -# number of cells, and extends the selection to that point. -# -# Arguments: -# w - The table widget. -# x - +1 to move down one cell, -1 to move up one cell. -# y - +1 to move right one cell, -1 to move left one cell. - -proc ::tk::table::ExtendSelect {w x y} { - if {[string compare extended [$w cget -selectmode]] || - [catch {$w index active row} r]} return - set c [$w index active col] - $w activate [incr r $x],[incr c $y] - $w see active - ::tk::table::Motion $w [$w index active] -} - -# ::tk::table::DataExtend -# -# This procedure is called for key-presses such as Shift-KEndData. -# If the selection mode isnt multiple or extend then it does nothing. -# Otherwise it moves the active element to el and, if we're in -# extended mode, extends the selection to that point. -# -# Arguments: -# w - The table widget. -# el - An integer cell number. - -proc ::tk::table::DataExtend {w el} { - set mode [$w cget -selectmode] - if {[string match extended $mode]} { - $w activate $el - $w see $el - if {[$w selection includes anchor]} {::tk::table::Motion $w $el} - } elseif {[string match multiple $mode]} { - $w activate $el - $w see $el - } -} - -# ::tk::table::SelectAll -# -# This procedure is invoked to handle the "select all" operation. -# For single and browse mode, it just selects the active element. -# Otherwise it selects everything in the widget. -# -# Arguments: -# w - The table widget. - -proc ::tk::table::SelectAll {w} { - if {[regexp {^(single|browse)$} [$w cget -selectmode]]} { - $w selection clear all - catch {$w selection set active} - } elseif {[$w cget -selecttitles]} { - $w selection set [$w cget -roworigin],[$w cget -colorigin] end - } else { - $w selection set origin end - } -} - -# ::tk::table::ChangeWidth -- -# -# Adjust the widget of the specified cell by $a. -# -# Arguments: -# w - The table widget. -# i - cell index -# a - amount to adjust by - -proc ::tk::table::ChangeWidth {w i a} { - set tmp [$w index $i col] - if {[set width [$w width $tmp]] >= 0} { - $w width $tmp [incr width $a] - } else { - $w width $tmp [incr width [expr {-$a}]] - } -} - -# tk_tableCopy -- -# -# This procedure copies the selection from a table widget into the -# clipboard. -# -# Arguments: -# w - Name of a table widget. - -proc tk_tableCopy w { - if {[selection own -displayof $w] == "$w"} { - clipboard clear -displayof $w - catch {clipboard append -displayof $w [::tk::table::GetSelection $w]} - } -} - -# tk_tableCut -- -# -# This procedure copies the selection from a table widget into the -# clipboard, then deletes the selection (if it exists in the given -# widget). -# -# Arguments: -# w - Name of a table widget. - -proc tk_tableCut w { - if {[selection own -displayof $w] == "$w"} { - clipboard clear -displayof $w - catch { - clipboard append -displayof $w [::tk::table::GetSelection $w] - $w cursel {} - $w selection clear all - } - } -} - -# tk_tablePaste -- -# -# This procedure pastes the contents of the clipboard to the specified -# cell (active by default) in a table widget. -# -# Arguments: -# w - Name of a table widget. -# cell - Cell to start pasting in. -# -proc tk_tablePaste {w {cell {}}} { - if {[string compare {} $cell]} { - if {[catch {::tk::table::GetSelection $w} data]} return - } else { - if {[catch {::tk::table::GetSelection $w CLIPBOARD} data]} { - return - } - set cell active - } - tk_tablePasteHandler $w [$w index $cell] $data - if {[$w cget -state] == "normal"} {focus $w} -} - -# tk_tablePasteHandler -- -# -# This procedure handles how data is pasted into the table widget. -# This handles data in the default table selection form. -# -# NOTE: this allows pasting into all cells except title cells, -# even those with -state disabled -# -# Arguments: -# w - Name of a table widget. -# cell - Cell to start pasting in. -# -proc tk_tablePasteHandler {w cell data} { - # - # Don't allow pasting into the title cells - # - if {[$w tag includes title $cell]} { - return - } - - set rows [expr {[$w cget -rows]-[$w cget -roworigin]}] - set cols [expr {[$w cget -cols]-[$w cget -colorigin]}] - set r [$w index $cell row] - set c [$w index $cell col] - set rsep [$w cget -rowseparator] - set csep [$w cget -colseparator] - ## Assume separate rows are split by row separator if specified - ## If you were to want multi-character row separators, you would need: - # regsub -all $rsep $data <newline> data - # set data [join $data <newline>] - if {[string compare {} $rsep]} { set data [split $data $rsep] } - set row $r - foreach line $data { - if {$row > $rows} break - set col $c - ## Assume separate cols are split by col separator if specified - ## Unless a -separator was specified - if {[string compare {} $csep]} { set line [split $line $csep] } - ## If you were to want multi-character col separators, you would need: - # regsub -all $csep $line <newline> line - # set line [join $line <newline>] - foreach item $line { - if {$col > $cols} break - $w set $row,$col $item - incr col - } - incr row - } -} - -# tk::table::Sort -- -# -# This procedure handles how data is sorted in the table widget. -# This isn't currently used by tktable, but can be called by the user. -# It's behavior may change in the future. -# -# Arguments: -# w - Name of a table widget. -# start - start cell of rectangle to sort -# end - end cell of rectangle to sort -# col - column within rectangle to sort on -# args - passed to lsort proc (ie: -integer -decreasing) - -proc ::tk::table::Sort {w start end col args} { - set start [$w index $start] - set end [$w index $end] - scan $start %d,%d sr sc - scan $end %d,%d er ec - if {($col < $sc) || ($col > $ec)} { - return -code error "$col is not within sort range $sc to $ec" - } - set col [expr {$col - $sc}] - - set data {} - for {set i $sr} {$i <= $er} {incr i} { - lappend data [$w get $i,$sc $i,$ec] - } - - set i $sr - foreach row [eval [list lsort -index $col] $args [list $data]] { - $w set row $i,$sc $row - incr i - } -} diff --git a/tktable/library/tktable.py b/tktable/library/tktable.py deleted file mode 100755 index d293f9f..0000000 --- a/tktable/library/tktable.py +++ /dev/null @@ -1,651 +0,0 @@ -# Updated tktable.py wrapper for Python 2.x with Tkinter. -# Improvements over previous version can be seen at: -# https://sf.net/tracker2/?func=detail&aid=2244167&group_id=11464&atid=311464 -# -# Copyright (c) 2008, Guilherme Polo -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 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. - -""" -This contains a wrapper class for the tktable widget as well a class for using -tcl arrays that are, in some instances, required by tktable. -""" - -__author__ = "Guilherme Polo <ggpolo@gmail.com>" - -__all__ = ["ArrayVar", "Table"] - -import Tkinter - -def _setup_master(master): - if master is None: - if Tkinter._support_default_root: - master = Tkinter._default_root or Tkinter.Tk() - else: - raise RuntimeError("No master specified and Tkinter is " - "configured to not support default master") - return master - -class ArrayVar(Tkinter.Variable): - def __init__(self, master=None, name=None): - # Tkinter.Variable.__init__ is not called on purpose! I don't wanna - # see an ugly _default value in the pretty array. - self._master = _setup_master(master) - self._tk = self._master.tk - if name: - self._name = name - else: - self._name = 'PY_VAR%s' % id(self) - - def get(self, index=None): - if index is None: - res = {} - for key in self.names(): - res[key] = self._tk.globalgetvar(str(self), key) - return res - - return self._tk.globalgetvar(str(self), str(index)) - - def names(self): - return self._tk.call('array', 'names', self._name) - - def set(self, key, value): - self._tk.globalsetvar(str(self), str(key), value) - - -class Table(Tkinter.Widget): - """Create and manipulate tables.""" - - _switches = ('holddimensions', 'holdselection', 'holdtags', 'holdwindows', - 'keeptitles', '-') - _tabsubst_format = ('%c', '%C', '%i', '%r', '%s', '%S', '%W') - _tabsubst_commands = ('browsecommand', 'browsecmd', 'command', - 'selectioncommand', 'selcmd', - 'validatecommand', 'valcmd') - - def __init__(self, master=None, **kw): - master = _setup_master(master) - try: - master.tk.call('package', 'require', 'Tktable') - except Tkinter.TclError: - try: - master.tk.call('load', 'Tktable.dll', 'Tktable') - except Tkinter.TclError: - master.tk.call('load', '', 'Tktable') - - Tkinter.Widget.__init__(self, master, 'table', kw) - - - def _options(self, cnf, kw=None): - if kw: - cnf = Tkinter._cnfmerge((cnf, kw)) - else: - cnf = Tkinter._cnfmerge(cnf) - - res = () - for k, v in cnf.iteritems(): - if callable(v): - if k in self._tabsubst_commands: - v = "%s %s" % (self._register(v, self._tabsubst), - ' '.join(self._tabsubst_format)) - else: - v = self._register(v) - res += ('-%s' % k, v) - - return res - - - def _tabsubst(self, *args): - if len(args) != len(self._tabsubst_format): - return args - - tk = self.tk - c, C, i, r, s, S, W = args - e = Tkinter.Event() - - e.widget = self - e.c = tk.getint(c) - e.i = tk.getint(i) - e.r = tk.getint(r) - e.C = (e.r, e.c) - try: - e.s = tk.getint(s) - except Tkinter.TclError: - e.s = s - try: - e.S = tk.getint(S) - except Tkinter.TclError: - e.S = S - e.W = W - - return (e,) - - - def _handle_switches(self, args): - args = args or () - return tuple(('-%s' % x) for x in args if x in self._switches) - - - def activate(self, index): - """Set the active cell to the one indicated by index.""" - self.tk.call(self._w, 'activate', index) - - - def bbox(self, first, last=None): - """Return the bounding box for the specified cell (range) as a - 4-tuple of x, y, width and height in pixels. It clips the box to - the visible portion, if any, otherwise an empty tuple is returned.""" - return self._getints(self.tk.call(self._w, 'bbox', first, last)) or () - - - def clear(self, option, first=None, last=None): - """This is a convenience routine to clear certain state information - managed by the table. first and last represent valid table indices. - If neither are specified, then the command operates on the whole - table.""" - self.tk.call(self._w, 'clear', option, first, last) - - - def clear_cache(self, first=None, last=None): - """Clear the specified section of the cache, if the table has been - keeping one.""" - self.clear('cache', first, last) - - - def clear_sizes(self, first=None, last=None): - """Clear the specified row and column areas of specific height/width - dimensions. When just one index is specified, for example 2,0, that - is interpreted as row 2 and column 0.""" - self.clear('sizes', first, last) - - - def clear_tags(self, first=None, last=None): - """Clear the specified area of tags (all row, column and cell tags).""" - self.clear('tags', first, last) - - - def clear_all(self, first=None, last=None): - """Perform all of the above clear functions on the specified area.""" - self.clear('all', first, last) - - - def curselection(self, value=None): - """With no arguments, it returns the sorted indices of the currently - selected cells. Otherwise it sets all the selected cells to the given - value if there is an associated ArrayVar and the state is not - disabled.""" - result = self.tk.call(self._w, 'curselection', value) - if value is None: - return result - - - def curvalue(self, value=None): - """If no value is given, the value of the cell being edited (indexed - by active) is returned, else it is set to the given value. """ - return self.tk.call(self._w, 'curvalue', value) - - - def delete_active(self, index1, index2=None): - """Deletes text from the active cell. If only one index is given, - it deletes the character after that index, otherwise it deletes from - the first index to the second. index can be a number, insert or end.""" - self.tk.call(self._w, 'delete', 'active', index1, index2) - - - def delete_cols(self, index, count=None, switches=None): - args = self._handle_switches(switches) + (index, count) - self.tk.call(self._w, 'delete', 'cols', *args) - - - def delete_rows(self, index, count=None, switches=None): - args = self._handle_switches(switches) + (index, count) - self.tk.call(self._w, 'delete', 'rows', *args) - - - def get(self, first, last=None): - """Returns the value of the cells specified by the table indices - first and (optionally) last.""" - return self.tk.call(self._w, 'get', first, last) - - - def height(self, row=None, **kwargs): - """If row and kwargs are not given, a list describing all rows for - which a width has been set is returned. - If row is given, the height of that row is returnd. - If kwargs is given, then it sets the key/value pairs, where key is a - row and value represents the height for the row.""" - if row is None and not kwargs: - pairs = self.tk.splitlist(self.tk.call(self._w, 'height')) - return dict(pair.split() for pair in pairs) - elif row: - return int(self.tk.call(self._w, 'height', str(row))) - - args = Tkinter._flatten(kwargs.items()) - self.tk.call(self._w, 'height', *args) - - - def hidden(self, *args): - """When called without args, it returns all the hidden cells (those - cells covered by a spanning cell). If one index is specified, it - returns the spanning cell covering that index, if any. If multiple - indices are specified, it returns 1 if all indices are hidden cells, - 0 otherwise.""" - return self.tk.call(self._w, 'hidden', *args) - - - def icursor(self, arg=None): - """If arg is not specified, return the location of the insertion - cursor in the active cell. Otherwise, set the cursor to that point in - the string. - - 0 is before the first character, you can also use insert or end for - the current insertion point or the end of the text. If there is no - active cell, or the cell or table is disabled, this will return -1.""" - return self.tk.call(self._w, 'icursor', arg) - - - def index(self, index, rc=None): - """Return the integer cell coordinate that corresponds to index in the - form row, col. If rc is specified, it must be either 'row' or 'col' so - only the row or column index is returned.""" - res = self.tk.call(self._w, 'index', index, rc) - if rc is None: - return res - else: - return int(res) - - - def insert_active(self, index, value): - """The value is a text string which is inserted at the index postion - of the active cell. The cursor is then positioned after the new text. - index can be a number, insert or end. """ - self.tk.call(self._w, 'insert', 'active', index, value) - - - def insert_cols(self, index, count=None, switches=None): - args = self._handle_switches(switches) + (index, count) - self.tk.call(self._w, 'insert', 'cols', *args) - - - def insert_rows(self, index, count=None, switches=None): - args = self._handle_switches(switches) + (index, count) - self.tk.call(self._w, 'insert', 'rows', *args) - - - #def postscript(self, **kwargs): - # """Skip this command if you are under Windows. - # - # Accepted options: - # colormap, colormode, file, channel, first, fontmap, height, - # last, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, - # width, x, y - # """ - # args = () - # for key, val in kwargs.iteritems(): - # args += ('-%s' % key, val) - # - # return self.tk.call(self._w, 'postscript', *args) - - - def reread(self): - """Rereads the old contents of the cell back into the editing buffer. - Useful for a key binding when <Escape> is pressed to abort the edit - (a default binding).""" - self.tk.call(self._w, 'reread') - - - def scan_mark(self, x, y): - self.tk.call(self._w, 'scan', 'mark', x, y) - - - def scan_dragto(self, x, y): - self.tk.call(self._w, 'scan', 'dragto', x, y) - - - def see(self, index): - self.tk.call(self._w, 'see', index) - - - def selection_anchor(self, index): - self.tk.call(self._w, 'selection', 'anchor', index) - - - def selection_clear(self, first, last=None): - self.tk.call(self._w, 'selection', 'clear', first, last) - - - def selection_includes(self, index): - return self.getboolean(self.tk.call(self._w, 'selection', 'includes', - index)) - - - def selection_set(self, first, last=None): - self.tk.call(self._w, 'selection', 'set', first, last) - - - def set(self, rc=None, index=None, *args, **kwargs): - """If rc is specified (either 'row' or 'col') then it is assumes that - args (if given) represents values which will be set into the - subsequent columns (if row is specified) or rows (for col). - If index is not None and args is not given, then it will return the - value(s) for the cell(s) specified. - - If kwargs is given, assumes that each key in kwargs is a index in this - table and sets the specified index to the associated value. Table - validation will not be triggered via this method. - - Note that the table must have an associated array (defined through the - variable option) in order to this work.""" - if not args and index is not None: - if rc: - args = (rc, index) - else: - args = (index, ) - return self.tk.call(self._w, 'set', *args) - - if rc is None: - args = Tkinter._flatten(kwargs.items()) - self.tk.call(self._w, 'set', *args) - else: - self.tk.call(self._w, 'set', rc, index, args) - - - def spans(self, index=None, **kwargs): - """Manipulate row/col spans. - - When called with no arguments, all known spans are returned as a dict. - When called with only the index, the span for that index only is - returned, if any. Otherwise kwargs is assumed to contain keys/values - pairs used to set spans. A span starts at the row,col defined by a key - and continues for the specified number of rows,cols specified by - its value. A span of 0,0 unsets any span on that cell.""" - if kwargs: - args = Tkinter._flatten(kwargs.items()) - self.tk.call(self._w, 'spans', *args) - else: - return self.tk.call(self._w, 'spans', index) - - - def tag_cell(self, tagname, *args): - return self.tk.call(self._w, 'tag', 'cell', tagname, *args) - - - def tag_cget(self, tagname, option): - return self.tk.call(self._w, 'tag', 'cget', tagname, '-%s' % option) - - - def tag_col(self, tagname, *args): - return self.tk.call(self._w, 'tag', 'col', tagname, *args) - - - def tag_configure(self, tagname, option=None, **kwargs): - """Query or modify options associated with the tag given by tagname. - - If no option is specified, a dict describing all of the available - options for tagname is returned. If option is specified, then the - command returns a list describing the one named option. Lastly, if - kwargs is given then it corresponds to option-value pairs that should - be modified.""" - if option is None and not kwargs: - split1 = self.tk.splitlist( - self.tk.call(self._w, 'tag', 'configure', tagname)) - - result = {} - for item in split1: - res = self.tk.splitlist(item) - result[res[0]] = res[1:] - - return result - - elif option: - return self.tk.call(self._w, 'tag', 'configure', tagname, - '-%s' % option) - - else: - args = () - for key, val in kwargs.iteritems(): - args += ('-%s' % key, val) - - self.tk.call(self._w, 'tag', 'configure', tagname, *args) - - - def tag_delete(self, tagname): - self.tk.call(self._w, 'tag', 'delete', tagname) - - - def tag_exists(self, tagname): - return self.getboolean(self.tk.call(self._w, 'tag', 'exists', tagname)) - - - def tag_includes(self, tagname, index): - return self.getboolean(self.tk.call(self._w, 'tag', 'includes', - tagname, index)) - - - def tag_lower(self, tagname, belowthis=None): - self.tk.call(self._w, 'tag', 'lower', belowthis) - - - def tag_names(self, pattern=None): - return self.tk.call(self._w, 'tag', 'names', pattern) - - - def tag_raise(self, tagname, abovethis=None): - self.tk.call(self._w, 'tag', 'raise', tagname, abovethis) - - - def tag_row(self, tagname, *args): - return self.tk.call(self._w, 'tag', 'row', tagname, *args) - - - def validate(self, index): - """Explicitly validates the specified index based on the current - callback set for the validatecommand option. Return 0 or 1 based on - whether the cell was validated.""" - return self.tk.call(self._w, 'validate', index) - - - @property - def version(self): - """Return tktable's package version.""" - return self.tk.call(self._w, 'version') - - - def width(self, column=None, **kwargs): - """If column and kwargs are not given, a dict describing all columns - for which a width has been set is returned. - If column is given, the width of that column is returnd. - If kwargs is given, then it sets the key/value pairs, where key is a - column and value represents the width for the column.""" - if column is None and not kwargs: - pairs = self.tk.splitlist(self.tk.call(self._w, 'width')) - return dict(pair.split() for pair in pairs) - elif column: - return int(self.tk.call(self._w, 'width', str(column))) - - args = Tkinter._flatten(kwargs.items()) - self.tk.call(self._w, 'width', *args) - - - def window_cget(self, index, option): - return self.tk.call(self._w, 'window', 'cget', index, option) - - - def window_configure(self, index, option=None, **kwargs): - """Query or modify options associated with the embedded window given - by index. This should also be used to add a new embedded window into - the table. - - If no option is specified, a dict describing all of the available - options for index is returned. If option is specified, then the - command returns a list describing the one named option. Lastly, if - kwargs is given then it corresponds to option-value pairs that should - be modified.""" - if option is None and not kwargs: - return self.tk.call(self._w, 'window', 'configure', index) - elif option: - return self.tk.call(self._w, 'window', 'configure', index, - '-%s' % option) - else: - args = () - for key, val in kwargs.iteritems(): - args += ('-%s' % key, val) - - self.tk.call(self._w, 'window', 'configure', index, *args) - - - def window_delete(self, *indexes): - self.tk.call(self._w, 'window', 'delete', *indexes) - - - def window_move(self, index_from, index_to): - self.tk.call(self._w, 'window', 'move', index_from, index_to) - - - def window_names(self, pattern=None): - return self.tk.call(self._w, 'window', 'names', pattern) - - - def xview(self, index=None): - """If index is not given a tuple containing two fractions is returned, - each fraction is between 0 and 1. Together they describe the - horizontal span that is visible in the window. - - If index is given the view in the window is adjusted so that the - column given by index is displayed at the left edge of the window.""" - res = self.tk.call(self._w, 'xview', index) - if index is None: - return self._getdoubles(res) - - - def xview_moveto(self, fraction): - """Adjusts the view in the window so that fraction of the total width - of the table text is off-screen to the left. The fraction parameter - must be a fraction between 0 and 1.""" - self.tk.call(self._w, 'xview', 'moveto', fraction) - - - def xview_scroll(self, number, what): - """Shift the view in the window left or right according to number and - what. The 'number' parameter must be an integer. The 'what' parameter - must be either units or pages or an abbreviation of one of these. - - If 'what' is units, the view adjusts left or right by number cells on - the display; if it is pages then the view adjusts by number screenfuls. - If 'number' is negative then cells farther to the left become visible; - if it is positive then cells farther to the right become visible. """ - self.tk.call(self._w, 'xview', 'scroll', number, what) - - - def yview(self, index=None): - """If index is not given a tuple containing two fractions is returned, - each fraction is between 0 and 1. The first element gives the position - of the table element at the top of the window, relative to the table - as a whole. The second element gives the position of the table element - just after the last one in the window, relative to the table as a - whole. - - If index is given the view in the window is adjusted so that the - row given by index is displayed at the top of the window.""" - res = self.tk.call(self._w, 'yview', index) - if index is None: - return self._getdoubles(res) - - - def yview_moveto(self, fraction): - """Adjusts the view in the window so that the element given by - fraction appears at the top of the window. The fraction parameter - must be a fraction between 0 and 1.""" - self.tk.call(self._w, 'yview', 'moveto', fraction) - - - def yview_scroll(self, number, what): - """Adjust the view in the window up or down according to number and - what. The 'number' parameter must be an integer. The 'what' parameter - must be either units or pages or an abbreviation of one of these. - - If 'what' is units, the view adjusts up or down by number cells; if it - is pages then the view adjusts by number screenfuls. - If 'number' is negative then earlier elements become visible; if it - is positive then later elements become visible. """ - self.tk.call(self._w, 'yview', 'scroll', number, what) - - -# Sample test taken from tktable cvs, original tktable python wrapper -def sample_test(): - from Tkinter import Tk, Label, Button - - def test_cmd(event): - if event.i == 0: - return '%i, %i' % (event.r, event.c) - else: - return 'set' - - def browsecmd(event): - print "event:", event.__dict__ - print "curselection:", test.curselection() - print "active cell index:", test.index('active') - print "active:", test.index('active', 'row') - print "anchor:", test.index('anchor', 'row') - - root = Tk() - - var = ArrayVar(root) - for y in range(-1, 4): - for x in range(-1, 5): - index = "%i,%i" % (y, x) - var.set(index, index) - - label = Label(root, text="Proof-of-existence test for Tktable") - label.pack(side = 'top', fill = 'x') - - quit = Button(root, text="QUIT", command=root.destroy) - quit.pack(side = 'bottom', fill = 'x') - - test = Table(root, - rows=10, - cols=5, - state='disabled', - width=6, - height=6, - titlerows=1, - titlecols=1, - roworigin=-1, - colorigin=-1, - selectmode='browse', - selecttype='row', - rowstretch='unset', - colstretch='last', - browsecmd=browsecmd, - flashmode='on', - variable=var, - usecommand=0, - command=test_cmd) - test.pack(expand=1, fill='both') - test.tag_configure('sel', background = 'yellow') - test.tag_configure('active', background = 'blue') - test.tag_configure('title', anchor='w', bg='red', relief='sunken') - root.mainloop() - -if __name__ == '__main__': - sample_test() |