Posted to tcl by hypnotoad at Mon Jun 03 20:28:44 GMT 2019view raw
- package require clay 0.8
- package provide clay::tk::console 0.1
- ###
- # topic: 3f0e8c2797e7bd5e470fce8f117980095ea094f0
- # description:
- # Open a console window for direct access to the
- # Tcl/Tk command interface to the IRM software suite
- ###
- proc ::console:start {} {
- if {[info command ::CONSOLE] ne {}} {
- CONSOLE wake
- } else {
- set args [list -prompt {wish% } -title {Tcl/Tk Shell}]
- ::clay::tk::console create CONSOLE .tclconsole mixinmap {language ::clay::tk::console.tcl} {*}$args
- }
- CONSOLE redirect_stdout
- }
- # Create a console widget named $w. The prompt string is $prompt.
- # The title at the top of the window is $title. The database connection
- # object is $db
- #
- proc sqlitecon:create {w prompt title db} {
- if {[info commands ::clay::tk::$w] ne {}} {
- ::clay::tk::$w wake
- } else {
- set args [list prompt $prompt title $title db $db]
- destroy $w
- ::clay::tk::console create ::clay::tk::$w $w mixinmap {language ::clay::tk::console.sqlite} {*}$args
- }
- }
- namespace eval ::clay::tk {}
- ###
- # This file implements the clay event manager
- ###
- ::namespace eval ::clay::event {}
- ###
- # topic: f2853d380a732845610e40375bcdbe0f
- # description: Cancel a scheduled event
- ###
- proc ::clay::event::cancel {self {task *}} {
- variable timer_event
- variable timer_script
- foreach {id event} [array get timer_event $self:$task] {
- ::after cancel $event
- set timer_event($id) {}
- set timer_script($id) {}
- }
- }
- ###
- # topic: 8ec32f6b6ba78eaf980524f8dec55b49
- # description:
- # Generate an event
- # Adds a subscription mechanism for objects
- # to see who has recieved this event and prevent
- # spamming or infinite recursion
- ###
- proc ::clay::event::generate {self event args} {
- set wholist [Notification_list $self $event]
- if {$wholist eq {}} return
- set dictargs [::oo::meta::args_to_options {*}$args]
- set info $dictargs
- set strict 0
- set debug 0
- set sender $self
- dict with dictargs {}
- dict set info id [::clay::event::nextid]
- dict set info origin $self
- dict set info sender $sender
- dict set info rcpt {}
- foreach who $wholist {
- catch {::clay::event::notify $who $self $event $info}
- }
- }
- ###
- # topic: 891289a24b8cc52b6c228f6edb169959
- # title: Return a unique event handle
- ###
- proc ::clay::event::nextid {} {
- return "event#[format %0.8x [incr ::clay::event_count]]"
- }
- ###
- # topic: 1e53e8405b4631aec17f98b3e8a5d6a4
- # description:
- # Called recursively to produce a list of
- # who recieves notifications
- ###
- proc ::clay::event::Notification_list {self event {stackvar {}}} {
- set notify_list {}
- foreach {obj patternlist} [array get ::clay::object_subscribe] {
- if {$obj eq $self} continue
- if {$obj in $notify_list} continue
- set match 0
- foreach {objpat eventlist} $patternlist {
- if {![string match $objpat $self]} continue
- foreach eventpat $eventlist {
- if {![string match $eventpat $event]} continue
- set match 1
- break
- }
- if {$match} {
- break
- }
- }
- if {$match} {
- lappend notify_list $obj
- }
- }
- return $notify_list
- }
- ###
- # topic: b4b12f6aed69f74529be10966afd81da
- ###
- proc ::clay::event::notify {rcpt sender event eventinfo} {
- if {[info commands $rcpt] eq {}} return
- if {$::clay::trace} {
- puts [list event notify rcpt $rcpt sender $sender event $event info $eventinfo]
- }
- $rcpt notify $event $sender $eventinfo
- }
- ###
- # topic: 829c89bda736aed1c16bb0c570037088
- ###
- proc ::clay::event::process {self handle script} {
- variable timer_event
- variable timer_script
- array unset timer_event $self:$handle
- array unset timer_script $self:$handle
- set err [catch {uplevel #0 $script} result errdat]
- if $err {
- puts "BGError: $self $handle $script
- ERR: $result
- [dict get $errdat -errorinfo]
- ***"
- }
- }
- ###
- # topic: eba686cffe18cd141ac9b4accfc634bb
- # description: Schedule an event to occur later
- ###
- proc ::clay::event::schedule {self handle interval script} {
- variable timer_event
- variable timer_script
- if {$::clay::trace} {
- puts [list $self schedule $handle $interval]
- }
- if {[info exists timer_event($self:$handle)]} {
- if {$script eq $timer_script($self:$handle)} {
- return
- }
- ::after cancel $timer_event($self:$handle)
- }
- set timer_script($self:$handle) $script
- set timer_event($self:$handle) [::after $interval [list ::clay::event::process $self $handle $script]]
- }
- ###
- # topic: e64cff024027ee93403edddd5dd9fdde
- ###
- proc ::clay::event::subscribe {self who event} {
- upvar #0 ::clay::object_subscribe($self) subscriptions
- if {![info exists subscriptions]} {
- set subscriptions {}
- }
- set match 0
- foreach {objpat eventlist} $subscriptions {
- if {![string match $objpat $who]} continue
- foreach eventpat $eventlist {
- if {[string match $eventpat $event]} {
- # This rule already exists
- return
- }
- }
- }
- dict lappend subscriptions $who $event
- }
- ###
- # topic: 5f74cfd01735fb1a90705a5f74f6cd8f
- ###
- proc ::clay::event::unsubscribe {self args} {
- upvar #0 ::clay::object_subscribe($self) subscriptions
- if {![info exists subscriptions]} {
- return
- }
- switch [llength $args] {
- 1 {
- set event [lindex $args 0]
- if {$event eq "*"} {
- # Shortcut, if the
- set subscriptions {}
- } else {
- set newlist {}
- foreach {objpat eventlist} $subscriptions {
- foreach eventpat $eventlist {
- if {[string match $event $eventpat]} continue
- dict lappend newlist $objpat $eventpat
- }
- }
- set subscriptions $newlist
- }
- }
- 2 {
- set who [lindex $args 0]
- set event [lindex $args 1]
- if {$who eq "*" && $event eq "*"} {
- set subscriptions {}
- } else {
- set newlist {}
- foreach {objpat eventlist} $subscriptions {
- if {[string match $who $objpat]} {
- foreach eventpat $eventlist {
- if {[string match $event $eventpat]} continue
- dict lappend newlist $objpat $eventpat
- }
- }
- }
- set subscriptions $newlist
- }
- }
- }
- }
- set ::clay::tk::winsys [tk windowingsystem]
- if {$::tcl_platform(platform) eq "windows"} {
- set ::clay::tk::platform windows
- catch {::ttk::style theme use xpnative}
- } else {
- if {$::tcl_platform(os) == "Darwin"} {
- set ::clay::tk::platform macosx
- } else {
- set ::clay::tk::platform unix
- }
- catch {::ttk::style theme use clam}
- }
- ::clay::define ::clay::tk::megawidget {
- constructor {tkpath args} {
- set hull $tkpath
- if {![winfo exists $tkpath]} {
- set toplevel $tkpath
- toplevel $tkpath
- } else {
- set toplevel [winfo toplevel $tkpath]
- destroy {*}[winfo children $tkpath]
- }
- my clay delegate hull $hull toplevel $toplevel
- my Config_merge $args
- my Hull_Populate
- my content
- }
- destructor {
- my variable ismain
- if { $ismain } {
- catch {rename ::console:puts ::puts}
- }
- my Hull_Destroy
- }
- Ensemble config::get args {
- return [my Config_get {*}$args]
- }
- Ensemble config::merge args {
- return [my Config_merge {*}$args]
- }
- Ensemble config::set args {
- my Config_set {*}$args
- }
- method Config_get {field args} {
- my variable config option_canonical option_getcmd
- set field [string trimleft $field -]
- if {[info exists option_canonical($field)]} {
- set field $option_canonical($field)
- }
- if {[info exists option_getcmd($field)]} {
- return [eval $option_getcmd($field)]
- }
- if {[dict exists $config $field]} {
- return [dict get $config $field]
- }
- if {[llength $args]} {
- return [lindex $args 0]
- }
- return [my meta cget $field]
- }
- ###
- # topic: dc9fba12ec23a3ad000c66aea17135a5
- ###
- method Config_merge dictargs {
- my variable config option_canonical
- set rawlist $dictargs
- set dictargs {}
- set dat [my clay get option]
- foreach {field val} $rawlist {
- set field [string trim $field -:/]
- if {[info exists option_canonical($field)]} {
- set field $option_canonical($field)
- }
- if {$field eq "mixinmap"} {
- my clay mixinmap {*}$val
- } elseif {$field eq "delegate"} {
- my clay delegate {*}$val
- } else {
- dict set dictargs $field $val
- }
- }
- ###
- # Validate all inputs
- ###
- foreach {field val} $dictargs {
- set script [my clay get option $field validate-command]
- if {$script ne {}} {
- dict set dictargs $field [eval [string map [list %field% [list $field] %value% [list $val] %self% [namespace which my]] $script]]
- }
- }
- ###
- # Apply all inputs with special rules
- ###
- foreach {field val} $dictargs {
- set script [my clay get option $field set-command]
- dict set config $field $val
- if {$script ne {}} {
- {*}[string map [list %field% [list $field] %value% [list $val] %self% [namespace which my]] $script]
- }
- }
- return $dictargs
- }
- method Config_set args {
- set dictargs [::clay::args_to_options {*}$args]
- set dat [my Config_merge $dictargs]
- my Config_triggers $dat
- }
- ###
- # topic: 543c936485189593f0b9ed79b5d5f2c0
- ###
- method Config_triggers dictargs {
- foreach {field val} $dictargs {
- set script [my clay get option $field post-command]
- if {$script ne {}} {
- {*}[string map [list %field% [list $field] %value% [list $val] %self% [namespace which my]] $script]
- }
- }
- }
- method content {} {}
- method event {submethod args} {
- ::clay::event::$submethod [self] {*}$args
- }
- method Option_Default field {
- set info [my meta getnull option $field]
- set getcmd [dict getnull $info default-command:]
- if {$getcmd ne {}} {
- return [{*}[string map [list %field% $field %self% [namespace which my]] $getcmd]]
- } else {
- return [dict getnull $info default:]
- }
- }
- method Hull_Bind tkpath {
- bind $tkpath <Destroy> [namespace code {my Hull_Destroy_From_Tk %w}]
- }
- method Hull_Destroy {} {
- set w [my widget hull]
- if {![winfo exists $w]} return
- bind $w <Destroy> {}
- $w destroy
- }
- method Hull_Destroy_From_Tk {tkpath} {
- set w [my widget hull]
- if { [string match "${tkpath}*" $w] } {
- bind $w <Destroy> {}
- my destroy
- }
- }
- method signal args {}
- # Renames the tcl command that represents the widget to
- # one that resides in the object's namespace. It then renames
- # the object to catch calls to the tk path.
- ###
- method tkalias tkname {
- set oldname $tkname
- my variable tkalias
- set tkalias $tkname
- set self [self]
- set hullwidget [::info object namespace $self]::tkwidget
- my clay delegate tkwidget $hullwidget
- rename ::$tkalias $hullwidget
- my clay delegate hullwidget $hullwidget
- ::clay::object_rename [self] ::$tkalias
- my Hull_Bind $tkname
- return $hullwidget
- }
- method wake {} {
- set hull [my clay delegate hull]
- if {![winfo exists $hull]} {
- my clay delegate toplevel $hull
- toplevel $hull
- my Hull_Populate
- } else {
- catch [list wm deiconify [my widget toplevel]]
- update
- catch [list raise [my widget toplevel]]
- catch [list focus [my widget hull]]
- }
- }
- }
- ###
- # topic: fc7ea2899bddf6a00d04dc7515fd004702d282ef
- # description:
- # By the overt act of typing this comment, the author of this code
- # releases it into the public domain. No claim of copyright is made.
- # In place of a legal notice, here is a blessing:
- #
- # May you do good and not evil.
- # May you find forgiveness for yourself and forgive others.
- # May you share freely, never taking more than you give.
- #
- #
- #
- # This file contains code use to implement a simple command-line console
- # for Tcl/Tk.
- ###
- ::clay::define ::clay::tk::console {
- superclass megawidget
- Variable toplevel {}
- Variable ismain 0
- clay set option language {
- default tcl
- }
- clay set option title {
- default {}
- }
- clay set option prompt {
- default {tcl% }
- }
- set has_consolas [expr {"Consolas" in [font families]}]
- if {$has_consolas} {
- set font {Consolas 10}
- switch $::clay::tk::platform {
- macosx {
- set font {Consolas 12}
- }
- }
- } else {
- set font {fixed 10}
- switch $::clay::tk::platform {
- macosx {
- set font {system 10}
- }
- windows {
- set font {systemfixed 9}
- }
- }
- }
- clay set option font [list \
- widget font \
- description {Font used on console widgets} \
- default $font ]
- clay set signal focus {
- follows *
- action {focus [my clay delegate text]}
- }
- destructor {
- my variable ismain
- if { $ismain } {
- catch {rename ::console:puts ::puts}
- }
- my Hull_Destroy
- set terminate [expr {$hull eq "."}]
- if {$terminate} {
- exit 0
- }
- }
- ###
- # topic: 03ca79afffe63938a00a9bd124316ba6fe83443d
- ###
- method addHistory line {
- my variable v
- if {$v(historycnt)>0} {
- set last [lindex $v(history) [expr $v(historycnt)-1]]
- if {[string compare $last $line]} {
- lappend v(history) $line
- incr v(historycnt)
- }
- } else {
- set v(history) [list $line]
- set v(historycnt) 1
- }
- set v(current) $v(historycnt)
- }
- ###
- # topic: 83fc9e18be0f0d1798c7e20e7ccb23d806e1474c
- # description:
- # Called whenever the mouse leaves the boundries of the widget
- # while button 1 is held down.
- ###
- method B1Leave {x y} {
- my variable v
- set v(y) $y
- set v(x) $x
- my motor
- }
- ###
- # topic: 61622cb601a30cc516a5b227c37e80444ae09911
- # description: Called whenever the mouse moves while button-1 is held down.
- ###
- method B1Motion {x y} {
- my variable v
- set v(y) $y
- set v(x) $x
- my SelectTo $x $y
- }
- ###
- # topic: b8eb39886df4395c26e911532af6c904910c735d
- # description: Erase the character to the left of the cursor
- ###
- method Backspace {} {
- my variable v
- scan [my <text> index insert] %d.%d row col
- if {$col>$v(plength)} {
- my <text> delete {insert -1c}
- }
- }
- ###
- # topic: 055c60d0743072b8d18f23322164664b80fa9328
- ###
- method build_buttons {} {
- my variable v
- set mb [my widget subwindow mb]
- ttk::frame $mb
- my clay delegate buttonframe $mb
- pack $mb -side top -fill x
- menubutton $mb.file -text File -menu $mb.file.m
- menubutton $mb.edit -text Edit -menu $mb.edit.m
- menubutton $mb.tool -text Tools -menu $mb.tool.m
- pack $mb.file $mb.edit $mb.tool -side left -padx 8 -pady 1
- set m [menu $mb.file.m -tearoff 0]
- # $m add command -label {Source...} -command "console:SourceFile $w.t"
- # $m add command -label {Save As...} -command "console:SaveFile $w.t"
- # $m add separator
- $m add command -label {Close} -command [list destroy [my widget hull]]
- $m add command -label {Exit} -command exit
- #$m add command -label {SQLite Console} -command \
- # {::sqlitecon::create .sqlitecon {sqlite> } {SQLite Console} db}
- set m [menu $mb.tool.m -tearoff 0]
- set editmenu $mb.edit.m
- set v(editmenu) $editmenu
- set m [menu $editmenu -tearoff 0]
- $m add command -label Cut -command [namespace code "my Cut"]
- $m add command -label Copy -command [namespace code "my Copy"]
- $m add command -label Paste -command [namespace code "my Paste"]
- $m add command -label {Clear Screen} -command [namespace code "my Clear"]
- $m add separator
- $m add command -label {Source...} -command [namespace code "my SourceFile"]
- $m add command -label {Save As...} -command [namespace code "my SaveFile"]
- catch {$editmenu config -postcommand [namespace code "my EnableEditMenu"]}
- }
- method SBSET {args} {
- set sb [my widget subwindow sb]
- catch {$sb set {*}$args}
- }
- ###
- # topic: 93a511dc8939a3f59315d2b2016946e82cc4c12c
- ###
- method build_console {} {
- set w [my widget hull]
- my variable v
- array set v {
- pressX 0
- mouseMoved 0
- }
- set sb [my widget subwindow sb]
- set st [my widget subwindow console]
- ttk::scrollbar $sb -orient vertical -command "$st yview"
- pack $sb -side right -fill y
- text $st -font [my Config_get font] -yscrollcommand [namespace code {my SBSET}]
- pack $st -side right -fill both -expand 1
- my clay delegate text $st
- set prompt [my Config_get prompt]
- set v(text) $st
- set v(history) 0
- set v(historycnt) 0
- set v(current) -1
- set v(prompt) $prompt
- set v(prior) {}
- set v(plength) [string length $v(prompt)]
- set v(x) 0
- set v(y) 0
- $st mark set insert end
- $st tag config ok -foreground blue
- $st tag config err -foreground red
- $st tag config grn -foreground #00a000
- $st tag config purple -foreground #c000c0
- $st tag config lblue -foreground #417a9b
- $st tag config orange -foreground #be9e4f
- $st insert end $v(prompt)
- $st mark set out 1.0
- my signal focus
- bindtags $st [list $st . all]
- bind $st <1> [namespace code {my Button1 %x %y}]
- bind $st <B1-Motion> [namespace code {my B1Motion %x %y}]
- bind $st <B1-Leave> [namespace code {my B1Leave %x %y}]
- bind $st <B1-Enter> [namespace code {my cancelMotor}]
- bind $st <ButtonRelease-1> [namespace code {my cancelMotor}]
- bind $st <KeyPress> [namespace code {my Insert %A}]
- bind $st <Left> [namespace code {my Left}]
- bind $st <Control-b> [namespace code {my Left}]
- bind $st <Right> [namespace code {my Right}]
- bind $st <Control-f> [namespace code {my Right}]
- bind $st <BackSpace> [namespace code {my Backspace}]
- bind $st <Control-h> [namespace code {my Backspace}]
- bind $st <Delete> [namespace code {my Delete}]
- bind $st <Control-d> [namespace code {my Delete}]
- bind $st <Home> [namespace code {my Home}]
- bind $st <Control-a> [namespace code {my Home}]
- bind $st <End> [namespace code {my End}]
- bind $st <Control-e> [namespace code {my End}]
- bind $st <Return> [namespace code {my Enter}]
- bind $st <KP_Enter> [namespace code {my Enter}]
- bind $st <Up> [namespace code {my Prior}]
- bind $st <Control-p> [namespace code {my Prior}]
- bind $st <Down> [namespace code {my Next}]
- bind $st <Control-n> [namespace code {my Next}]
- bind $st <Control-k> [namespace code {my EraseEOL}]
- bind $st <<Cut>> [namespace code {my Cut}]
- bind $st <<Copy>> [namespace code {my Copy}]
- bind $st <<Paste>> [namespace code {my Paste}]
- bind $st <<Clear>> [namespace code {my Clear}]
- }
- ###
- # topic: 67ea0661809dd66ff34b45263c465789bfbb9591
- # description:
- # Called when the mouse button is pressed at position $x,$y on
- # the console widget.
- ###
- method Button1 {x y} {
- global tkPriv
- set w [my clay delegate text]
- my variable v
- set v(mouseMoved) 0
- set v(pressX) $x
- set p [my nearestBoundry $x $y]
- scan [my <text> index insert] %d.%d ix iy
- scan $p %d.%d px py
- if {$px==$ix} {
- my <text> mark set insert $p
- }
- my <text> mark set anchor $p
- focus $w
- }
- ###
- # topic: 937a1570589f78997120e0f82d9989651a462dad
- # description: This routine cancels the scrolling motor if it is active
- ###
- method cancelMotor {} {
- my event cancel motor
- }
- ###
- # topic: 968b14fc7c6cbd13fd8a23f3d635ae0da45c6561
- # description:
- # Return 1 if the selection exists and is contained
- # entirely on the input line. Return 2 if the selection
- # exists but is not entirely on the input line. Return 0
- # if the selection does not exist.
- ###
- method canCut {} {
- set r [catch {
- scan [my <text> index sel.first] %d.%d s1x s1y
- scan [my <text> index sel.last] %d.%d s2x s2y
- scan [my <text> index insert] %d.%d ix iy
- }]
- if {$r==1} {return 0}
- if {$s1x==$ix && $s2x==$ix} {return 1}
- return 2
- }
- ###
- # topic: 4a6b17559391aff67a3b8d9e850da371c89ff5ab
- # description: Erase everything from the console above the insertion line.
- ###
- method Clear {} {
- my <text> delete 1.0 {insert linestart}
- }
- ###
- # topic: cca0174bee56d0c82519a22c26fa417a3d61e373
- # description: Do a Copy operation on the stuff currently selected.
- ###
- method Copy {} {
- set w [my clay delegate text]
- if {![catch {set text [my <text> get sel.first sel.last]}]} {
- clipboard clear -displayof $w
- clipboard append -displayof $w $text
- }
- }
- ###
- # topic: 5600bf5544e3c2a4c7d5b2a8a8f77e3cf4fb80f1
- # description:
- # Do a Cut operation if possible. Cuts are only allowed
- # if the current selection is entirely contained on the
- # current input line.
- ###
- method Cut {} {
- if {[my canCut]==1} {
- my Copy
- my <text> delete sel.first sel.last
- }
- }
- ###
- # topic: 340c92b30cf1d0ee90eac3cc9ee0ff99360bb42d
- # description: Erase the character to the right of the cursor
- ###
- method Delete {} {
- my <text> delete insert
- }
- ###
- # topic: a11cb7a2a3118e0f46a332542e4853543f18cf8b
- ###
- method dialog_preferences {} {
- set pvar [my varname prefs]
- set f [my widget hull]
- if {[winfo exists $f.prefs]} {
- destroy {*}[winfo children $f.prefs]
- wm deiconify $f.prefs
- raise $f.prefs
- $f.prefs signal build_content
- } else {
- ::clay::tk::preference_panel $f.prefs object [self]
- }
- }
- ###
- # topic: 0c0ea9da28a51f2440c58c80021e67e605d750db
- # description: Enable or disable entries in the Edit menu
- ###
- method EnableEditMenu {} {
- my variable v
- set m $v(editmenu)
- if {$m=="" || ![winfo exists $m]} return
- switch [my canCut] {
- 0 {
- $m entryconf Copy -state disabled
- $m entryconf Cut -state disabled
- }
- 1 {
- $m entryconf Copy -state normal
- $m entryconf Cut -state normal
- }
- 2 {
- $m entryconf Copy -state normal
- $m entryconf Cut -state disabled
- }
- }
- }
- ###
- # topic: b6157a20658fef4530840f60f8163984a8c0bd6b
- # description: Move the cursor to the end of the current line
- ###
- method End {} {
- my <text> mark set insert {insert lineend}
- }
- ###
- # topic: ade17f15ff8a2b984f503c9570066952844ddf4e
- # description: Erase to the end of the line
- ###
- method EraseEOL {} {
- my variable v
- scan [my <text> index insert] %d.%d row col
- if {$col>=$v(plength)} {
- my <text> delete insert {insert lineend}
- }
- }
- ###
- # topic: ab0549c4965bf2dabdd74d318531a3a2bc90cf85
- # description: Move the cursor to the beginning of the current line
- ###
- method Home {} {
- my variable v
- scan [my <text> index insert] %d.%d row col
- my <text> mark set insert $row.$v(plength)
- }
- ###
- # topic: 04d56668301bb768d53522d5754828bf8b8e2cfa
- ###
- method Hull_Populate {} {
- set t [my widget toplevel]
- set w [my widget hull]
- set prompt [my Config_get prompt]
- set title [my Config_get title]
- upvar #0 $w.t v
- if {[info exists v]} {unset v}
- wm title $w $title
- wm iconname $w $title
- my clay delegate hull $t
- my build_buttons
- my build_console
- }
- ###
- # topic: f21c52fa306df0b911649a088f634792260f9bc3
- # description: Insert a single character at the insertion cursor
- ###
- method Insert a {
- my <text> insert insert $a
- my <text> yview insert
- }
- ###
- # topic: a86a704912089f9f69a51608a795ca78846e1c59
- ###
- method insert text {
- my insert $a
- my Enter
- }
- ###
- # topic: a893a71497eca915ca47f88a86f296a05ce1fcab
- # description: Move the cursor one character to the left
- ###
- method Left {} {
- my variable v
- scan [my <text> index insert] %d.%d row col
- if {$col>$v(plength)} {
- my <text> mark set insert "insert -1c"
- }
- }
- ###
- # topic: f7d39c17edaa0287b478e6e9924e1ad6c5376ddc
- # description:
- # This routine is called to automatically scroll the window when
- # the mouse drags offscreen.
- ###
- method motor {} {
- my variable v
- set w [my clay delegate text]
- if {![winfo exists $w]} return
- if {$v(y)>=[winfo height $w]} {
- $w yview scroll 1 units
- } elseif {$v(y)<0} {
- $w yview scroll -1 units
- } else {
- return
- }
- my SelectTo $v(x) $v(y)
- my event schedule motor 50 [namespace code {my motor}]
- }
- ###
- # topic: 9089b1e19d4d54d37830de5832c94ed317abfc54
- # description:
- # Find the boundry between characters that is nearest
- # to $x,$y
- ###
- method nearestBoundry {x y} {
- my variable v
- set p [my <text> index @$x,$y]
- set bb [my <text> bbox $p]
- if {![string compare $bb ""]} {return $p}
- if {($x-[lindex $bb 0])<([lindex $bb 2]/2)} {return $p}
- my <text> index "$p + 1 char"
- }
- ###
- # topic: f2543342648de822341ab839b19fc875549c0d71
- # description: Change the line to the next line
- ###
- method Next {} {
- my variable v
- if {$v(current)>=$v(historycnt)} return
- incr v(current) 1
- set line [lindex $v(history) $v(current)]
- my SetLine $line
- }
- ###
- # topic: 1fbaa6cd76c0ba81725f87e67e30c28f13a42de4
- ###
- method Option_set::font newvalue {
- my <text> configure -font $newvalue
- }
- ###
- # topic: c2f59206f13fc6cd17ba0cc916d4b64853545642
- # description: Do a paste opeation.
- ###
- method Paste {} {
- my variable v
- if {[my canCut]==1} {
- my <text> delete sel.first sel.last
- }
- set w [my clay delegate text]
- if {[catch {selection get -displayof $w -selection CLIPBOARD} topaste]
- && [catch {selection get -displayof $w -selection PRIMARY} topaste]} {
- return
- }
- set prior 0
- foreach line [split $topaste \n] {
- if {$prior} {
- my Enter
- update
- }
- set prior 1
- my <text> insert insert $line
- }
- }
- ###
- # topic: 1bdd01f30493ccdf242fcb581c188a861bc51246
- # description: Change the line to the previous line
- ###
- method Prior {} {
- my variable v
- if {$v(current)<=0} return
- incr v(current) -1
- set line [lindex $v(history) $v(current)]
- my SetLine $line
- }
- ###
- # topic: f58b9ac700bd1dc6748c89a4d346e7cc4a068bf6
- # description:
- # Insert test at the "out" mark. The "out" mark is always
- # before the input line. New text appears on the line prior
- # to the current input line.
- ###
- method puts {t tag} {
- set nc [string length $t]
- set endc [string index $t [expr $nc-1]]
- if {$endc=="\n"} {
- if {[my <text> index out]<[my <text> index {insert linestart}]} {
- my <text> insert out [string range $t 0 [expr $nc-2]] $tag
- my <text> mark set out {out linestart +1 lines}
- } else {
- my <text> insert out $t $tag
- }
- } else {
- if {[my <text> index out]<[my <text> index {insert linestart}]} {
- my <text> insert out $t $tag
- } else {
- my <text> insert out $t\n $tag
- my <text> mark set out {out -1 char}
- }
- }
- my <text> yview insert
- }
- ###
- # topic: c7a8603d316f43da21effe7223902dd2853ded43
- # description: Move the cursor one character to the right
- ###
- method Right {} {
- my <text> mark set insert "insert +1c"
- }
- ###
- # topic: 0833547d2ad5522b8a54fa0d92d339e4197ab635
- # description:
- # Prompt the user for the name of a writable file. Then write the
- # entire contents of the console screen to that file.
- ###
- method SaveFile {} {
- set types {
- {{Text Files} {.txt}}
- {{All Files} *}
- }
- set f [tk_getSaveFile -filetypes $types -title "Write Screen To..."]
- if {$f!=""} {
- if {[catch {open $f w} fd]} {
- ::clay::tk::dialog -type ok -icon error -message {Error writing file} -detail $fd
- } else {
- puts $fd [string trimright [my <text> get 1.0 end] \n]
- close $fd
- }
- }
- }
- ###
- # topic: 71af63e2fb369f7677c165caa724b99b2ac0ca26
- # description: This routine extends the selection to the point specified by {$x,$y}
- ###
- method SelectTo {x y} {
- my variable v
- set cur [my nearestBoundry $x $y]
- if {[catch {my <text> index anchor}]} {
- my <text> mark set anchor $cur
- }
- set anchor [my <text> index anchor]
- if {[my <text> compare $cur != $anchor] || (abs($v(pressX) - $x) >= 3)} {
- if {$v(mouseMoved)==0} {
- my <text> tag remove sel 0.0 end
- }
- set v(mouseMoved) 1
- }
- if {[my <text> compare $cur < anchor]} {
- set first $cur
- set last anchor
- } else {
- set first anchor
- set last $cur
- }
- if {$v(mouseMoved)} {
- my <text> tag remove sel 0.0 $first
- my <text> tag add sel $first $last
- my <text> tag remove sel $last end
- update idletasks
- }
- }
- ###
- # topic: d832f029f5a3c95ebbbc0c7f46b053151dbecd2e
- # description: Change the contents of the entry line
- ###
- method SetLine line {
- my variable v
- scan [my <text> index insert] %d.%d row col
- set start $row.$v(plength)
- my <text> delete $start end
- my <text> insert end $line
- my <text> mark set insert end
- my <text> yview insert
- }
- Ensemble widget::toplevel {} {
- return [my clay delegate toplevel]
- }
- Ensemble widget::hull {} {
- return [my clay delegate hull]
- }
- Ensemble widget::parent {} {
- return [winfo parent [my clay delegate hull]]
- }
- Ensemble widget::subwindow path {
- set tl [string trimleft [my widget hull] .]
- if { $tl eq {} } {
- return .[string trimleft $path .]
- }
- return .$tl.[string trimleft $path .]
- }
- }
- ::clay::define ::clay::tk::console.tcl {
- ###
- # topic: c3d3bed792724df80d4ee0a5b1bc486d2501fd69
- # description:
- # Called when "Enter" is pressed. Do something with the line
- # of text that was entered.
- ###
- method Enter {} {
- my variable v
- set w [my clay delegate text]
- scan [my <text> index insert] %d.%d row col
- set start $row.$v(plength)
- set line [my <text> get $start "$start lineend"]
- my addHistory $line
- my <text> insert end \n
- my <text> mark set out end
- if {$v(prior)==""} {
- set cmd $line
- } else {
- set cmd $v(prior)\n$line
- }
- if {[info complete $cmd]} {
- set rc [catch {uplevel #0 $cmd} res]
- if {![winfo exists $w]} return
- if {$rc} {
- my <text> insert end $res\n err
- } elseif {[string length $res]>0} {
- my <text> insert end $res\n ok
- }
- set v(prior) {}
- my <text> insert end $v(prompt)
- } else {
- set v(prior) $cmd
- regsub -all {[^ ]} $v(prompt) . x
- my <text> insert end $x
- }
- my <text> mark set insert end
- my <text> mark set out {insert linestart}
- my <text> yview insert
- }
- ###
- # topic: adb57b892b7da0eb46ab54c904f0de9cb1e31e01
- ###
- method redirect_stdout {} {
- my variable ismain
- if { $ismain } return
- set nspace [namespace current]
- set my [namespace which my]
- set newproc ::console:puts
- if {[info command $newproc] eq {}} {
- catch {rename puts $newproc}
- }
- proc ::puts args [string map [list %newproc% $newproc %nspace% $nspace %self% $my] {
- if {[info command %self%] eq {} } {
- uplevel #0 %newproc% $args
- ::rename ::puts {}
- ::rename %newproc% ::puts
- return
- }
- switch -glob -- "[llength $args] $args" {
- {1 *} {
- set msg [lindex $args 0]\n
- set tag ok
- }
- {2 stdout *} {
- set msg [lindex $args 1]\n
- set tag ok
- }
- {2 stderr *} {
- set msg [lindex $args 1]\n
- set tag err
- }
- {2 green *} {
- set msg [lindex $args 1]\n
- set tag grn
- }
- {2 purple *} {
- set msg [lindex $args 1]\n
- set tag purple
- }
- {2 lightblue *} {
- set msg [lindex $args 1]\n
- set tag lblue
- }
- {2 orange *} {
- set msg [lindex $args 1]\n
- set tag orange
- }
- {2 -nonewline *} {
- set msg [lindex $args 1]
- set tag ok
- }
- {3 -nonewline stdout *} {
- set msg [lindex $args 2]
- set tag ok
- }
- {3 -nonewline stderr *} {
- set msg [lindex $args 2]
- set tag err
- }
- default {
- uplevel #0 %newproc% $args
- return
- }
- }
- %self% puts $msg $tag
- }]
- set ismain 1
- return {}
- }
- ###
- # topic: 85c1d45d5027823e4407e59dbdfadca12a15d689
- # description: Prompt for the user to select an input file, the source that file.
- ###
- method SourceFile {} {
- set types {
- {{TCL Scripts} {.tcl}}
- {{All Files} *}
- }
- set f [tk_getOpenFile -filetypes $types -title "TCL Script To Source..."]
- if {$f!=""} {
- uplevel #0 [list source [file normalize $f]]
- }
- }
- }
- ::clay::define ::clay::tk::console.sqlite {
- clay set option db {class organ}
- clay set option prompt {default {sqlite-> }}
- clay set option title {default {SQLite Console}}
- clay set option header {datatype boolean default 1}
- clay set option mode {widget select default column values {line list column csv multicolumn}}
- ###
- # topic: 43e235cf3b612e95c590e5de400d4bcc39d622a4
- # description:
- # Execute a single SQL command. Pay special attention to control
- # directives that begin with "."
- #
- # The return value is the text output from the command, properly
- # formatted.
- ###
- method DoCommand cmd {
- my clay delegate db [my Config_get db]
- my variable v
- set mode [my Config_get mode]
- set header [my Config_get header]
- if {[regexp {^(\.[a-z]+)} $cmd all word]} {
- if {$word==".tcl"} {
- my tcl_console
- return {}
- } elseif {$word==".mode"} {
- regexp {^.[a-z]+ +([a-z]+)} $cmd all newvalue
- my config set [list mode $newvalue]
- return {}
- } elseif {$word==".exit"} {
- my destroy
- return {}
- } elseif {$word==".header"} {
- regexp {^.[a-z]+ +([a-z]+)} $cmd all newvalue
- my config set [list header $newvalue]
- return {}
- } elseif {$word==".tables"} {
- set mode multicolumn
- set cmd {SELECT name FROM sqlite_master WHERE type='table'
- UNION ALL
- SELECT name FROM sqlite_temp_master WHERE type='table'}
- my <db> eval {PRAGMA database_list} {
- if {$name!="temp" && $name!="main"} {
- append cmd "UNION ALL SELECT name FROM $name.sqlite_master\
- WHERE type='table'"
- }
- }
- append cmd { ORDER BY 1}
- } elseif {$word==".fullschema"} {
- set pattern %
- regexp {^.[a-z]+ +([^ ]+)} $cmd all pattern
- set mode list
- set header 0
- set cmd "SELECT sql FROM sqlite_master WHERE tbl_name LIKE '$pattern'
- AND sql NOT NULL UNION ALL SELECT sql FROM sqlite_temp_master
- WHERE tbl_name LIKE '$pattern' AND sql NOT NULL"
- my <db> eval {PRAGMA database_list} {
- if {$name!="temp" && $name!="main"} {
- append cmd " UNION ALL SELECT sql FROM $name.sqlite_master\
- WHERE tbl_name LIKE '$pattern' AND sql NOT NULL"
- }
- }
- } elseif {$word==".schema"} {
- set pattern %
- regexp {^.[a-z]+ +([^ ]+)} $cmd all pattern
- set mode list
- set header 0
- set cmd "SELECT sql FROM sqlite_master WHERE name LIKE '$pattern'
- AND sql NOT NULL UNION ALL SELECT sql FROM sqlite_temp_master
- WHERE name LIKE '$pattern' AND sql NOT NULL"
- my <db> eval {PRAGMA database_list} {
- if {$name!="temp" && $name!="main"} {
- append cmd " UNION ALL SELECT sql FROM $name.sqlite_master\
- WHERE name LIKE '$pattern' AND sql NOT NULL"
- }
- }
- } else {
- return \
- ".exit\n.mode line|list|column|csv\n.schema ?TABLENAME?\n.tables\n.tcl"
- }
- }
- set res {}
- if {$mode=="list"} {
- my <db> eval $cmd x {
- set sep {}
- foreach col $x(*) {
- append res $sep$x($col)
- set sep |
- }
- append res \n
- }
- if {[info exists x(*)] && $header} {
- set sep {}
- set hdr {}
- foreach col $x(*) {
- append hdr $sep$col
- set sep |
- }
- set res $hdr\n$res
- }
- } elseif {[string range $mode 0 2]=="col"} {
- set y {}
- my <db> eval $cmd x {
- foreach col $x(*) {
- if {![info exists cw($col)] || $cw($col)<[string length $x($col)]} {
- set cw($col) [string length $x($col)]
- }
- lappend y $x($col)
- }
- }
- if {[info exists x(*)] && $header} {
- set hdr {}
- set ln {}
- set dash ---------------------------------------------------------------
- append dash ------------------------------------------------------------
- foreach col $x(*) {
- if {![info exists cw($col)] || $cw($col)<[string length $col]} {
- set cw($col) [string length $col]
- }
- lappend hdr $col
- lappend ln [string range $dash 1 $cw($col)]
- }
- set y [concat $hdr $ln $y]
- }
- if {[info exists x(*)]} {
- set format {}
- set arglist {}
- set arglist2 {}
- set i 0
- foreach col $x(*) {
- lappend arglist x$i
- append arglist2 " \$x$i"
- incr i
- append format " %-$cw($col)s"
- }
- set format [string trimleft $format]\n
- if {[llength $arglist]>0} {
- foreach $arglist $y "append res \[format [list $format] $arglist2\]"
- }
- }
- } elseif {$mode=="multicolumn"} {
- set y [my <db> eval $cmd]
- set max 0
- foreach e $y {
- if {$max<[string length $e]} {set max [string length $e]}
- }
- set ncol [expr {int(80/($max+2))}]
- if {$ncol<1} {set ncol 1}
- set nelem [llength $y]
- set nrow [expr {($nelem+$ncol-1)/$ncol}]
- set format "%-${max}s"
- for {set i 0} {$i<$nrow} {incr i} {
- set j $i
- while 1 {
- append res [format $format [lindex $y $j]]
- incr j $nrow
- if {$j>=$nelem} break
- append res { }
- }
- append res \n
- }
- } elseif {$mode=="csv"} {
- my <db> eval $cmd x {
- set sep {}
- foreach col $x(*) {
- set val $x($col)
- if {$val=="" || [regexp {[\s",]} $val]} {
- set val \"[string map [list \" \"\"] $val]\"
- }
- append res $sep$val
- set sep ,
- }
- append res \n
- }
- } else {
- my <db> eval $cmd x {
- foreach col $x(*) {append res "$col = $x($col)\n"}
- append res \n
- }
- }
- return [string trimright $res]
- }
- ###
- # topic: 93d94ab333ba8ad804eefcc8bba8afa95b1e0dcf
- ###
- method Enter {} {
- my variable v
- set w [my clay delegate text]
- scan [my <text> index insert] %d.%d row col
- set start $row.$v(plength)
- set line [my <text> get $start "$start lineend"]
- my <text> insert end \n
- my <text> mark set out end
- if {$v(prior)==""} {
- set cmd $line
- } else {
- set cmd $v(prior)\n$line
- }
- if {[string index $cmd 0]=="." || [my <db> complete $cmd]} {
- regsub -all {\n} [string trim $cmd] { } cmd2
- my addHistory $cmd2
- set rc [catch {my DoCommand $cmd} res]
- if {![winfo exists $w]} return
- if {$rc} {
- my <text> insert end $res\n err
- } elseif {[string length $res]>0} {
- my <text> insert end $res\n ok
- }
- set v(prior) {}
- my <text> insert end $v(prompt)
- } else {
- set v(prior) $cmd
- regsub -all {[^ ]} $v(prompt) . x
- my <text> insert end $x
- }
- my <text> mark set insert end
- my <text> mark set out {insert linestart}
- my <text> yview insert
- }
- method tcl_console {} {
- set w [my widget toplevel]
- if {$w ne "."} {
- console:start
- } else {
- if {[winfo exists .tclconsole]} {
- catch {wm deiconify .tclconsole}
- update
- catch {raise .tclconsole}
- } else {
- set args [list -prompt {wish% } -title {Tcl/Tk Shell}]
- taotk::console .tclconsole {*}$args
- }
- .tclconsole redirect_stdout
- wm title .tclconsole "TCL [my Config_get title]"
- .tclconsole puts "SQL Object Available as [my Config_get db]" green
- }
- }
- }
- # Start the console
- #
- # console:create {.@console} {% } {Tcl/Tk Console}