From e9731978420254e387a7e95e9751cd3eff79c426 Mon Sep 17 00:00:00 2001 From: dcp1990 Date: Wed, 5 Jan 2005 03:41:41 +0000 Subject: [PATCH] Initial revision --- dumps/dump.chan | 109 +++++++++++++ dupl.rtf | Bin 0 -> 4203 bytes readme.txt | 45 ++++++ scripts/example.tcl | 10 ++ src/api.tcl | 10 ++ src/beartkat.conf | 11 ++ src/beartkat.tcl | 315 ++++++++++++++++++++++++++++++++++++++ src/configns.tcl | 36 +++++ src/dumpmem.tcl | 100 ++++++++++++ src/loadfreqs.tcl | 65 ++++++++ src/scommand.tcl | 18 +++ win32/beartkat.ico | Bin 0 -> 2238 bytes win32/beartkat_splash.bmp | Bin 0 -> 154872 bytes win32/btkinstall.ico | Bin 0 -> 2238 bytes win32/installer.nsi | 214 ++++++++++++++++++++++++++ 15 files changed, 933 insertions(+) create mode 100644 dumps/dump.chan create mode 100644 dupl.rtf create mode 100644 readme.txt create mode 100755 scripts/example.tcl create mode 100644 src/api.tcl create mode 100644 src/beartkat.conf create mode 100755 src/beartkat.tcl create mode 100644 src/configns.tcl create mode 100644 src/dumpmem.tcl create mode 100644 src/loadfreqs.tcl create mode 100644 src/scommand.tcl create mode 100644 win32/beartkat.ico create mode 100644 win32/beartkat_splash.bmp create mode 100644 win32/btkinstall.ico create mode 100644 win32/installer.nsi diff --git a/dumps/dump.chan b/dumps/dump.chan new file mode 100644 index 0000000..535f555 --- /dev/null +++ b/dumps/dump.chan @@ -0,0 +1,109 @@ +001:0154.8150,"Wakefield",-d yes +002:0155.5500,"Wakefield",-d yes +003:0155.9700,"Wakefield",-d yes +004:0460.1000,"Providence",-d yes +005:0460.2750,"Providence",-d yes +006:0460.3250,"Providence",-d yes +007:0154.7700,"East Providence",-d yes +008:0155.0100,"East Providence",-d yes +009:0155.4300,"Central Falls",-d yes +010:0155.6550,"Central Falls",-d yes +011:0154.8750,"Narragansett",-d yes +012:0482.8375,"Woonsocket",-d yes +013:0460.2000,"Providence",-d yes +014:0453.1500,"Providence",-d yes +015:0460.4250,"Providence",-d yes +016:0154.6950,"State",-d yes +017:0154.9050,"State",-d yes +018:0154.9350,"State",-d yes +019:0155.1900,"State",-d yes +020:0155.4450,"State",-d yes +021:0155.5050,"State",-d yes +022:0155.6100,"State",-d yes +023:0159.1500,"State",-d yes +024:0154.8000,"North Providence",-d yes +025:0158.9700,"North Providence",-d yes +026:0866.3500,"Providence",-d yes +027:0866.3875,"Providence",-d yes -l yes +028:0866.8875,"Providence",-d yes -l yes +029:0867.8125,"Providence",-d yes -l yes +030:0867.8375,"Providence",-d yes -l yes +031:0868.0625,"Providence",-d yes -l yes +032:0868.1000,"Providence",-d yes -l yes +033:0868.5875,"Providence",-d yes -l yes +034:0868.7875,"Providence",-d yes -l yes +035:0868.8375,"Providence",-d yes -l yes +036:0154.8900,"Warwick",-d yes +037:0155.1300,"Warwick",-d yes -l yes +038:0154.4300,"Pawtucket",-d yes +039:0154.8300,"Pawtucket",-d yes +040:0154.7250,"North Providence",-d yes +041:0156.3300,"Woonsocket",-d yes +042:0481.4125,"Cranston",-d yes +043:0482.4125,"Cranston",-d yes +044:0482.4625,"Cranston",-d yes +045:0482.5625,"Cranston",-d yes +046:0859.8375,"",-d yes -l yes +047:0860.3125,"",-d yes -l yes +048:0860.9875,"",-d yes -l yes +049:0866.9250,"A",-d yes -l yes +050:0155.6250,"Coventry",-d yes +051:0000.0000,"",-l yes +052:0000.0000,"",-l yes +053:0000.0000,"",-l yes +054:0000.0000,"",-l yes +055:0000.0000,"",-l yes +056:0000.0000,"",-l yes +057:0000.0000,"",-l yes +058:0000.0000,"",-l yes +059:0000.0000,"",-l yes +060:0000.0000,"",-l yes +061:0000.0000,"",-l yes +062:0000.0000,"",-l yes +063:0000.0000,"",-l yes +064:0000.0000,"",-l yes +065:0000.0000,"",-l yes +066:0000.0000,"",-l yes +067:0000.0000,"",-l yes +068:0000.0000,"",-l yes +069:0000.0000,"",-l yes +070:0000.0000,"",-l yes +071:0000.0000,"",-l yes +072:0000.0000,"",-l yes +073:0000.0000,"",-l yes +074:0000.0000,"",-l yes +075:0000.0000,"",-l yes +076:0000.0000,"",-l yes +077:0000.0000,"",-l yes +078:0000.0000,"",-l yes +079:0000.0000,"",-l yes +080:0000.0000,"",-l yes +081:0000.0000,"",-l yes +082:0000.0000,"",-l yes +083:0000.0000,"",-l yes +084:0000.0000,"",-l yes +085:0000.0000,"",-l yes +086:0000.0000,"",-l yes +087:0000.0000,"",-l yes +088:0000.0000,"",-l yes +089:0000.0000,"",-l yes +090:0000.0000,"",-l yes +091:0000.0000,"",-l yes +092:0000.0000,"",-l yes +093:0000.0000,"",-l yes +094:0000.0000,"",-l yes +095:0000.0000,"",-l yes +096:0000.0000,"",-l yes +097:0000.0000,"",-l yes +098:0000.0000,"",-l yes +099:0000.0000,"",-l yes +100:0000.0000,"",-l yes +101:0154.3700,"Providence",-d yes +102:0154.0700,"East Providence",-d yes +103:0154.4450,"Pawtucket",-d yes +104:0154.1300,"Woonsocket",-d yes +105:0046.4200,"Wakefield",-d yes +106:0155.2800,"Providence Amblc",-d yes +107:0155.3400,"Providence Amblc",-d yes +108:0154.1600,"Lincoln",-d yes +109:0123.1000,"Aircraft SAR",-d yes diff --git a/dupl.rtf b/dupl.rtf new file mode 100644 index 0000000000000000000000000000000000000000..2b9a6915d0d296155fe12161044b5345903c5bbf GIT binary patch literal 4203 zcmaJ_%WmUF7M=9~^A8u<#0J!A+ufZkW<^`HOhlqI6qSYnZHiP;sxir8sz|$)Apbt+ z79XOLac^WjSoeAExu^Wc&eYlMPLx);m$W+E-hH{-?PZqT{ISb)S=UL9H#fV?=t7jc ztTMmd?XvVJjFt5b#j22&Lit7!|Niek|NPfKcdtsmy{K~kdDo=3yGoe-E*ItD_U6;4 zUE++{yBi9(w>Qdro`am;L(l)P+pmmevDy4-=Woc!1 z5=Z>aLlmszU=>~%r1&UXd&-iasyz)0e3~+CsKMXlM4~*w+mwR(M~lZyrSUz^)S9e( zl}6?#%2lCis$sD*I#-!AqE@;jol&ZbLYh>Gd_rlCv-=NLHzt*2bymL#BPUce=@B+w zq%$#JFQ)XQ-`MzsU>D9ZVW`kX64&-P9kN?TzPG$zT-J&_7cv#%nnaPPL!)XX?Sza(Qk*jg-#B`j-^ z)*LP$5lwwWh*#VrRpPa9#TI$r9ea)V_o#fiNA$Y1R5nEdhhN<)XKBRjG@|qOF$m&!qrjfLeOoE*2en3GH_%NcA2F;CNr8tVn)C zwK&sMS0|$m$C}U_pwc2&u0kIUW`gdfY!-77AAv*0NvR2tGNP}j;o48=Wg2{(G7cq<#SP6 zWZgfLH;;Tj2YwEK7RFLy!f<^R`bYP5+2@e z{2AeEJR8yKYe-SB`DH?0ICD>W+xTe}U2U%E!3)DxO!q!L`HLAv{${-jHv!0vf)LL? z(^v1AHc#H#r&UCct7yqD?w6Std$d?>HWPNe_M;eKhqI6P+5gWrSTFrBrkS_&=7{<+ z2)*zj0O_3j_q z3mPZ12t3ZE4;k*bQXW4093GsaQ2wuY3)5X2+VwZ=yMgu}R?DRyaSk7G{sVG;3}S>o z3pQ~S+;7<$R}dc_`2FTQ%{<0ns~Cf?!7qwOxntCh7JEK$^ab>QN11poCl1u(wHvQJ zjNO`V5QALlM<+V`{8@+C;*Rbj*mEZtfd9=HNn zx2>se0kuA_nCL+nSQ^rdfQuA&Nt5TYCf@8I6f7cfKxm*xObCYh2-)D^e=w363aP{K zepea@20-Mdyn>3=}L}82k_nk7w{Q6_n&d z4N=uQhA81p2IA1|vcx-d!OF7jLf2Pj0%2d!2M`KKo-Oe5bb?}B-uFB|3Y9k?OjO_T zH+D<6sIk~uJ_B2y>BKb#8|?xGM*;rr62)?8a^$bdZh-~B^DOXUzhh0u*lZd2>}3Gk z@AVlXIj;iexkK$J1>RO0#@9s{e-$8Bpc(@wk9=?mS?akZ^d1)e|IWwIbZdX#OQud= zBH?cDvu+s$>ojf;T14@^b$+?2x!6~3jxO?aTcE;-YR0o0Dce+)HVgu{RXU+CuHN;4 z$gZ64W4E^vo_m0ZBv$^`uqbSS+2S7)Dh$?JlSAWnit@d} zFnrtnj8SQ22&?p7YdEdP%aT`T0u9Q0Fp0Yww1X=`&iN}tUFwlg$bRtWQZaKsnq>U|82I>*X9N<55^5fEC zkAkg*I=SL4-yJmIYt)qaj)N~aK+se(Az7!>>-O8Ozb)rtl&Tyg(W#@qHLw-jfDNuA z8HoxCE@iC&Wyi&KN^@ZG_QH|~)^I383i)erMPh{u9RfjJq1U>x`DxsgpQdz=SqI+_ zbM3kb8N{@R>lK;`os5f2uO!(pOhTzQtx~6>eq;3Mgpt?}niFiS&f3~TiMiWa%gLZy z*ClV{vF0#uoh5b>zH`#^69pj=IF9ZD90-MvHsC`qhs@r%a%c zF1PjImwB+;)@LXE#0`u2dv_u9AV0anwT;0o0_4)(F;FWjxqX_Yw_uQ&>v7h+*pw#KgE}7Hq)$ literal 0 HcmV?d00001 diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..9d6f5d2 --- /dev/null +++ b/readme.txt @@ -0,0 +1,45 @@ +******************************************************************************* +*** *** +*** BearTKat Readme *** +*** PLEASE READ! PLEASE READ! PLEASE READ! PLEASE READ! PLEASE READ! *** +*** *** +******************************************************************************* +1.0 Introduction + Welcome to BearTKat, one of the most fully-featured free scanner control applications for the BC250D and other Bearcat series scanner radios from Uniden that runs on both Unix and Windows! For someone new to computing, the Tcl/Tk approach may seem awkward and overly complicated. However, it is very sensible in actuality. Using Tcl/Tk allows more time to be spent on the application than interface coding and having differing codebases for different platforms. It also makes the author's job easier by bringing some comforts of the Unix programming environment to Windows, while maintaining consistency with other applications on the platform. + If you have bug reports, fixes, suggestions, questions, comments, or anything else, feel free to direct them to Dan at dcp1990@cox.net. +1.1 System Prerequisites + *Tcl/Tk 8.4 (stock for Unix works fine, on Windows, ActiveTcl works very nicely) (available from http://www.tcl.tl/) + *A BC250D radio and cable, other models may work with modifications + *A Unix-like operating system, Windows, and possibly Mac Classic + *A text editor (Vim is a fine choice) + *425k of disk space on Windows, less on Unix. More for frequency databases. +1.2 Licensing + BearTKat is one of the first applications licensed under the DUPL. A copy of the DUPL should be in the source distribution or displayed during installation on Windows. Please take the time to read the license, and if you are a commercial entity, it is imperative that you do so. If you are unsure about any part, talk to qualified legal personnel. +1.3 Developer Test Platforms + Dan is able to test BearTKat on: + *FreeBSD (stock Unix Tcl/Tk 8.4) + *Windows XP (ActiveTcl/Tk 8.4) + *Linux (stock Unix Tcl/Tk 8.4) +2.0 Installation and execution + On Unix, simply run src/beartkat.tcl. If your radio is on a serial device other than /dev/cuaa0 and/or your radio's baud rate is not 19200bps, edit beartkat.conf accordingly before use. If the path to your wish binary is not /usr/local/bin/wish8.4 (as it is on FreeBSD), change the first line of beartkat.tcl accordingly. + On Windows, run Setup.exe and the wizard will guide you from there. After installation, click either of the shortcuts created on the Desktop or the Start Menu. If your radio is on a serial device other than COM1: and/or your radio is set to a speed other than 19200 baud, please edit beartkat.conf (in the beartkat installation directory) as such. There should be a configuration utility/dialog in the very near future to handle this. + I am unsure about MacOS Classic, but I would imagine OSX users would follow a combination of the Windows and Unix procedures outlined above. +2.1 Usage + Upon execution of BearTKat, it will probe for your radio (by sending an "SI" command). If, after 9 tries, the radio doesn't respond, it will notify the user. If the user chooses to ignore, they can re-probe for the radio by going to Help->About my radio (which resends an "SI" command). Upon sucessful probing, the "Model:" label is set accordingly. After that, you are presented with 3 windows: the main window, the LCD/Keypad window, and the Frequency Import/Exportation window. Each serves a particular purpose, being either of: + *Controling BearTKat itself + *Controling the radio and displaying it's status + *Managing memories within the radio +2.2 BearTKat dialogs + "Set Alpha Tags," available from the Scanner menu in the main window, as it's name implies, allows you to set, clear, and retreive alpha tags for a given channel. In the channel box, one must enter a three-digit channel number, 000 being channel 1000 and 001 being channel 1. You must pad the number with zeroes. Use is fairly self-explanatory besides that point. + The "About my radio" dialog, accessed from the Help menu, allows one to view information about their radio, including model number and battery status. +2.3 Radio control + The LCD/Keypad window emulates the LCD display of the radio and a select few buttons. To begin polling the radio for it's LCD contents, click the "Start Polling" button in the main window. When polling is enabled, BearTKat will request LCD contents every second (this is adjustable by using the "interval" configuration parameter) until the "Stop Polling" button is pressed. You may resume polling by clicking "Start Polling" again. Other than that, use is fairly self-explanatory. +2.4 Frequency Management + A frequency database is simply a file with lines in the form of: +Channel:freq.uency,"Alpha Tag",-d , -l +For example: + 016:0154.6950,"State",-d yes -l no +Channel is a 3 digit number (padded with zeroes), frequency is the frequency in megahertz, -d specifies the delay flag, and -l specifies the lockout flag. An example is included in the file dumps/dump.chan. +To dump your frequencies, use the buttons in the "Frequencies" window. +2.5 Channel dialog + The channel dialog allows one to load a dump in the proper format and manage the channels. Currently, only tuning to a specific channel is supported (and the scanner and dump file must be in sync to work properly). diff --git a/scripts/example.tcl b/scripts/example.tcl new file mode 100755 index 0000000..fb8cfd0 --- /dev/null +++ b/scripts/example.tcl @@ -0,0 +1,10 @@ +# Example BearTKat script +# gets info, toggles light, switches to weather and back again +# (C)2004, 2005 Dan Ponte +puts "Loading..." +puts [beartkat::docommand "SI"] +beartkat::togglelight +after 1000 {beartkat::togglelight; after 1000 {beartkat::togglelight;after 1000 beartkat::togglelight}} +beartkat::docommand "KEY10" +beartkat::docommand "KEY02 1" +after 5000 {beartkat::docommand "KEY01"} diff --git a/src/api.tcl b/src/api.tcl new file mode 100644 index 0000000..7a7f04e --- /dev/null +++ b/src/api.tcl @@ -0,0 +1,10 @@ +#api +namespace eval beartkat { + namespace export docommand + proc docommand {cmd} { + return [scommand $cmd] + } + proc togglelight {} { + return [scommand "KEY08"] + } +} diff --git a/src/beartkat.conf b/src/beartkat.conf new file mode 100644 index 0000000..5deb495 --- /dev/null +++ b/src/beartkat.conf @@ -0,0 +1,11 @@ +# this file is source(n)'d from configns.tcl. Put tcl here if you want, +# but it isn't recommended. +baud 19200 +# This sets the interval. Default is 1 second. +# interval 1 +# simple default checks, change this if you want +if {$unix} { + serial /dev/cuaa0 +} elseif {$windows} { + serial COM1: +} diff --git a/src/beartkat.tcl b/src/beartkat.tcl new file mode 100755 index 0000000..7199bb2 --- /dev/null +++ b/src/beartkat.tcl @@ -0,0 +1,315 @@ +#!/usr/local/bin/wish8.4 +# under the DUPL +# (C)2004-2005, Dan Ponte +#YA!!! +#package require wcb +set lastcmd "" +set version 0.1 +set tries 1 +set gotresp no +set donthandle no +proc setalpha {chan tag fhh mde} { + if {[expr [string length $chan] != 3]} { + return + } + if {[string equal $mde "set"]} { + sendcommand [list TA C $chan $tag] + } elseif {[string equal $mde "clear"]} { + sendcommand "TA C $chan " + } elseif {[string equal $mde "get"]} { + set algt [scommand "TA C $chan"] + if {[regexp -- "TA C (\[0-9\]{3}) (.{0,16})\$" $algt a cn ttag]} { + if {[string equal [.alp.mfr.chan get] $cn]} { + .alp.mfr.ent delete 0 end + .alp.mfr.ent insert 1 $ttag + } + } + } +} +proc rejmod {w args} { +# wcb::cancel + return +} +proc table {w content args} { + frame $w -bg black + set r 0 + foreach row $content { + set fields {} + set c 0 + foreach col $row { + lappend fields [label $w.$r/$c -text $col] + incr c + } + eval grid $fields -sticky news -padx 1 -pady 1 + incr r + } + set w +} + +proc dispol {} { + global fhn + every "cancel" {sendcommand "LCD"} + .mfr.openprt configure -text "Start Polling" + .mfr.openprt configure -command {enabpol $fhn} +} +proc gbatt {} { + set blvl [scommand "BL"] + if {[regexp "BAT (\[0-9\]{3})" $blvl a lvl]} { + set flvl [expr {int($lvl * .392156862745098)}] + .disp.scr.batt configure -text "Batt: $flvl%" + } +} +proc checkscanner {} { + global waitingresp + global gotresp + if {$gotresp} { + return + } + set gotresp no + global fhn + set waitingresp yes + global tries + if {$tries == 1} { + sendcommand SI + after 1000 {incr tries; checkscanner} + } elseif {$tries < 9} { + sendcommand SI + after 1000 {incr tries; checkscanner} + } elseif {$tries == 9} { + set res [tk_messageBox -message "Never got a response from the radio.\nCheck that it is plugged in, your serial settings are correct, and that it is powered on." -type abortretryignore -icon error] + if {$res == "abort"} { + exit -1 + } elseif {$res == "retry"} { + set waitingresp yes + set gotresp no + set tries 1 + checkscanner + } elseif {$res == "ignore"} { + .statusbar.scmodel configure -text "Goto Help->About my radio" + return + } + } +} +proc filedialog {w types oper ent} { + set file [realdialog $w $types $oper] + if [string compare $file ""] { + $ent delete 0 end + $ent insert 0 $file + $ent xview end + } + return $file +} +proc realdialog {w types oper} { + if {$oper == "open"} { + set file [tk_getOpenFile -filetypes $types -parent $w] + } else { + set file [tk_getSaveFile -filetypes $types -parent $w \ + -initialfile Untitled -defaultextension .txt] + } + return $file +} +proc enabpol fhh { + global fhn + .mfr.openprt configure -text "Stop Polling" + .mfr.openprt configure -command {dispol} + every $btkConfig::interv {sendcommand "LCD"} +} +proc every {interval script} { + global everyIds + if {$interval eq "cancel"} { + catch {after cancel $everyIds($script)} + return + } + set everyIds($script) [after $interval [info level 0]] + uplevel #0 $script +} +set alphop no +proc oalphwind {} { + global alphop + toplevel .alp + set alphop yes + .menubar.scan activate "Set Alpha Tags" + wm resizable .alp no no + wm title .alp "Alpha Tags" + frame .alp.mfr -borderwidth 2 + pack .alp.mfr + label .alp.mfr.cl -text "Channel number:" + entry .alp.mfr.chan -width 4 -validate key -vcmd {expr {[regexp "^\[0-9\]{0,3}\$" %P] && [string length %P]<4}} + pack .alp.mfr.cl .alp.mfr.chan -side left + label .alp.mfr.tl -text "Alpha Text:" + entry .alp.mfr.ent -width 16 -validate key -vcmd {expr {[string length %P] < 17}} + pack .alp.mfr.tl .alp.mfr.ent -side left + button .alp.mfr.setal -text "Set Alpha" -command {setalpha [.alp.mfr.chan get] [.alp.mfr.ent get] $fhn set} + button .alp.mfr.clral -text "Clear Alpha" -command {setalpha [.alp.mfr.chan get] [.alp.mfr.ent get] $fhn clear} + button .alp.mfr.getal -text "Get Alpha" -command {setalpha [.alp.mfr.chan get] "" $fhn get} + pack .alp.mfr.setal .alp.mfr.clral .alp.mfr.getal -side left + button .alp.mfr.close -text "Okay" -command "destroy .alp; set alphop no" + pack .alp.mfr.close -fill y + wm protocol .alp WM_DELETE_WINDOW {set alphop no} +} +proc handlefile fhh { + global lastin + global donthandle + global lastcmd + set curin [gets $fhh] + if {[regexp -- "LCD(\[1-4\]) \\\[(.{16})\\\]\\\[(.{16})\\\]" $curin oth lnum te fmt]} { + if {[expr $lnum == 1]} { + .disp.scr.lcd1 configure -text $te + } elseif {[expr $lnum == 2]} { + .disp.scr.lcd2 configure -text $te + } elseif {[expr $lnum == 3]} { + .disp.scr.lcd3 configure -text $te + } elseif {[expr $lnum == 4]} { + .disp.scr.lcd4 configure -text $te + } + return; + } elseif {[regexp -- "ERR" $curin]} { + tk_messageBox -message "Received ERR message from radio. Last command $lastcmd" -type ok -icon error + } elseif {[regexp -- {SI (.*),(.*),([0-9][0-9][0-9])$} $curin a model esn rcmdv]} { + global waitingresp + global gotresp + if {$waitingresp && !$gotresp} { + set waitingresp no + set gotresp yes + .statusbar.scmodel configure -text "Model: $model" + } elseif {$donthandle} { + set lastin $curin + set donthandle no + } else { + set blfs [scommand "BL"] + regexp "BAT (\[0-9\]{3})" $blfs a batl + set blevel [expr {int( $batl * .392156862745098)}] + tk_messageBox -message "Scanner reported the following:\nModel: $model\nRemote Command Version: $rcmdv\nESN (not used): $esn\nBattery Level: $batl ($blevel%)" -type ok -icon info -title "About my radio" + } + } elseif {[string length $curin] > 1} { + set lastin $curin + } +} +source scommand.tcl +source api.tcl +source configns.tcl +source dumpmem.tcl +source loadfreqs.tcl +wm geometry . "=200x100" +set fhn [ open $btkConfig::ttydev "r+" ] +fconfigure $fhn -mode $btkConfig::baudrate,n,8,1 -blocking no +wm title . "BearTkat v$version" +frame .mfr -borderwidth 2 -width 102c -height 30c +grid .mfr -sticky wwwwwnnnnn -row 0 -column 0 +#frame .menubar -relief raised -bd 2 +#pack .menubar -in .mfr -fill x -expand yes +menu .menubar -tearoff no +#menubutton .menubar.file -text "File" -menu .menubar.file.menu +#pack .menubar.file -side left +#menubutton .menubar.scan -text "Scanner" -menu .menubar.scan.menu +#pack .menubar.scan -side left +#menubutton .menubar.help -text "Help" -menu .menubar.help.menu +#pack .menubar.help -side right +menu .menubar.file -tearoff no +.menubar add cascade -label "File" -menu .menubar.file -underline 0 +.menubar.file add command -label "Exit" -command "exit" +.menubar.file add command -label "Run Tcl Script" -command {set tscr [realdialog . {{"Tcl Script" {.tcl}}} open]; if {[string compare $tscr ""]} {source $tscr}} +menu .menubar.scan -tearoff no +.menubar add cascade -label "Scanner" -menu .menubar.scan -underline 0 +.menubar.scan add command -label "Set Alpha Tags" -command {if {!$alphop} {oalphwind}} +menu .menubar.help -tearoff no +.menubar add cascade -label "Help" -menu .menubar.help -underline 0 +.menubar.help add command -label "Help" -command {tk_messageBox -message "No online help yet. Try README.txt, included in the distribution." -type ok -icon info} +.menubar.help add command -label "About my radio" -command {sendcommand "SI"} +.menubar.help add command -label "About BearTKat" -command {tk_messageBox -message "BearTKat v$version - a scanner control app for the BC250D and other radios\n(C)2004-2005, Dan Ponte. Licensed under the DUPL.\nA copy of the DUPL should have been included with this application. If not, write dcp1990@cox.net.\nPortions (specifically the control protocol) are copyright (C)2003,2004 Uniden America, Inc.\nThis product is not endorsed by or affiliated with Uniden.\nThe \"Bearcat\" logo and the Bearcat name are property of Uniden America and are trademarked." -type ok -icon info -title "About BearTKat"} +if {$windows} { + menu .menubar.system -tearoff no + .menubar add cascade -label "System" -menu .menubar.system -underline 0 + .menubar.system add command -label "About my radio" -command {sendcommand SI} +} +button .mfr.openprt -text "Start Polling" -command {enabpol $fhn} +button .mfr.quit -text "Exit" -command "exit" +pack .mfr.openprt .mfr.quit -side left +frame .statusbar +grid .statusbar -sticky s -row 4 +label .statusbar.scmodel -text "Model: Waiting..." +pack .statusbar.scmodel +toplevel .disp +wm title .disp "LCD" +wm resizable .disp no no +frame .disp.scr -borderwidth 2 -width 16c -height 4c -relief sunken -background orange +pack .disp.scr +label .disp.scr.lcd1 -width 16 -text " " -background orange -font "Courier 10" +label .disp.scr.lcd2 -width 16 -text " " -background orange -font "Courier 10" +label .disp.scr.lcd3 -width 16 -text " " -background orange -font "Courier 10" +label .disp.scr.lcd4 -width 16 -text " " -background orange -font "Courier 10" +pack .disp.scr.lcd1 .disp.scr.lcd2 .disp.scr.lcd3 .disp.scr.lcd4 +#label .disp.scr.batt -width 10 -text "Batt: ---" -background orange -font "Courier 10" +#pack .disp.scr.batt -side left +frame .disp.but -borderwidth 2 -width 16c -height 7c +pack .disp.but +set crow 0 +button .disp.but.scan -text "SCAN" -command {sendcommand "KEY01"} +button .disp.but.rsm -text "RSM" -command {sendcommand KEY00} +button .disp.but.manual -text "MAN" -command {sendcommand KEY07} +button .disp.but.lgt -text "Light" -command {sendcommand "KEY08"} +button .disp.but.wx -text "WX" -command {sendcommand "KEY10"; sendcommand "KEY02 1"} +button .disp.but.lockout -text "L/O" -command {sendcommand "KEY06"} +grid .disp.but.manual .disp.but.rsm -sticky we -ipadx .2c +grid .disp.but.scan .disp.but.wx -sticky we +grid .disp.but.lgt .disp.but.lockout -sticky we +frame .disp.butk -width 7c +pack .disp.butk -expand yes -fill x +foreach cn {1 2 3} { + button .disp.butk.kn$cn -text $cn -command [list sendcommand [list KEY02 $cn]] + grid .disp.butk.kn$cn -row $crow -column [expr "$cn - 1"] -sticky we -ipadx .25c +} +incr crow +foreach cn {4 5 6} { + button .disp.butk.kn$cn -text $cn -command [list sendcommand [list KEY02 $cn]] + grid .disp.butk.kn$cn -row $crow -column [expr "$cn - 4"] -sticky we +} +incr crow +foreach cn {7 8 9} { + button .disp.butk.kn$cn -text $cn -command [list sendcommand [list KEY02 $cn]] + grid .disp.butk.kn$cn -row $crow -column [expr "$cn - 7"] -sticky we +} +unset cn +button .disp.butk.dec -text "." -command {sendcommand "KEY03"} +button .disp.butk.kn0 -text "0" -command {sendcommand "KEY02 0"} +button .disp.butk.enter -text "E" -command {sendcommand KEY04} +grid .disp.butk.dec .disp.butk.kn0 .disp.butk.enter -sticky we +fileevent $fhn readable {handlefile $fhn} +set tx .freq.outp +toplevel .freq +wm title .freq "Frequencies" +text .freq.outp -wrap word -width 78 -height 20 -setgrid on -yscrollcommand ".freq.ys set" +scrollbar .freq.ys -command ".freq.outp yview" +$tx insert end "This is the output area. Click the 'Open' button below to open a file in the following format:\n\tchannel#:freq.uency,\"Alpha tag\",-d yes|no -l yes|no\\n\nwhere -d is the delay flag and -l is the lockout flag\n" +pack .freq.ys -side right -fill y +pack .freq.outp -fill both -expand 1 +frame .freq.mfr -height 24c -width 80c +pack .freq.mfr -side left -fill x +entry .freq.mfr.ftop -width 20 +button .freq.mfr.browse -text "Browse..." -command {filedialog . {{"Frequency Database" {.fdb .chan}}} save .freq.mfr.ftop} +button .freq.mfr.dfreqs -text "Dump frequencies" -command {.freq.mfr.dfreqs configure -state disabled; dumpall [.freq.mfr.ftop get] $tx; .freq.mfr.dfreqs configure -state normal} +pack .freq.mfr.ftop .freq.mfr.browse .freq.mfr.dfreqs -side left +toplevel .chanl +wm title .chanl "Channels" +frame .chanl.f -height 16c -width 80c +frame .chanl.b -height 4c -width 80c +pack .chanl.f .chanl.b -side top -fill y +scrollbar .chanl.f.scb -command ".chanl.f.clist yview" +listbox .chanl.f.clist -height 14 -setgrid 1 -width 64 -yscroll ".chanl.f.scb set" +entry .chanl.b.fet -width 20 +button .chanl.b.load -text "Load FDB" -command {filedialog . {{"Frequency Database" {.fdb .chan}}} open .chanl.b.fet; loadtolist [.chanl.b.fet get] .chanl.f.clist } +button .chanl.b.tune -text "Tune Selected" -command {set csel [.chanl.f.clist curselection] ; if {[string length $csel] == 0} {tk_messageBox -message "Nothing selected!" -type ok -icon error} else { tunechan [.chanl.f.clist get $csel]} } +pack .chanl.f.scb -side right -fill y +pack .chanl.f.clist -side left -fill x +pack .chanl.b.fet .chanl.b.load .chanl.b.tune -side left -fill y +#wcb::callback $tx before insert rejmod +#wcb::callback $tx before delete rejmod +wm protocol . WM_DELETE_WINDOW {exit} +wm protocol .disp WM_DELETE_WINDOW {exit} +wm resizable . no no +wm protocol .chanl WM_DELETE_WINDOW {exit} +. configure -menu .menubar +if {$windows} { + wm iconbitmap . -default "beartkat.ico" +} +checkscanner diff --git a/src/configns.tcl b/src/configns.tcl new file mode 100644 index 0000000..1e863d5 --- /dev/null +++ b/src/configns.tcl @@ -0,0 +1,36 @@ +#config namespace +if {$tcl_platform(platform) == "unix"} { + set unix yes + set windows no +} elseif {$tcl_platform(platform) == "windows"} { + set unix no + set windows yes +} +namespace eval btkConfig { + variable ttydev "/dev/cuaa0" + variable baudrate 19200 + variable interv 1000 + namespace export baud + namespace export serial + namespace export interval + proc baud {rate} { + if {[string is integer $rate]} { + set btkConfig::baudrate $rate + } else { + tk_messageBox -message "Error: baud parameter only accepts arguments in the form of an integer. Using default." -type ok -icon error -title "Configuration error" + } + } + proc serial {device} { + set btkConfig::ttydev $device + } + proc interval {seconds} { + if {[string is double $seconds]} { + set btkConfig::interv [expr [list int( $seconds * 1000 )]] + } else { + tk_messageBox -message "Error: interval parameter only accepts arguments in the form of a number. Using default." -type ok -icon error -title "Configuration error" + } + } +} +namespace import btkConfig::baud btkConfig::serial btkConfig::interval +source beartkat.conf +namespace forget btkConfig::* diff --git a/src/dumpmem.tcl b/src/dumpmem.tcl new file mode 100644 index 0000000..0c22771 --- /dev/null +++ b/src/dumpmem.tcl @@ -0,0 +1,100 @@ +#!/usr/local/bin/tclsh8.4 +# dumps the specified bank +set cr 1 +proc getbank {chan} { + if {[expr $chan <= 100 && $chan >= 1]} { + return "A" + } elseif {[expr $chan >= 101 && $chan <= 200]} { + return "B" + } elseif {[expr $chan >= 201 && $chan <= 300]} { + return "C" + } elseif {[expr $chan >= 301 && $chan <= 400]} { + return "D" + } elseif {[expr $chan >= 401 && $chan <= 500]} { + return "E" + } elseif {[expr $chan >= 501 && $chan <= 600]} { + return "F" + } elseif {[expr $chan >= 601 && $chan <= 700]} { + return "G" + } elseif {[expr $chan >= 701 && $chan <= 800]} { + return "H" + } elseif {[expr $chan >= 801 && $chan <= 900]} { + return "I" + } elseif {[expr ($chan >= 901 && $chan <= 1000) || $chan == 0]} { + return "J" + } +} +proc getbankschan {bank} { + return [string map {A 1 B 101 C 201 D 301 E 401 F 501 G 601 H 701 I 801 J 901} $bank] +} +proc getbankechan {bank} { + return [string map {A 100 B 200 C 300 D 400 E 500 F 600 G 700 H 800 I 900 J 1000} $bank] +} +proc simulcommand {command} { + #puts [join [list "Running command" $command]] + if {[regexp -- "^TA (\[CB\]) (\[A-J\]|\[0-9\]{3}) (.{0,16})$" $command a mde bchan tag]} { + return "OK" + } elseif {[regexp -- "^TA C (\[0-9\]{3})$" $command a chan]} { + return "TA C $chan Some Tag" + } elseif {[regexp -- "^PM(\[0-9\]{3})$" $command a chan]} { +#C089 F08511625 TN DN LF AF RF N000 + return "C$chan F01555500 TN DN LN AF RF N000" + } +} +proc dumpbank {bank file fhn} { + set bstart [getbankschan $bank] + set bend [getbankechan $bank] + set ccdbh [open $file "a"] + for {set cx $bstart} {$cx <= $bend} {incr cx} { + if {[expr [string length $cx] < 3]} { + lappend x [join [list [string repeat "0" [expr 3- [string length $cx]]] $cx] ""] + } elseif {[expr $cx == 1000]} { + set x "000" + } else { + set x $cx + } + set result [scommand [join [list "PM" $x] ""]] + set tag [scommand [list "TA" "C" $x]] + if {[regexp -- "^TA C $x (.{1,16})" $tag a ttg]} { + set fta [join [list ",\"" $ttg "\""] ""] + } else { + set fta ",\"\"" + } + if {[regexp -- "^C(\[0-9\]{3}) F(\[0-9\]{4})(\[0-9\]{4}) T(\[TFNY\]) D(\[TFNY\]) L(\[TFNY\]) A(\[TFNY\]) R(\[TFNY\]) N(\[0-9\]{3})" $result a chan wmhz dmhz trunked delay lockout atten recording ctcss]} { + set flags " " + if {[string equal "N" $delay]} { + lappend flags -d yes + } + if {[string equal "N" $lockout]} { + lappend flags -l yes + } + puts $ccdbh [join [list $chan ":" $wmhz "." $dmhz $fta "," $flags] ""] + } + unset -nocomplain chan wmhz fta result x tag ttg + } + close $ccdbh +} +proc dumpall {filename clabel} { + $clabel insert end "Dumping to $filename\n" + $clabel insert end "Dumping bank A...\n" + dumpbank "A" $filename 0 + $clabel insert end "Dumping bank B...\n" + dumpbank "B" $filename 0 + $clabel insert end "Dumping bank C...\n" + dumpbank "C" $filename 0 + $clabel insert end "Dumping bank D...\n" + dumpbank "D" $filename 0 + $clabel insert end "Dumping bank E...\n" + dumpbank "E" $filename 0 + $clabel insert end "Dumping bank F...\n" + dumpbank "F" $filename 0 + $clabel insert end "Dumping bank G...\n" + dumpbank "G" $filename 0 + $clabel insert end "Dumping bank H...\n" + dumpbank "H" $filename 0 + $clabel insert end "Dumping bank I...\n" + dumpbank "I" $filename 0 + $clabel insert end "Dumping bank J...\n" + dumpbank "J" $filename 0 + $clabel insert end "Dumping Finished!" +} diff --git a/src/loadfreqs.tcl b/src/loadfreqs.tcl new file mode 100644 index 0000000..983ebf3 --- /dev/null +++ b/src/loadfreqs.tcl @@ -0,0 +1,65 @@ +#!/usr/local/bin/tclsh8.4 +proc loadfreqs {file range} { + set freqdbh [ open $file "r" ] + while {[gets $freqdbh cline] >= 0} { + if {[regexp -- "^(\[0-9\]{1,3}):(\[0-9\]{2,4})\\.(\[0-9\]{3,4}),\"(.{0,16})\",(.*)$" $cline a chan wmhz dmhz alpha flags]} { + if {[expr [string length $wmhz] != 4]} { + lappend mhz [join [list [string repeat "0" [expr 4- [string length $wmhz]]] $wmhz] ""] + } else { + lappend mhz $wmhz + } + if {[expr [string length $dmhz] != 4]} { + lappend mhz [join [list $dmhz [string repeat "0" [expr 4- [string length $dmhz]]]] ""] + } else { + lappend mhz $dmhz + } + set fmhz [join $mhz ""] + if {[expr [string length $chan] != 3]} { + lappend rchan [join [list [string repeat "0" [expr 3- [string length $chan]]] $chan] ""] + } else { + lappend rchan $chan + } + set fcmd [join [list PM $rchan] ""] + set fcmdl [join [list $fcmd $fmhz]] + puts $fcmdl + if {[expr [string length $alpha] > 0]} { + sendcommand "TA C $rchan $alpha" + } + foreach {key value} $flags { + if {[string equal $key "-d"] && [string is boolean $value] && $value} { + sendcommand "MA$rchan" + sendcommand "DLN" + } elseif {[string equal $key "-l"] && [string is boolean $value] && $value} { + sendcommand "MA$rchan" + sendcommand "LON" + } + } + unset -nocomplain mhz fcmd fcmdl rchan a chan wmhz dmhz wal alpha key value flags + } elseif {[regexp -- "^B(\[0-9\]|\[A-J\]):\"(.{0,16})\"$" $cline a bank btg]} { + if {[string is digit $bank]} { + set fbnk [string map {0 J 1 A 2 B 3 C 4 D 5 E 6 F 7 G 8 H 9 I} $bank] + } else { + set fbnk $bank + } + sendcommand "TA B $fbnk $btg" + unset -nocomplain a bank btg fbnk + } + } + close $freqdbh +} +proc loadtolist {file lb} { + if {[string length $file] == 0} {return} + set freqdbh [ open $file "r" ] + while {[gets $freqdbh cline] >= 0} { + if {[regexp -- "^(\[0-9\]{1,3}):(\[0-9\]{2,4})\\.(\[0-9\]{3,4}),\"(.{0,16})\",(.*)$" $cline a chan wmhz dmhz alpha flags]} { + if {$wmhz == 0} { continue } + $lb insert end [list [join [list $chan :] ""] [join [list $wmhz "." $dmhz] ""] $alpha] + } + } + close $freqdbh +} +proc tunechan {chanline} { + if {[regexp -- "^(\[0-9\]{1,3}):" $chanline a chan]} { + scommand [join [list "MA" $chan] ""] + } +} diff --git a/src/scommand.tcl b/src/scommand.tcl new file mode 100644 index 0000000..92de0d4 --- /dev/null +++ b/src/scommand.tcl @@ -0,0 +1,18 @@ +# sourced from main +proc scommand {command} { + global fhn + global lastin + global lastcmd + puts $fhn $command + flush $fhn + set lastcmd $command + vwait lastin + return $lastin +} +proc sendcommand {cmd} { + global lastcmd + global fhn + puts $fhn $cmd + flush $fhn + set lastcmd $cmd +} diff --git a/win32/beartkat.ico b/win32/beartkat.ico new file mode 100644 index 0000000000000000000000000000000000000000..e97f1c78b07de981b76231217ab152b0dc07cfe6 GIT binary patch literal 2238 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 Jf%Ytc{|}3^81Dc8 literal 0 HcmV?d00001 diff --git a/win32/btkinstall.ico b/win32/btkinstall.ico new file mode 100644 index 0000000000000000000000000000000000000000..b0540fcb6054135c3f2ae4e5e9cb2a52a2d6d6c1 GIT binary patch literal 2238 zcmeH|F;c`Z3`OO5GueWfbkr#+a|1Za-hm5*8&Getv>byQ) zf$JOizi*)b1Bouh<>pg|NsVHSAqM=(jcu;jxZSQ*{Duu{zW47m z-S0$ZlrCMOTp$kVEs0b6z80@g=Bx50l==>j`i1?-m4KG@bAEgNK7=h^6U`L;bs?a% zHX(JBdW3u)ZCZ^+NQ{edJ?emJoZ9?;EWUg4dA@8^60ueLt6lX8^R)#3|2O%F`~;=T wCF>jZ%OewGJ%b&fwCQ1huTVKpP#Q3sD?ih~d-!j_$20Vkd0g&!MA;YSFS}`3y8r+H literal 0 HcmV?d00001 diff --git a/win32/installer.nsi b/win32/installer.nsi new file mode 100644 index 0000000..2394fb7 --- /dev/null +++ b/win32/installer.nsi @@ -0,0 +1,214 @@ +; Script generated by the HM NIS Edit Script Wizard. + +; HM NIS Edit Wizard helper defines +!define PRODUCT_NAME "BearTKat" +!define PRODUCT_VERSION "0.1" +!define PRODUCT_PUBLISHER "KiwiSoft" +!define PRODUCT_WEB_SITE "http://skynard.flinkpoyd.homeunix.com:88/beartkat.html" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\makensis.exe" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" +!define PRODUCT_UNINST_ROOT_KEY "HKLM" + +SetCompressor bzip2 + +; MUI 1.67 compatible ------ +!include "MUI.nsh" +!include Sections.nsh +; MUI Settings +!define MUI_ABORTWARNING +!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" + +; Welcome page +!define MUI_WELCOMEPAGE_TEXT "Welcome to the BearTKat installer!\r\n\r\nPlease note that BearTKat needs both Tcl/Tk8.4 (tested with ActiveTcl) and Wcb3.0, both available online.\r\n\r\nAlso, please read all supplied documentation prior to use.\r\n\r\n\r\nClick Next to begin the install." +!insertmacro MUI_PAGE_WELCOME +; License page + +!define MUI_LICENSEPAGE_CHECKBOX +!define MUI_LICENSEPAGE_TEXT_TOP "It is imperative that you read the license, especially if you are a commercial entity." +!insertmacro MUI_PAGE_LICENSE "dupl.rtf" + +; Directory page +!insertmacro MUI_PAGE_DIRECTORY + + +!insertmacro MUI_PAGE_COMPONENTS +; Instfiles page +!insertmacro MUI_PAGE_INSTFILES +; Finish page +!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt" +!define MUI_FINISHPAGE_NOAUTOCLOSE +!insertmacro MUI_PAGE_FINISH + +; Uninstaller pages +!insertmacro MUI_UNPAGE_INSTFILES + +; Language files +!insertmacro MUI_LANGUAGE "English" + + +; Reserve files +!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS + +; MUI end ------ + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +XPStyle on +OutFile "BearTKatSetup.exe" +CRCCheck on +Icon btkinstall.ico +UninstallIcon btkinstall.ico +InstallDir "$PROGRAMFILES\BearTKat" +InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" +ShowInstDetails show +ShowUnInstDetails show +Function .onInit +SetOutPath $TEMP +InitPluginsDir +File /oname=splash.bmp beartkat_splash.bmp +advsplash::show 1000 600 400 -1 $TEMP\splash +Pop $0 +Delete $TEMP\splash.bmp +functionend +Section "Main (required)" SEC01 +SectionIn RO +SetDetailsPrint textonly + DetailPrint "Main Files" + SetDetailsPrint listonly + +IfFileExists "C:\Tcl\bin\wish84.exe" sokt +MessageBox MB_OKCANCEL "Apparently Tcl/Tk 8.4 isn't installed. You can get it from http://www.tcl.tk/" IDOK sok +quit +sok: +ExecShell open "http://www.tcl.tk/" +sokt: +IfFileExists "C:\Tcl\lib\wcb3.0\wcb.tcl" tokt +MessageBox MB_okcancel "Apparently, Wcb3.0 isn't installed. Search http://wiki.tcl.tk/ for Wcb to find and install it." idok tok +quit +tok: +ExecShell open "http://wiki.tcl.tk/" +tokt: + SetOutPath "$INSTDIR" + SetOverwrite ifnewer + ; File "${NSISDIR}\makensis.exe" + CreateDirectory "$SMPROGRAMS\BearTKat" + CreateShortCut "$SMPROGRAMS\BearTKat\BearTKat.lnk" "$INSTDIR\main.tcl" parameters "$INSTDIR\beartkat.ico" + CreateShortCut "$DESKTOP\BearTKat.lnk" "$INSTDIR\main.tcl" parameters "$INSTDIR\beartkat.ico" + File "dupl.rtf" + File "beartkat.ico" + File "beartkat.tcl" + File "scommand.tcl" + File "dumpmem.tcl" + File "loadfreqs.tcl" + File "api.tcl" + File "configns.tcl" + File "dump.chan" + File "beartkat.conf" + File "README.txt" + File "beartkat_splash.bmp" + ; Wrapper script (cd's to the install directory and sources beartkat.tcl, which does all the work) + DetailPrint "Writing main.tcl wrapper script..." + FileOpen $3 $INSTDIR\main.tcl w + FileWrite $3 "# Generated by the BearTKAT installer (NSIS) on ${__TIMESTAMP__}$\n" + FileWrite $3 'set appinstpath {$INSTDIR}$\n' + FileWrite $3 'cd $$appinstpath$\n' + FileWrite $3 'source beartkat.tcl' + FileClose $3 +SectionEnd + + + + +Section "Example Scripts" SEC02 + SetOutPath "$INSTDIR\scripts" + SetOverwrite ifnewer + File "scripts\example.tcl" +SectionEnd + +Section -AdditionalIcons + WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" + CreateShortCut "$SMPROGRAMS\BearTKat\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" + CreateShortCut "$SMPROGRAMS\BearTKat\Uninstall.lnk" "$INSTDIR\uninst.exe" +SectionEnd + +Section -Post + WriteUninstaller "$INSTDIR\uninst.exe" + WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\makensis.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\beartkat.ico" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" + WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" +SectionEnd + +Function ConnectInternet + + Push $R0 + + ClearErrors + Dialer::AttemptConnect + IfErrors noie3 + + Pop $R0 + StrCmp $R0 "online" connected + MessageBox MB_OK|MB_ICONSTOP "Cannot connect to the internet." + Quit ;Remove to make error not fatal + + noie3: + + ; IE3 not installed + MessageBox MB_OK|MB_ICONINFORMATION "Please connect to the internet now." + + connected: + + Pop $R0 + +FunctionEnd + +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." +FunctionEnd + +Function un.onInit + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2 + Abort +FunctionEnd + +Section Uninstall + Delete "$INSTDIR\${PRODUCT_NAME}.url" + Delete "$INSTDIR\uninst.exe" + Delete "$INSTDIR\scommand.tcl" + Delete "$INSTDIR\main.tcl" + delete "$INSTDIR\beartkat.tcl" + Delete "$INSTDIR\dupl.rtf" + Delete "$INSTDIR\loadfreqs.tcl" + Delete "$INSTDIR\dumpmem.tcl" + Delete "$INSTDIR\api.tcl" + Delete "$INSTDIR\configns.tcl" + Delete "$INSTDIR\dump.chan" + Delete "$INSTDIR\beartkat.ico" + Delete "$INSTDIR\README.txt" + Delete "$INSTDIR\beartkat.conf" + Delete "$INSTDIR\License.txt" + ; Delete "$INSTDIR\makensis.exe" + Delete "$INSTDIR\beartkat_splash.bmp" + Delete "$INSTDIR\scripts\example.tcl" + Delete "$SMPROGRAMS\BearTKat\Uninstall.lnk" + Delete "$SMPROGRAMS\BearTKat\Website.lnk" + Delete "$DESKTOP\BearTKat.lnk" + Delete "$SMPROGRAMS\BearTKat\BearTKat.lnk" + + RMDir /r "$SMPROGRAMS\BearTKat" + RMDir "$INSTDIR\scripts" + RMDir "$INSTDIR" + + DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" + DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" + SetAutoClose true +SectionEnd +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "Core install files" + !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "Example scripts" +!insertmacro MUI_FUNCTION_DESCRIPTION_END