#!/usr/local/bin/wish8.0 ############################################################################# # Rewritten as a Visual Tcl Project # ################################ # Configuration Section #global PrevueLocale; set PrevueLocale {61380}# PrevueLocale is the database reference determined by a normal browser # lookup at www.prevue.com (or other site using the same schedule info # database identifiers as public identifiers) See menued locations belowglobal PrevueWhen; set PrevueWhen 0# PrevueWhen is the offset of when we want a schedule for. Prevue.com, # unlike some others, such as www.tvquest.com doesn't seem to keep even # a full day's schedule actively on-line at a time, and uses secondary # server transfers periodically. Zero (the default) gets the CURRENT # schedule, until moments before an hour. 2 gets current + 2 hours, etc.global PrevueServer; set PrevueServer www.prevue.com# PrevueServer is our default serverarray set locations { 62149 {Casper TCI} 61380 {Cheyenne TCI} 61615 {C-Band Mtn} 60770 {Colorado TCI} 63893 {Direct TV Mtn} 63099 {Hartford SNET} 60836 {Hartford TCI} 60835 {Philly ComCst} 60938 {Philly GrMed} 62277 {Salina Cable} 60827 {San Jose TCI} 62196 {Tucson TCI} 60861 {Worcester GrMed} 63887 {USSB - Mtn} }# The keys in the above array are extracted from the last five digits # of the displayed URL in a selected schedule. They are a catalog # index for the schedule in question. Those listed are given in # the options menu, from a selection by Zip Code, or from the map. ##### # Items we want flagged as black... We'll match strings.set infomercials [list \ {Aspen Wellness Diet} \ {Beautiful U} \ {Building American Dream} \ {Carleton Sheets} \ {Classic Country Collection} \ {Consumer Product Showcase} \ {Feed the Children} \ {Free Computer Learing} \ {Free Money} \ {George Forman Grill} \ {Golden Days of R & R} \ {Infomercial} \ {Larry North} \ {Making Money} \ {Psychic Hot} \ {Secrets to Cash Flow Now} \ {Shop at Home} \ {Success 'N Life} \ {T-Fal Cookware} \ {Thirty Days to Financial Freedom} \ ]##### # Favorites ... We'll match strings for extra highlighting...set favorites [list \ ]################################# # GLOBAL VARIABLES #global appname;set appname {Prevue} global apprevs; array set apprevs { 2.00 {{Mon Jan 18 05:18:26 1999 GMT} Complete rewrite: vTcl based, multi-window, added bottom headings and scrollbars, status moved to bottom} 1.11 {{Mon Jan 18 04:54:08 1999 GMT} Examine failed ad servers} 1.10 {{} add educational and favorites matches} 1.09 {{} identify named infomercials for black backgroun and known ancient B&W shows for graying of title} 1.08 {{} make Ad redirects a little hardier - process Location: HTTP} 1.07 {{} Round to even hour - CGI seems to have changed.} 1.06 {{} Change the slice fetched 5 minutes early.} 1.05 {{} Add an X behind unfetchable/unrenderable ads} 1.04 {{Mon Aug 31 15:34:51 1998 GMT} documentation update.} 1.03 {{} added MANUAL selection of [www|pol1|pol2].prevue.com} 1.02 {{} added parsing for "reloading pages" - needs redirect, though.} 1.01 {{} minor syntax error corrections} 1.00 {{} first version with cache management and MIME TYPE cache.} 0.98 {{} No details} 0.95 {{} added advertisment fetches.} 0.94 {{} No details} 0.93 {{} No details} 0.92 {{} No details} 0.91 {{} No details} 0.90 {{} added recoloring for Off Air, etc.} 0.00 {{} No details preserved on early versions} } global appvers; set appvers [lindex [lsort -real [array names apprevs]] end] global appdate; set appdate [lindex [lindex apprevs($appvers) 1] 0] global appcpyr; set appcpyr "Copyright \xA9 1998,1999 Bruce Gingery" global appplug; set appplug [info exists embed_args] global DISTNAME; set DISTNAME [join [list Mozilla/5.0a2 \ \(compatible interactive Tcl/Tk v[info patchlevel] browser v$appvers\) \ ] { }] global chanfont;set chanfont {Helvetica -10} global timefont;set timefont {Helvetica -12} global dispfont;set dispfont {Helvetica -10 bold} global btnfont; set btnfont {Helvetica -12} global menufont;set menufont {Helvetica -12} global statfont;set statfont {Helvetica -12 bold} global x y t rootwin refresh refbtn status global hours; set hours 2 global lasterror; set lasterror {} global logoimage cachedir tcl_platform env global nextwin; set nextwin 0 global status; set status(.) {};# reserve as array global server; global slocale; global soffset; global curwin; global queue; set queue {} global widget;################################# # USER DEFINED PROCEDURES #
proc {init} {argc argv} { global cachedir env tcl_platform if [info exists env(PRCACHE)] { if {![expr [file exists env(PRCACHE)] && \ [file isdirectory $env(PRCACHE)]]} { catch {file mkdir $env(PRCACHE)} } set cachedir $env(PRCACHE) } if {[expr ![info exists cachedir] && \ [info exists env(TEMP)]] } { if { ![expr [file exists $env(TEMP)] && \ [file isdirectory $env(TEMP)]]} { catch {file mkdir $env(TEMP)} } set cachedir $env(TEMP) } if {[expr ![info exists cachedir] && \ [info exists env(TMP)]]} { if {![expr [file exists $env(TMP)] && \ [file isdirectory $env(TMP)]]} { catch {file mkdir $env(TMP)} } set cachedir $env(TMP) } if {![info exists cachedir]} { if [string match windows $tcl_platform(platform)] { set cachedir C:\windows\temp# It'll be somewhere if we're really running windows and no TEMP or TMP} elseif [string match unix $tcl_platform(platform)] { set cachedir /tmp/pvcache if { ![file isdirectory $cachedir] } { file mkdir $cachedir } } else { if [info exists env(HOME)] { set cachedir [file join $env(HOME) pvcache] if {![expr [file exists $cachedir] && [file isdirectory $cachedir]]} { file mkdir $cachedir } # } else { # set cachedir [pwd[ } } } if {![expr [file exists $cachedir] && [file isdirectory $cachedir]]} { unset cachedir } if {[info exists cachedir] && [file isdirectory $cachedir]} { set bm [open [file join $cachedir iconbitmap.xbm] w] if [info exists bm] { puts $bm { #define icon_width 63 #define icon_height 66 static unsigned char icon_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xfc,0xff,0xff,0x03,0x00,0x00,0x00,0xf0,0xff, 0xff,0xff,0x7f,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x07, 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xfe,0xff,0xff, 0xff,0xff,0xff,0x7f,0xc0,0xf7,0xff,0xff,0xff,0xff,0xff,0x7f, 0xf8,0xfe,0xff,0xff,0xff,0xff,0xff,0x7f,0xce,0xff,0xff,0xff, 0xff,0xff,0xff,0x7f,0xfb,0xff,0xff,0x03,0x00,0xf0,0xff,0x7f, 0xfe,0xff,0x07,0x00,0x00,0x00,0xf0,0x7f,0xff,0x7f,0x00,0xf0, 0xff,0x03,0x00,0x7f,0xff,0x07,0x00,0xfe,0xff,0x0f,0x00,0x78, 0x7f,0x00,0x80,0xe1,0xff,0x7f,0x00,0x40,0x0f,0x00,0x20,0xf8, 0xff,0xff,0x00,0x00,0x01,0x00,0x10,0xff,0xff,0xff,0x01,0x00, 0x00,0x00,0x84,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xe2,0xff, 0xff,0xff,0x07,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0x0f,0x00, 0x00,0x00,0xfc,0xff,0xff,0xff,0x1f,0x00,0x00,0x40,0xfe,0xff, 0xff,0xff,0x1f,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x3f,0x00, 0x00,0x90,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0xc8,0x01,0xc0, 0xff,0xff,0x7f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0x00, 0x00,0x20,0x00,0x00,0xc0,0xff,0xff,0x00,0x00,0x32,0x00,0x00, 0xc0,0xff,0xff,0x00,0x00,0x30,0x00,0x00,0xc0,0xff,0xff,0x00, 0x00,0x39,0x00,0x00,0xc0,0x3f,0xe0,0x00,0x00,0x2f,0x00,0x00, 0xc0,0xdf,0xff,0x01,0x80,0xef,0x3f,0xf0,0xff,0x6f,0xc0,0x01, 0x80,0xff,0x3f,0x10,0xff,0x2f,0xe0,0x01,0xc0,0xff,0x37,0x10, 0xff,0x17,0xe0,0x01,0xc0,0xff,0x17,0x10,0xff,0x1b,0xf0,0x01, 0xc0,0xff,0x17,0x18,0xfe,0x0d,0xf8,0x01,0xc0,0xff,0x17,0x08, 0xfe,0x06,0xfc,0x01,0xc0,0xff,0x1b,0x08,0x7e,0x03,0xfc,0x01, 0xc0,0xff,0x1b,0x08,0x7c,0x01,0xfe,0x00,0xe0,0xff,0x1b,0x08, 0xbc,0x01,0xff,0x00,0xe0,0xff,0x1b,0x08,0xdc,0x00,0xff,0x00, 0xe0,0xff,0x1b,0x08,0x7c,0x80,0xff,0x00,0xe0,0xff,0x0b,0x18, 0x38,0xc0,0xff,0x00,0xe0,0xff,0x0b,0x1c,0x18,0xe0,0x7f,0x00, 0xe0,0xff,0x0b,0x1c,0x18,0xe0,0x7f,0x00,0xe0,0xff,0x0d,0x1c, 0x00,0xf0,0x3f,0x00,0xe0,0xff,0x0d,0x3c,0x00,0xf8,0x3f,0x00, 0xe0,0xff,0x0d,0x3c,0x00,0xfc,0x1f,0x00,0xe0,0xff,0x0d,0x3c, 0x00,0xfc,0x1f,0x00,0xc0,0xff,0x0d,0x3c,0x00,0xfe,0x0f,0x00, 0xc0,0xff,0x05,0x3e,0x00,0xff,0x0f,0x00,0xc0,0xff,0x05,0x7e, 0x00,0xff,0x07,0x00,0x80,0xff,0x05,0x7e,0x80,0xff,0x07,0x40, 0x80,0xff,0x06,0x7e,0xc0,0xff,0x01,0x10,0x00,0xff,0x06,0x7e, 0xe0,0xff,0x01,0x6c,0x00,0xff,0x06,0x7e,0xe0,0xff,0x00,0x73, 0x00,0xfe,0x06,0x7e,0xf0,0x7f,0xe0,0x3e,0x00,0xfe,0x07,0xfe, 0xff,0x3f,0xf8,0x0f,0x00,0xfc,0xff,0xff,0xff,0x1f,0xff,0x03, 0x00,0xf8,0xff,0xff,0xff,0xef,0xff,0x00,0x00,0xf0,0xff,0xff, 0xff,0xff,0x1f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x03,0x00, 0x00,0x80,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xfe,0xff, 0xff,0x03,0x00,0x00,0x00,0x00,0xf0,0xff,0x2f,0x00,0x00,0x00}; } close $bm unset bm } set bm [open [file join $cachedir iconbitmask.xbm] w] if [info exists bm] { puts $bm { #define mask_width 63 #define mask_height 66 static unsigned char mask_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xfc,0xff,0xff,0x03,0x00,0x00,0x00,0xf0,0xff, 0xff,0xff,0x7f,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x07, 0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0xfe,0xff,0xff, 0xff,0xff,0xff,0x7f,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0xf8,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfe,0xff,0xff,0xff, 0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0x03,0x00,0xf0,0xff,0x7f, 0xff,0xff,0x07,0x00,0x00,0x00,0xf0,0x7f,0xff,0x7f,0x00,0xf0, 0xff,0x03,0x00,0x7f,0xff,0x07,0x00,0xfe,0xff,0x0f,0x00,0x78, 0x7f,0x00,0x80,0xff,0xff,0x7f,0x00,0x40,0x0f,0x00,0xe0,0xff, 0xff,0xff,0x00,0x00,0x01,0x00,0xf8,0xff,0xff,0xff,0x01,0x00, 0x00,0x00,0xfc,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xff,0xff, 0xff,0xff,0x07,0x00,0x00,0x80,0xff,0xff,0xff,0xff,0x0f,0x00, 0x00,0xc0,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0xe0,0xff,0xff, 0xff,0xff,0x1f,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0x3f,0x00, 0x00,0xf0,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0xfc,0xff,0xff, 0xff,0xff,0x7f,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x00, 0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xfe,0xff,0xff, 0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00, 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff, 0xff,0xff,0xff,0x01,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x01, 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xc0,0xff,0xff,0xff, 0xff,0xff,0xff,0x01,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x01, 0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xc0,0xff,0xff,0xff, 0xff,0xff,0xff,0x01,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x01, 0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xe0,0xff,0xff,0xff, 0xff,0xff,0xff,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x00, 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xe0,0xff,0xff,0xff, 0xff,0xff,0xff,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x7f,0x00, 0xe0,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0xe0,0xff,0xff,0xff, 0xff,0xff,0x3f,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0x3f,0x00, 0xe0,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0xe0,0xff,0xff,0xff, 0xff,0xff,0x1f,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0x0f,0x00, 0xc0,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0xc0,0xff,0xff,0xff, 0xff,0xff,0x07,0x00,0x80,0xff,0xff,0xff,0xff,0xff,0x07,0x40, 0x80,0xff,0xff,0xff,0xff,0xff,0x01,0x70,0x00,0xff,0xff,0xff, 0xff,0xff,0x01,0x7c,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x7f, 0x00,0xfe,0xff,0xff,0xff,0x7f,0xe0,0x3f,0x00,0xfe,0xff,0xff, 0xff,0x3f,0xf8,0x0f,0x00,0xfc,0xff,0xff,0xff,0x1f,0xff,0x03, 0x00,0xf8,0xff,0xff,0xff,0xef,0xff,0x00,0x00,0xf0,0xff,0xff, 0xff,0xff,0x1f,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0x03,0x00, 0x00,0x80,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xfe,0xff, 0xff,0x03,0x00,0x00,0x00,0x00,0xf0,0xff,0x3f,0x00,0x00,0x00}; } close $bm unset bm } } } # init is run DURING script load, we need a cache, and why not, while # we're accessing the disk directly, anyways. But, to simplify getting # it going, we will wait to load the http package until after we have # our About window showing. init $argc $argv# to do an array sort of $locations() by value proc {valuesort} {left right} { global locations return [string compare $locations($left) $locations($right)] }# invoke next window fetch-and-update proc {doQueue} {} { global queue curwin if {[llength $queue] == 0} return set base [lindex $queue 0] if {[llength $queue] == 1} { set queue {} } else { set queue [lrange $queue 1 end] } if {[string length $base] == 0} { doQueue } else { after 5 dspSchedule $base } }# enqueue window fetch-and-update proc {enqueue} {base where when} { global queue curwin slocale soffset if {[info exists curwin] && [string compare $curwin $base] == 0} {return} set slocale($base) $where set soffset($base) $when lappend queue $base if {![info exists curwin]} { after 5 doQueue return } if {[string length $curwin] == 0} { after 5 doQueue } }# post fetch status in statusbar proc {showProgress} {token total current} { global curwin upvar #0 status($curwin) statline upvar #0 $token httpState set statline \ [format "Fetching ... %d bytes of %d, %s" $current $total $httpState(state)] update idletasks }# Manage our local browser cache proc {cacheManage} {index} { upvar #0 cachedir cdir set expire [expr [clock seconds] - 10800] set ixout [open [file join $cdir index.new] w] if {![info exists ixout]} {return $index} seek $index 0 start while { ![eof $index]} { if [gets $index line] { set ix [string first | $line] incr ix -1 set cachename [string range $line 0 $ix] if {[catch {file mtime [file join $cdir $cachename]} mtime]} { puts $ixout $line } else { if {$mtime < $expire} { file delete [file join $cdir $cachename] } else { puts $ixout $line } } } } close $index file delete -- [file join $cdir index] file rename [file join $cdir index.new] [file join $cdir index] return $ixout }proc {getToCache} {url mimetype} { upvar #0 cachedir cdir global DISTNAME status curwin lasterror if {![info exists cdir]} { return {} } # Let's see if we already have it set cacheindex [open [file join $cdir index] a+] if {![info exists cacheindex]} { return {} } seek $cacheindex 0 start while {![eof $cacheindex]} { if [gets $cacheindex line] { set ix [string first | $line] set cachename [string range $line 0 [expr $ix - 1]] set cacheurl [string range $line [expr $ix + 1] end] if {[string compare $cacheurl $url] == 0} { close $cacheindex return $cachename } } } set cacheindex [cacheManage $cacheindex] set cachename [clock seconds] set cachefile [open [file join $cdir $cachename] w] if {![info exists cachefile]} { close $cacheindex return {} } fconfigure $cachefile -translation binary # Nope, let's fetch it. ::http::config -accept $mimetype -useragent "$DISTNAME" set statline $status($curwin) set token [::http::geturl $url -progress showProgress -timeout 10000 \ -channel $cachefile] upvar #0 $token httpState set frozen 0 while { [string match eof $httpState(state)] != 1 } { incr frozen set status($curwin) "Fetch appears to be stalled..." update idletasks # puts stderr "$httpState(state) [string match eof $httpState(state)]" flush stderr after 100 if {$frozen > 30} { # time the sucker out - we cannot get the file we want, and # usually it's an ad. return {} } } set status($curwin) "Closing cache and connection..." update idletasks if [info exists httpState(meta)] { array set meta $httpState(meta) if [info exists meta(Content-Type)] { if { [regexp -nocase -- {image/(.*)} $meta(Content-Type) {} imgtype] } { file rename [file join $cdir $cachename] \ [join [list [file join $cdir $cachename] $imgtype] .] set cachename [join [list $cachename $imgtype] .] } else { file rename [file join $cdir $cachename] \ [join [list [file join $cdir $cachename] html] .] set cachename [join [list $cachename html] .] } } else { file rename [file join $cdir $cachename] \ [join [list [file join $cdir $cachename] html] .] set cachename [join [list $cachename html] .] } } else { file rename [file join $cdir $cachename] \ [join [list [file join $cdir $cachename] html] .] set cachename [join [list $cachename html] .] } update idletasks ::http::Finish $token if [info exists meta(Location)] { set meta(Location) [string trim $meta(Location)] puts -nonewline $cachefile {<A HREF="} puts -nonewline $cachefile $meta(Location) puts $cachefile {">Graphic Location</A>} close $cachefile set status($curwin) $statline puts $cacheindex [join [list $cachename $url] {!}] flush $cacheindex close $cacheindex update idletasks if [catch {getToCache $meta(Location) image/*} followed] { return $cachename } else { return $followed } } # puts [join [list Cached as $cachename, $url] { }] # flush stdout close $cachefile set status($curwin) $statline puts $cacheindex [join [list $cachename $url] {|}] close $cacheindex update idletasks return $cachename }# We can snarf HTML files pretty easliy proc {getHtml} {url} { global DISTNAME status curwin lasterror ::http::config -accept text/html -useragent $DISTNAME set statsave $status($curwin) set token [::http::geturl $url -progress showProgress -timeout 10000] upvar #0 $token httpState while { [string match eof $httpState(state)] != 1 } { puts stderr "$httpState(state) [string match eof $httpState(state)]" flush stderr after 100 } set status($curwin) "Closing connection..." update ::http::Finish $token set status($curwin) $statsave update if { [info exists httpState(error)] } { set lasterror $httpState(http) return "error $httpState(http)" } set lasterror {} return $httpState(body) }# Build a URL and get the content of it proc {getSchedule} {stamp} { global DISTNAME status server curwin slocale soffset hours lasterror ::http::config -accept text/html -useragent "$DISTNAME" set URL [join [list {http://} $server($curwin) {/scripts/pol.dll?} \ {BuildGuidePage&I=} $slocale($curwin) {&ST=} $stamp \ {&GB=} [expr $hours * 2]] {}] # set URL http://localhost/~bruce/prevue.html set token [http::geturl $URL -progress showProgress -timeout 60000] upvar #0 $token httpState while { [string match eof $httpState(state)] != 1 } { puts stderr "$httpState(state) [string match eof $httpState(state)]" flush stderr after 100 } set status($curwin) "Closing connection..." update ::http::Finish $token if { [info exists httpState(error)] } { set lasterror $httpState(http) return "error $httpState(http)" } set lasterror {} return $httpState(body) }# draw on canvas proc {makeBlock} {canv x y w {h 20} fill {ridge sunken}} { $canv create rectangle \ $x $y \ [expr $x + $w] [expr $y + $h] \ -fill $fill -outline #333333 -width 1 if { [string match sunken $ridge] } { $canv create line \ [expr $x + 1] [expr $y + 1 + $h] \ [expr $x + 1 + $w] [expr $y + 1 + $h] \ [expr $x + 1 + $w] [expr $y + 1] \ -arrow none -capstyle round -joinstyle round \ -fill #CCCCCC -width 1 } elseif { [string match raised $ridge] } { $canv create line \ [expr $x + $w - 1] [expr $y - 1] \ [expr $x - 1] [expr $y - 1] \ [expr $x - 1] [expr $y + $h - 1] \ -arrow none -capstyle round -joinstyle round \ -fill #CCCCCC -width 1 } }# draw on canvas >proc {makeContent} {canv x y fg w content} { global dispfont $canv create text \ $x $y -anchor center -fill $fg -justify left -font $dispfont \ -text $content -width $w }# draw on canvas proc {makeChannel} {canv x y fg w content} { global chanfont $canv create text \ $x $y -anchor center -fill $fg -justify center -font $chanfont \ -text $content -width $w }# draw on canvas proc {makeHeading} {canv x y w h bg fg hd} { global timefont makeBlock $canv $x $y $w $h $bg raised $canv create text \ [expr $x + ( $w / 2 ) ] [expr $y + ( $h / 2 ) ] \ -anchor center -fill $fg -font $timefont -justify center \ -text $hd -width $w }# Tie two canvas widgets for simultaneous horizontal movement proc {tied_xview} {base args} { eval "$base.c.t xview $args" eval "$base.c.c xview $args" }# format a unix timestamp proc {headtime} {t} { return [string trimleft [clock format $t -format {%I:%M}] 0] }# post status at end of fetch of schedule proc {statusDone} {t} { global curwin slocale locations upvar #0 status($curwin) statline set statline [format {%s As of %s} $locations($slocale($curwin)) \ [clock format $t -format {%R %a, %d %b %Y}]] }# fetch - parse - display the schedule proc {dspSchedule} {base} { global x y hours refbtn status PrevueWhen slocale autoupdate dispfont global lasterror curwin queue soffset upvar #0 cachedir cdir logoimage logoimg infomercials infomercial upvar #0 favorites favorite set curwin $base set canv $base.c.c set head $base.c.t # Logo is 118x60 on #000066, http://www.prevue.com/gifs/logo/Pvchannel.JPG # But http://www.prevue.com/gifs/24temp/POL_logo_violet.gif looks better. # even though it is a 140x70 pixel image We can let it overlap titles. # Click Ad is actually 468x60 and loaded from a dynamic image link on # http://www.prevue.com/scripts/LongAd.asp?I=_____&S=-1&N=-1&Q=NONE # where _____ is the table value above. $base.mb.fetch configure -state disabled update set basetime \ [expr ( ( [clock seconds] + 300 + $soffset($base) ) / 3600 ) * 3600] set page [getSchedule $basetime] if { [string match error* $page] } { set status($base) {Error - see below} makeHeading $canv 40 40 560 360 #000000 #F86666 $base.mb.fetch configure -state normal set curwin {} return } if {[string length $page] == 0} { set status($base) {No page returned} $base.mb.fetch configure -state normal set curwin {} return } regexp -nocase {HTTP-EQUIV=\"Refresh\" CONTENT=\"(\d+)\"} \ $page discard refresh set status($base) {Parsing ...} update set x 0 if [info exists cdir] { set y 60 } else { set y 0 } # strip <HEAD> and everything else through <TABLE> from the page $canv delete all $head delete all makeBlock $canv 0 0 162 72 #CC0000 flat makeHeading $canv 0 $y 79 20 #000099 #F8F800 Channel makeHeading $head 0 0 79 20 #000099 #F8F800 Channel makeHeading $canv 83 $y 196 20 #000099 #F8F800 [headtime $basetime] makeHeading $head 83 0 196 20 #000099 #F8F800 [headtime $basetime] makeHeading $canv 283 $y 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 1800]] makeHeading $head 283 0 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 1800]] set pwidth 500 if {$hours > 1} { makeHeading $canv 483 $y 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 3600]] makeHeading $head 483 0 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 3600]] makeHeading $canv 683 $y 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 5400]] makeHeading $head 683 0 195 20 #000099 #F8F800 \ [headtime [expr $basetime + 5400]] set pwidth 900 if {$hours > 2} { makeHeading $canv 883 $y 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 7200]] makeHeading $head 883 0 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 7200]] makeHeading $canv 1083 $y 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 9000]] makeHeading $head 1083 0 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 9000]] set pwidth 1100 if {$hours > 3} { makeHeading $canv 1283 $y 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 10800]] makeHeading $head 1283 0 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 10800]] makeHeading $canv 1483 $y 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 12600]] makeHeading $head 1483 0 196 20 #000099 #F8F800 \ [headtime [expr $basetime + 12600]] set pwidth 1300 } } } update incr y 25 set bf [string first {are currently loading data} $page] if { $bf > -1 } { set page [string range $page $bf end] set bf [string first \n $page] if { $bf > -1 } { set page [string range $page 0 $bf] makeHeading $canv 90 120 300 200 #990000 #F8F800 $page } } # loop through rows while { [set bf [string first <TR> $page]] > -1 } { set be [string first </TR> $page] set block [string range $page $bf $be] incr be 4 set page [string range $page $be end] regexp -nocase {.*<TH[^B]+BGCOLOR=\"(#[0-9A-Fa-f]+)} $block {} bgcolor regexp -nocase {.*<TH WIDTH=\"([0-9]+)\%\"} $block {} w set w [expr int ( $pwidth / 100 * $w ) ] makeBlock $canv 0 $y 79 18 $bgcolor raised set ix [string first <FONT $block] set block [string range $block $ix end] regexp -nocase \ {<FONT COLOR=\"(#[0-9A-Fa-f]+)\">([^<]+)</FONT>} $block {} fgcolor text regsub -nocase \ {COLOR=.*>.*</TH>} $block {} block makeChannel $canv 39 [expr $y + 11] $fgcolor 78 $text set shopchan [expr [regexp HSN $text] || [regexp QVC $text] || \ [regexp HSN $text]] set bs [string first <TD $block] set x 83 # loop through cells in row while {$bs > -1} { set be [string first </TD> $block] incr be 4 set cell [string range $block $bs $be] incr be set block [string range $block $be end] regexp -nocase {<TD WIDTH=\"([0-9]+)\%\"} $cell {} w set w [expr $pwidth / 100 * $w] set w [expr ( int ( $w / 200 ) - 1 ) * 200 + 196] regexp -nocase {<TD.*BGCOLOR=\"(#[0-9A-Fa-f]+)\"} $cell {} bgcolor regsub -nocase {.*<FONT} $cell {<FONT} $cell regexp -nocase {<FONT COLOR=\"(#[0-9A-Fa-f]+)\">([^<]+)</FONT>} $cell \ {} fgcolor text # Just to demonstrate that we _can_, we'll alter just a few blocks. # We'll force ``Paid Program'' to near-black background if {$shopchan} { set bgcolor #000033 } if { [regexp -nocase {.*Paid\ Program.*} $text {}] } { set bgcolor #000033 set fgcolor #CCCCCC } if [info exists infomercial] { foreach pat $infomercial { if {[string first "$pat" "$text"] > -1} { set bgcolor #000033 set fgcolor #CCCCCC } } } # and Off-Air (or Off Air) to black background with gray foreground if { [regexp -nocase {.*Off.Air.*} $text {}] } { set bgcolor #000000 set fgcolor #CCCCCC } # and change News broadcasts to a very dark cyan. It'll still look # very much like its original deep blue color. if { [regexp -nocase {.*News.*} $text {}] } { set bgcolor #003366 } # and finally, in thanks to the provider, we'll give them a royal purple # background with gold lettering. if { [regexp -nocase {Prevue First!} $text {}] } { set fgcolor #F8F866 set bgcolor #330066 } # But, it's the user's program, not Prevue's, so we make # favorites take precedence over ALL other colorations... if [info exists favorite] { foreach pat $favorite { if {[regexp -- $pat "$text" {}]} { set fgcolor #660099 set bgcolor #F8F866 } } } makeBlock $canv $x $y $w 18 $bgcolor makeContent $canv [expr $x + ( $w / 2 ) ] [expr $y + 9] $fgcolor \ [expr $w - 4] $text incr x [expr $w + 4] set bs [string first <TD $block] } update idletasks incr y 21 } $canv configure -scrollregion [list 0 0 [expr $pwidth + 4] [expr $y + 10]] $head configure -scrollregion [list 0 0 [expr $pwidth + 4] 0] $base.mb.fetch configure -state normal -text {Update Schedule} statusDone $basetime update if { ![info exists logoimg] } { catch {set logo [getToCache \ http://www.prevue.com/gifs/24temp/POL_logo_violet.gif image/gif] } if {[info exists logo] && [string length $logo] > 0 } { set logoimg [image create photo -file [file join $cdir $logo]] } } if [info exists logoimg] { $canv create image 10 1 -anchor nw -image $logoimg update idletasks } set page [getHtml [join \ [list {http://www.prevue.com/scripts/LongAd.asp?I=} \ $slocale($base) {&S=-1&N=-1&Q=NONE}] {}]] if { [string first error $page] == 0 } { set curwin {} return } set ix [string first {<img src="} $page] if { $ix > -1 } { incr ix 10 set page [string range $page $ix end] set ix [string first \" $page] if { $ix > -1 } { incr ix -1 set page [string range $page 0 $ix] set ad [getToCache "$page" image/*] if { [string length $ad] > 0 } { if { ![catch {image create photo -file [file join $cdir $ad]} adi] } { set i [$canv create image 170 0 -anchor nw -image $adi] $canv lower $i all } else { set ad [file join $cdir $ad] set msg [join [list Unable to display advertisement, \ unsupported image format or error return. It is \ cached as $ad \n $lasterror] { }] $canv create line \ 170 0 660 58 660 0 170 58 170 0 \ -arrow none -capstyle round -joinstyle round \ -fill #666699 -width 1 $canv create text \ 400 20 -anchor center -fill #99F899 -justify left \ -font $dispfont -text $msg -width 468 } } } } if {[llength $queue] > 0} doQueue set curwin {} }# at startup, we display the about window for at least 30 seconds # 10 ms after dropping it, we auto-fetch the first schedule proc {main} {argc argv} {uplevel #0 package require http 2.0after 3000 Window hide .about after 3010 dspSchedule .prevue }################################# # VTCL GENERATED GUI PROCEDURES # >proc {Window} {args} { global vTcl set cmd [lindex $args 0] set name [lindex $args 1] set newname [lindex $args 2] set rest [lrange $args 3 end] if {$name == "" || $cmd == ""} {return} if {$newname == ""} { set newname $name } set exists [winfo exists $newname] switch $cmd { show { # Correction from vTcl 1.11: if {$exists == "1" && $newname != "."} {wm deiconify $newname; return} if {[info procs vTclWindow(pre)$name] != ""} { eval "vTclWindow(pre)$name $newname $rest" } if {[info procs vTclWindow$name] != ""} { eval "vTclWindow$name $newname $rest" } if {[info procs vTclWindow(post)$name] != ""} { eval "vTclWindow(post)$name $newname $rest" } } hide { if $exists {wm withdraw $newname; return} } iconify { if $exists {wm iconify $newname; return} } destroy { if $exists { destroy $newname; # Modification from vtcl 1.11: auto-die on last window close if {[llength [winfo children .]] == 0} {destroy .} return } } } }proc {vTclWindow.} {base} { if {$base == ""} { set base . } ################### # CREATING WIDGETS ################### wm focusmodel $base passive wm geometry $base 1x1+0+0 wm maxsize $base 1265 994 wm minsize $base 1 1 wm overrideredirect $base 0 wm resizable $base 1 1 wm withdraw $base wm title $base "vt.tcl #2" ################### # SETTING GEOMETRY ################### }proc {vTclWindow.prevue} {base args} { global nextwin chanfont timefont dispfont btnfont menufont statfont status global locations which PrevueServer server PrevueWhen PrevueLocale cachedir global soffset slocale set basename .prevue if {$base == ""} { set base $basename } if {[winfo exists $base]} { wm deiconify $base; return } ################### # CREATING WIDGETS ################### toplevel $base -class Toplevel wm focusmodel $base passive wm geometry $base 640x480+52+52 wm maxsize $base 1265 994 wm minsize $base 1 1 wm overrideredirect $base 0 wm resizable $base 1 1 wm title $base "Prevue.com Schedule" wm iconname $base "TV-Schedule" wm protocol $base WM_DELETE_WINDOW "Window destroy $base" if {[info exists cachedir] && \ [file exists [file join $cachedir iconbitmap.xbm]]} { wm iconbitmap $base "@[file join $cachedir iconbitmap.xbm]" } if {[info exists cachedir] && \ [file exists [file join $cachedir iconbitmask.xbm]]} { wm iconmask $base "@[file join $cachedir iconbitmask.xbm]" } frame $base.mb \ -background #666666 \ -borderwidth 2 \ -highlightcolor #999999 \ -highlightbackground #333333 \ -relief raised button $base.mb.quit \ -activebackground #F8F800 \ -borderwidth 2 \ -background #666666 \ -command "Window destroy ." \ -cursor pirate \ -font "$btnfont" \ -foreground #CCCC00 \ -highlightbackground #333333 \ -highlightcolor #999999 \ -padx 9 -pady 3 \ -relief groove \ -text Quit \ -underline 0 bind $base"$base.mb.quit invoke" menubutton $base.mb.opts \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 2 \ -font "$btnfont" \ -foreground #CCCC00 \ -highlightbackground #333333 \ -highlightcolor #999999 \ -menu $base.mb.opts.m \ -padx 9 -pady 3 \ -relief groove \ -text Options \ -underline 0 menu $base.mb.opts.m \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 2 \ -font "$menufont" \ -foreground #F8F800 \ -selectcolor SpringGreen \ -tearoff 0 set server($base) $PrevueServer $base.mb.opts.m add radiobutton \ -indicatoron 1 \ -label {Server: WWW} \ -selectcolor #F8F800 \ -value www.prevue.com \ -variable server($base) $base.mb.opts.m add radiobutton \ -indicatoron 1 \ -label {Server: POL1} \ -selectcolor #F8F800 \ -value pol1.prevue.com \ -variable server($base) $base.mb.opts.m add radiobutton \ -indicatoron 1 \ -label {Server: POL2} \ -selectcolor #F8F800 \ -value pol2.prevue.com \ -variable server($base) set which($base) $PrevueLocale set slocale($base) $PrevueLocale set soffset($base) $PrevueWhen foreach g [lsort -ascii -command valuesort [array names locations]] { $base.mb.opts.m add separator $base.mb.opts.m add radiobutton \ -command "global slocale soffset; set slocale($base) $g; set soffset($base) 0" \ -indicatoron 1 \ -selectcolor SpringGreen \ -label $locations($g) \ -value [expr $g + 0] \ -variable which($base) $base.mb.opts.m add radiobutton \ -command "global slocale soffset; set slocale($base) $g; set soffset($base) 7200" \ -indicatoron 1 \ -selectcolor SpringGreen \ -label "$locations($g) + 2hr" \ -value [expr $g + 7200] \ -variable which($base) if {$g == $PrevueLocale} { $base.mb.opts.m add radiobutton \ -command "global slocale soffset; set slocale($base) $g; set soffset($base) 14400" \ -indicatoron 1 \ -selectcolor SpringGreen \ -label "$locations($g) + 4hr" \ -value [expr $g + 14400] \ -variable which($base) } } menubutton $base.mb.windows \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 2 \ -font "$btnfont" \ -foreground #CCCC00 \ -highlightbackground #333333 \ -highlightcolor #999999 \ -menu $base.mb.windows.m \ -padx 9 -pady 3 \ -relief groove \ -text Windows \ -underline 0 menu $base.mb.windows.m \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 2 \ -font "$menufont" \ -foreground #F8F800 \ -selectcolor SpringGreen \ -tearoff 0 $base.mb.windows.m add command \ -command "Window show .about" \ -label About... $base.mb.windows.m add command \ -command "global nextwin set w \$nextwin incr nextwin Window show $basename ${basename}_\$w" \ -label Add... $base.mb.windows.m add command \ -command "Window destroy $base" \ -label Close \ -underline 0 $base.mb.windows.m add separator button $base.mb.fetch \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 2 \ -command "global slocale soffset; enqueue $base \$slocale($base) \$soffset($base)" \ -font "$btnfont" \ -foreground #CCCC00 \ -highlightbackground #333333 \ -highlightcolor #999999 \ -padx 9 -pady 3 \ -relief groove \ -text {Fetch Schedule} \ -underline 0 bind $base "$base.mb.fetch invoke" bind $base "$base.mb.fetch invoke" frame $base.c \ -background #000061 \ -borderwidth 1 \ -relief sunken scrollbar $base.c.hs \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 1 \ -command "tied_xview $base" \ -highlightbackground #333333 \ -highlightcolor #999999 \ -orient horizontal \ -troughcolor #000031 \ -width 10 scrollbar $base.c.vs \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 1 \ -command "$base.c.c yview" \ -highlightbackground #333333 \ -highlightcolor #999999 \ -orient vertical \ -troughcolor #000031 \ -width 10 canvas $base.c.c \ -background #333333 \ -borderwidth 0 \ -confine 1 \ -closeenough 3.0 \ -cursor box_spiral \ -highlightthickness 1 \ -relief flat \ -scrollregion [list 0 0 900 700] \ -xscrollincrement 21 \ -xscrollcommand "$base.c.hs set" \ -yscrollincrement 21 \ -yscrollcommand "$base.c.vs set" canvas $base.c.t \ -background #333333 \ -borderwidth 0 \ -confine 1 \ -closeenough 3.0 \ -cursor {} \ -height 22 \ -highlightthickness 1 \ -relief flat \ -scrollregion [list 0 0 900 0] \ -xscrollincrement 21 \ -xscrollcommand "$base.c.hs set" \ -yscrollincrement 0 bind $base.c.c <1> " $base.c.c configure -cursor fleur $base.c.c scan mark %x %y $base.c.t scan mark %x 0" bind $base.c.c " $base.c.c scan dragto %x %y $base.c.t scan dragto %x 0" bind $base.c.c "%W configure -cursor box_spiral" set status($base) {} label $base.s \ -background #000031 \ -borderwidth 0 \ -font "$statfont" \ -foreground #F8F800 \ -textvariable status($base) \ -relief flat ################### # SETTING GEOMETRY ################### pack $base.mb \ -anchor center -expand 0 -fill x -side top pack $base.mb.quit \ -anchor center -expand 0 -fill y -side left pack $base.mb.opts \ -anchor center -expand 0 -fill y -side left pack $base.mb.windows \ -anchor center -expand 0 -fill y -side left pack $base.mb.fetch \ -anchor center -expand 0 -fill y -side right pack $base.c \ -anchor center -expand 1 -fill both -side top grid columnconf $base.c 0 -weight 1 grid rowconf $base.c 0 -weight 1 grid rowconf $base.c 1 -minsize 24 -weight 0 grid $base.c.hs \ -column 0 -row 2 -columnspan 1 -rowspan 1 -sticky ew grid $base.c.t \ -column 0 -row 1 -columnspan 1 -rowspan 1 -sticky ew grid $base.c.vs \ -column 1 -row 0 -columnspan 1 -rowspan 1 -sticky ns grid $base.c.c \ -column 0 -row 0 -columnspan 1 -rowspan 1 -sticky nesw pack $base.s \ -anchor center -expand 0 -fill x -side top foreach w [winfo children .] { if [winfo exists $w.mb.windows.m] { set z [$w.mb.windows.m index Close] incr z 2 if {[$w.mb.windows.m index end] >= $z} { $w.mb.windows.m delete $z end } foreach t [winfo children .] { if {[winfo exists $t.mb.windows.m] && \ ( [string compare $w $t] != 0 ) } { $w.mb.windows.m add command \ -command "Window show $basename $t raise $t" -label $t } } } } } proc {vTclWindow.about} {base args} { global nextwin chanfont timefont dispfont btnfont menufont cachedir global appname apprevs appvers appdate appcpyr appplug tk_patchLevel set basename .about if {$base == ""} { set base $basename } if {[winfo exists $base]} { wm deiconify $base; return } ################### # CREATING WIDGETS ################### toplevel $base -class Toplevel wm focusmodel $base passive wm geometry $base 400x250+53+53 wm maxsize $base 1265 994 wm minsize $base 1 1 wm overrideredirect $base 0 wm resizable $base 1 1 wm title $base "About prevue.tcl" wm iconname $base "About Prevue" wm protocol $base WM_DELETE_WINDOW "Window destroy $base" t; if {[info exists cachedir] && \ [file exists [file join $cachedir iconbitmap.xbm]]} { wm iconbitmap $base "@[file join $cachedir iconbitmap.xbm]" } if {[info exists cachedir] && \ [file exists [file join $cachedir iconbitmask.xbm]]} { wm iconmask $base "@[file join $cachedir iconbitmask.xbm]" } frame $base.mb \ -background #666666 \ -borderwidth 2 \ -highlightcolor #999999 \ -highlightbackground #333333 \ -relief raised button $base.mb.close \ -activebackground #F8F800 \ -borderwidth 2 \ -background #666666 \ -command "Window destroy $base" \ -font "$btnfont" \ -foreground #CCCC00 \ -highlightbackground #333333 \ -highlightcolor #999999 \ -padx 9 -pady 3 \ -relief groove \ -text Close \ -underline 0 bind $base"$base.mb.close invoke" bind $base "$base.mb.close invoke" button $base.mb.quit \ -activebackground #F8F800 \ -borderwidth 2 \ -background #666666 \ -command "Window destroy ." \ -cursor pirate \ -font "$btnfont" \ -foreground #CCCC00 \ -highlightbackground #333333 \ -highlightcolor #999999 \ -padx 9 -pady 3 \ -relief groove \ -text Quit \ -underline 0 bind $base "$base.mb.quit invoke" frame $base.c \ -background #666666 \ -borderwidth 2 \ -highlightcolor #999999 \ -highlightbackground #333333 \ -relief flat scrollbar $base.c.hs \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 1 \ -command "$base.c.t xview" \ -highlightbackground #333333 \ -highlightcolor #999999 \ -orient horizontal \ -troughcolor #000031 \ -width 10 scrollbar $base.c.vs \ -activebackground #F8F800 \ -background #666666 \ -borderwidth 1 \ -command "$base.c.t yview" \ -highlightbackground #333333 \ -highlightcolor #999999 \ -orient vertical \ -troughcolor #000031 \ -width 10 set t [text $base.c.t \ -background #000031 \ -borderwidth 0 \ -foreground #F8F800 \ -font {Helvetica -12} \ -highlightthickness 1 \ -relief flat \ -xscrollcommand "$base.c.hs set" \ -yscrollcommand "$base.c.vs set" \ -wrap none] $t tag configure h1 -font "Helvetica -24 bold" $t tag configure h2 -font "Helvetica -16 bold&auot; $t tag configure b -font "Helvetica -12 bold" $t tag configure n -font "Helvetica -12" $t tag configure tt -font "Courier -12" $t tag configure c -justify center $t tag configure ww -lmargin1 .5c -lmargin2 .5c -rmargin .5c -wrap word $t insert end \ "\n$appname Version $appvers\n" {h1 c} \ "\n$appcpyr\nAll Rights Reserved\n" {h2 c} \ "\nTcl v[info patchlevel] / Tk v$tk_patchLevel\n" {b c} catch {$t insert end \ "on $tcl_platform(platform) \($tcl_platform(os)\)" {b c}} $t insert end \n\n ww foreach r [lsort -decreasing -real [array names apprevs]] { $t insert end \ [format %4.2f $r] tt "\t[lindex $apprevs($r) 0]\n" tt \ "\t[lrange $apprevs($r) 1 end]\n\n" {n ww} } $t configure -state disabled ################### # SETTING GEOMETRY ################### pack $base.mb \ -anchor center -expand 0 -fill x -side top pack $base.mb.close \ -anchor center -expand 0 -fill none -side left pack $base.mb.quit \ -anchor center -expand 0 -fill none -side left pack $base.c \ -anchor center -expand 1 -fill both -side top grid columnconf $base.c 0 -weight 1 grid rowconf $base.c 0 -weight 1 grid $base.c.hs \ -column 0 -row 1 -columnspan 1 -rowspan 1 -sticky ew grid $base.c.vs \ -column 1 -row 0 -columnspan 1 -rowspan 1 -sticky ns grid $base.c.t \ -column 0 -row 0 -columnspan 1 -rowspan 1 -sticky nesw set x [expr [winfo screenwidth $base] / 2 - ( [winfo reqwidth $base] / 2 )] set y [expr [winfo screenheight $base] / 2 - ( [winfo reqheight $base] / 2 )] wm geometry $base 400x250+$x+$y } Window show . Window show .about Window show .prevuemain $argc $argv
You can download the above script without HTML escapes or refer to the older (v1.08) version. Rember to shift-click or otherwise select DOWNLOAD if you have the Tclet plugin installed! This script does its own cache management, as a stand alone Tcl/Tk application. That is not valid for most Tclet security policies.
The converse of this is tcletsVersion 2.00 - Special Purpose Browser
In late January or early February 1999, TV Guide bought out Prevue, and changed the display to be almost identical to that provided by this program. This application is no longer fully functional, because the web pages upon which it depends are no longer being produced. The logic of the program, and the validity of creating specialty applications for web content over which the creator has control remains quite valid.
Version 3.00 is in progress - will use schedules from www.tv1.com
Do you need help with your Tcl/Tk or PerlTk designs? Trying to figure out if this is the best tool for your current project? Looking into cross-platform compatibility? Need a concentrated course for your staff? Write us at <
ai@gtcs.com> for consultation, or call 1.307.637.3488Advanced Integrators, LC
Verson 2.00 was created with vTcl (a recent version), and routines from the previous v1.11 verson of this application were modified to handle multiple windows - then grafted in. It still does not have a central string and message table for ease in multi-lingual configuration, and only small token code segments are intended to ease the use on Windows95/98/NT/2000 or MacIntosh. Yet any of these could easily be added.
Unlike the v1.xx versions of this application, this one uses v2.0 of the standard tcl8.x distribution of html.tcl, complete with its namespace usage. This application, to keep it simpler, still does not use namespaces within this script.