package require Tktable # The [catch] below is a workaround for the bug in Galileo Galilei supplying 3.8.3.1 instead of 3.8.3 catch {package require sqlite3} namespace path ::tcl::mathop catch {font create myfont -family courier -size 10} wm attributes . -fullscreen 1 # Create a Tktable for display of an attached file's schema proc maketable {attachedname} { global tableinfo destroy {*}[winfo children .] set f [filename2widgetname $attachedname] set tableinfo(framename,$attachedname) $f pack [frame $f ] -padx 5 -pady 5 set t $f.t table $t -cols [expr {$::tableinfo(maxnumcols,$attachedname)+2}] -rows [expr {$::tableinfo(numtables,$attachedname)+1}] \ -titlecols 1 -titlerows 1 -font myfont -command [list filltable %i %r %c %s $attachedname] -anchor w \ -xscrollcommand [list ${t}sx set] -yscrollcommand [list ${t}sy set] -height 0 -width 0 -ipadx 4 $t tag col entries 1 $t tag configure entries -anchor e $t width 0 18 scrollbar ${t}sy -orient vert -width 30 -command [list $t yview] scrollbar ${t}sx -orient horiz -width 30 -command [list $t xview] grid $t ${t}sy -sticky nsew grid ${t}sx -sticky new grid columnconfigure $f 0 -weight 1 } # Redraw the table (and enclosing frame) when the orientation is changed # Assumes the table widget is named xxxxxx.t and is enclosed in a frame proc frameconfig tablewidget { if {[string range $tablewidget end-1 end] ne ".t"} return array set metrics [borg displaymetrics] set w [- $metrics(width) 10] set h [- $metrics(height) 10] [string range $tablewidget 0 end-2] configure -width $w -height $h $tablewidget configure -maxwidth [- $w 30] -maxheight [- $h 30] -width 0 -height 0 } # Called by tktable innards to get values to show with display colnum & rownum proc filltable { iswrite rownum colnum tblval attachedname} { set retval {} if { ! $iswrite} { if {$rownum == 0} { switch $colnum \ 0 {set retval Table} \ 1 {set retval Entries} \ default {set retval "F [expr $colnum - 1]"} } else { set rownum [expr {$rownum-1}] set tablename $::tableinfo(tablename,$attachedname,$rownum) if {$colnum == 0} {set retval $tablename} if {$colnum == 1} {set retval $::tableinfo(numentries,$attachedname,$tablename)} if {$colnum > 1 && $colnum <= $::tableinfo(numcols,$attachedname,$tablename)+1} {set retval $::tableinfo(colname,$attachedname,$tablename,[expr {$colnum - 1}]) } } } return $retval } # Attach a file and set up tableinfo global array proc attachfile {filename attachedname} { global tableinfo db eval "attach \"$filename\" as $attachedname" set tablesql_list [db eval "select sql from $attachedname.sqlite_master where type = 'table'"] set tableinfo(numtables,$attachedname) [llength $tablesql_list] set tablenum 0 set tableinfo(maxnumcols,$attachedname) 0 foreach tablesql $tablesql_list { regsub -nocase {create table } $tablesql {} tablesql regsub -all { +} $tablesql { } tablesql] scan $tablesql {%[^(]%[^!]} tablename tabledef set tableinfo(tablename,$attachedname,$tablenum) $tablename set tableinfo(tablenum,$attachedname,$tablename) $tablenum set tableinfo(tabledef,$attachedname,$tablename) $tabledef set tableinfo(numentries,$attachedname,$tablename) [db eval "select count(*) from $attachedname.$tablename"] set colnum 0 regexp {\((.*)\)} $tabledef -> tabledefguts foreach coldef [splitcols $tabledefguts] { set isconstraint [regexp -nocase {^unique|^check|^primary key|^not null|^default|^collate|^references} $coldef] if {$isconstraint} { lappend tableinfo(constraint,$attachedname,$tablename) $coldef } else { incr colnum set colname [coldef2colname $coldef] set tableinfo(colname,$attachedname,$tablename,$colnum) $colname set tableinfo(colnum,$attachedname,$tablename,$colname) $colnum } } set tableinfo(numcols,$attachedname,$tablename) $colnum set tableinfo(maxnumcols,$attachedname) [lindex [lsort -integer -decreasing [list $colnum $tableinfo(maxnumcols,$attachedname)]] 0] incr tablenum } } # Split a table definition at any comma not inside parentheses and return the list of column defs proc splitcols tabledef { set collist [list] set colstring "" set parendepth 0 foreach char [split $tabledef {}] { if {$char eq "("} { incr parendepth } elseif {$char eq ")"} { incr parendepth -1 } if {$char ne "," || $parendepth > 0} { append colstring $char } else { lappend collist [string trim $colstring] set colstring "" } } lappend collist [string trim $colstring] return $collist } # Ignore comments at the beginning of a column definition proc coldef2colname coldef { foreach line [split $coldef \n] { if {[string range $line 0 1] ne "--"} { set colname [lindex $line 0] break } } return $colname } # Convert attached name of file to frame name proc filename2widgetname filename { return .$filename } global tableinfo sqlite3 db main.sq3 set filename [tk_getOpenFile] if {$filename eq ""} return set attachedname _[file rootname [file tail $filename]] attachfile $filename $attachedname set t [filename2widgetname $attachedname] maketable $attachedname bind . <Configure> { frameconfig %W }
Superlinux - 2014-06-19 16:01:16You may test the first published Androwish app on Google Play store named CashierTclTk It has some logical bugs which I might not fix in the near future. I made a Java/Android app instead named it "LebanesePos(Free)". You may find and download the code of CashierTclTk here