#!/usr/bin/wish -f ## FIXME: Under Windows make this line the first line and look for # #!c:/tcl/bin/tclsh.exe -f ## Look for more lines with the FIXME: comment ## check the version number for mysql shared library and set it ## to match your version of mysql. # # copyright Nov 16, 2001, Marteinn Sverrisson, TF3MA\ # matti_at_raunvis_dot_hi_dot_is # This software is available under the terms of the GNU Public License # # $Id: MyMALog.tcl,v 2.14 2007/07/14 15:02:22 matti Exp matti $ # # Simple logging program for Radio Amateurs written in tcl/tk # by TF3MA. # # The original logfile was a flat text file, entries are separated by "|" # The current logfile is a TCL list, i.e. entries separated by a Space # and grouped via {} pair, this speed i/o and processing # Then the logfile was changed to use a MySQL database. # Now the size of the logfile is unimportant, but looking up old QSO's takes # a few seconds if the logfile is large (>30000 entries), this can be changed # by increasing the value of CHECK_LIMIT by pressing middle mouse button # # Usage: MyMALog.tcl # # when the first letters of the callsign have been entered # the program displayes the matching entries in the log # # History: # initial version 0.1: Þri Nóv 13 09:49:20 GMT 2001 # 0.1: Mið Nóv 14 20:49:45 GMT 2001 # Bætti við DXCC landaslista # 1.16: Lau Nóv 17 09:14:01 GMT 2001 # scrolling windows, improved packing of windows # Mán Nóv 26 22:18:42 GMT 2001 # Bætti við Band # 1.23 margar vidbætur # 11. dec 2001 # datastructure a la ADIF # 1.28 # prentun á formi sem hentar fyrir labelnation # 5.2.2003 # 1.34 New format for logfiles, now each line is # saved as a TCL list, with white space separator # and curly {} brackets for eliments # The conversion is automatic # # 1.38 Code cleanup, Del button added # 1.41 Info now displays in info window # 1.42 Popup asks for confirm, after edit # edit the logfilentry in the info window # as well as the one in the qsl window # middle mouse button on Pr button pops up a menu # to select what to print QSL, ADI or CBR # 1.44 Added an array of callsigns to speed lookup, mklist # 1.50 Added reports for DXCC etc and some statistics # 1.57 Added serial connection to K2, and rig_info # 1.69 Do not use serial port if busy, dxcc file read # 1.71 Use right mouse button to lookup Name, Qth, Call info # 1.72 Use right mouse button in info mod to lookup all contacts # to the selected country # ############################################################### # New version using MySQL database Nov 2003 # 1.16 All functions work as in the old version, I hope # 1.17 Fixing permission on *rc file. Put password on MySQL access # 1.19 Added multiple logbooks # 1.20 Use GMT data and time # 1.22 Zone info for CQ-WW, rigth mouse in Logmode menu # 1.23 Restore session upon start # 1.25 Rewritten contest processing, new format for rc-file # contest_id field # 1.28 Rewritten check_pre, added EQP contest mode # 1.33 mozilla-firefox # 1.34 Added Auto Date toggle, for entering from a paperlog. # 1.35 Added PTT # 1.36 FREQ restored from db, MY_CALL updated when rc-file edited # 1.39 Automatic connection to rig, when rig is turned on # ############################################################### # # 2.00 Using hamlib-tcl to get info from the rig # Only freq, mode and power level at the moment # K2 rig control and K2 cw keyer still work # DXCCLIST --- better match # 2.01 Skip printout of empty ADIF and CBR entries # 2.02 sql table name change from CALL to CALLSIGN # all instances of CALL changed to CALLSIGN # CALL is a reserved name in mysql 5 # Database must be dumped and table structure # (CALL --> CALLSIGN) changed before upgrading to mysql 5 # 2.3 in open_db, select if you are using ip og socket # added mysqlping watchdog, to prevent the server # from hanging up # 2.4 correct starting with empty database # 2.6 code cleanup # 2.8 better startup code and code cleanup # 2.9 code cleanup, new prenta_qsl # 2.11 Use hamlib with multiple programs # run (as root): "rpc.rigd -m 221 -r /dev/ttyS0 &" # and set RIG_ID = 1901 # 2.12 Rigth mouse click on RIG, toggles RANT on K2 ############# Install Instructions ############################# # # Install this program under any name, and make it executable (chmod 755)!! # it gets its installed name from "set programname [file tail [info script]]" # # The program reads a rc file: .${programname}rc # if the file does not exist the progam uses the names: # "logfiles" for the log directory and # ".${programname}.dat" for the logfile # # i.e. if the program is installed under the name "hamlog" # then the log is stored in the file ~/logfiles/hamlog.dat # # If separate logs are preferred for different operations # make symbolic links to the actual program with the prefered # logfile names without the .dat suffixt and you are done. # or use the rc file to set the logfile name. # # for example: ln -s MyMALog.tcl contest # when invoked as "contest" it reads the initfile .contestrc # # the rc file uses the following syntax, see .*rc file for full list: # # MY_CALL your_callsign # MYNAME your_name # QTH your_own_qth # ADDRESS your_mailing_address # CQZ your_cq_zone # IOTA your_iota_zone # ITUZ your_itu_zone # LIC your_licence_year # LATLONG your_latitud_and_longitude # GRIDSQUARE your_grid_locator # LOGDIR your_logdir_name # DATABASE your_database_name {your_logbook_name . . .} # LIBRARY your_library_dir # DXCC_FILE your_dxccfile_name # OFFSET where to start when looking up old QSO's # EQSL where to start when exporting eQSL # GUI_LANG the GUI language, is or en are currently supported # # dxcc list is used for looking up the country informations # # Download the DXCC file from\ # "http://www.arrl.org/files/infoserv/tech/dxcck2di.txt" # Install it in the LIBRARY directory, see the *rc file. # # Remember to install the "gcb" package for Linux # # The program uses Mozilla to lookup callsigns in qrz.com # ############## MySQL instructions: # # Remember to install the "mysqltcl" package on your computer # # On first time start the program will ask for your callsign. # and a password for the database. # To prepare the MySQL admin (root) has to make a database # for you, if your callsign is "TF3MA" then # your database name will be "TF3MA_logbook" # and if your user name is tf3ma, # then this is what has to be done: # # mysqadmin -u root -p create TF3MA_logbook # mysql -u root -p # mysql> grant all on TF3MA_logbook.* to tf3ma@localhost identified by\ # 'password'; # mysql> exit # # If you want to use different database name edit the rc file DATABASE\ # entry # and make sure you have all grants to that database # ############# ## On Linux uncomment the appropriate line, to match with your MySQL version ## load "/usr/lib/mysqltcl-2.30/libmysqltcl2.30.so" ## load "/usr/lib/mysqltcl-3.01/libmysqltcl3.01.so" #load "/usr/lib/mysqltcl-3.02/libmysqltcl3.02.so" # if {[exec find /usr/lib -type f -name libmysqltcl*.so] == {}} { set svar [tk_messageBox -message "libmysqltcl not found \n install\ mysqltcl and try again\n --- aborting" -type ok -icon error] exit } set libmysqltcl [exec find /usr/lib -type f -name libmysqltcl*.so] load "$libmysqltcl" if {[exec find /usr/lib -type f -name hamlibtcl*.so] == {}} { tk_messageBox -message "No hamlib found\nrunning without hamlib" -type ok\ -icon info set use_hamlib 0 update } { set hamlibtcl [exec find /usr/lib -type f -name hamlibtcl*.so] load "$hamlibtcl" Hamlib rig_set_debug $RIG_DEBUG_NONE set use_hamlib 1 } if {[catch {exec which gcb} svar]} { tk_messageBox -message "No gcb package" -type ok -icon info } ## FIXME:On Windows use the two next lines ## package require Tk ## package require Hamlib ## load "c:/tcl/lib/mysqltcl-2.50/mysqltcl.dll" set Rev "\$Revision: 2.14 $" # This is for the MATerm program. set MALog 1 # # first initialize some data structures # # How many characters before looking up old QSO's (>1 for speed), with the\ # limit set to 2, # it takes about 1 sec to lookup and display all QSO's with callsigns starting\ with # f.ex. "K2" when there are 30.000 entries in the log) # this on a 500MHz mobile AMD Athlon(tm) XP 1400+ set CHECK_LIMIT 1 #set font {-*-courier-demi-r-*-*-12-*} set font {-*-courier-bold-r-*-*-12-*} set programname [file tail [info script]] set Credit "$programname $Rev\n QSO logging program using MySQL\n written from\ scratch by TF3MA\n distributed under the GPL v2 Licence\n" set Help "\nSimple Help: Use the Mouse and the buttons or\nTAB -- for next\ entry F9 -- to log the QSO\n Callsign lookup:\n \%3 finds all calls with\ 3 in it\n" set loggrc .${programname}rc set refresh 10 set dog 0 set db_dog 0 set block 1 set val(Call) {} set tfreeze 0 set qrz_lookup 0 set auto_date 1 set serial_busy 0 set live_key 0 set rig_on 0 set rig_initstring "K22;AI2;AN;FA;FB;FR;FT;FW;GT;KS;LK;MD;NB;PA;PC;RA;RC;RD;XT;" # # Language specific texts # The Box texts, use for setting different languaes # Please note the length of the stings # # default database user # set filename(DB_USER) $env(USER) # set lang "en" set lang "is" set logbook_name(is) "Loggbók" set logbook_name(en) "Logbook" # The box texts set box_date(en) "Date" set box_date(is) "Dags" set box_time(is) "Tími" set box_time(en) "Time" set box_station(is) "Stöð kölluð" set box_station(en) "Station" set box_band(is) "Band" set box_band(en) "Band" set box_freq(en) "Freq" set box_freq(is) "Tíðni" set box_mode(is) "Teg" set box_mode(en) "Mode" set box_rst_sent(is) "Rst_sent" set box_rst_sent(en) "Rst_sent" set box_rst_rcvd(is) "Rst_mótt" set box_rst_rcvd(en) "Rst_rcvd" set box_qsl(is) "Qsl" set box_qsl(en) "Qsl" set box_name(is) "Nafn" set box_name(en) "Name" set box_qth(is) "Qth" set box_qth(en) "Qth" set box_rig(is) "Tæki" set box_rig(en) "Rig" set box_notes(is) "Athugas" set box_notes(en) "Notes" set box_time_off(is) "Endar" set box_time_off(en) "Ends" # The button texts and the last qso text set b_text_auto(is) "Sjálfv" set b_text_auto(en) "Auto" set b_text_manual(is) "Handv" set b_text_manual(en) "Manual" set b_text_time(is) "Tími" set b_text_time(en) "Time" set b_text_log(is) "Skrá" set b_text_log(en) "Log" set b_text_clear(is) "Hreinsa" set b_text_clear(en) "Clear" set b_text_file(is) "Sýsl" set b_text_file(en) "File" set b_text_time_off(is) "Endar" set b_text_time_off(en) "Ends" set b_text_station(is) "Stöð" set b_text_station(en) "Station" set b_text_sent(is) "Se" set b_text_sent(en) "Se" set b_text_recvd(is) "Mó" set b_text_recvd(en) "Rc" set b_text_print(is) "Pr" set b_text_print(en) "Pr" set b_text_upd(is) "Tölfr" set b_text_upd(en) "Info" set b_text_edit(is) "Edit" set b_text_edit(en) "Edit" set b_text_info(is) "->" set b_text_info(en) "Info" set b_text_last(is) "Logg #" set b_text_last(en) "QSO #" # FREQ set FREQ(160m) 1800.000 set FREQ(80m) 3500.000 set FREQ(40m) 7000.000 set FREQ(30m) 10100.000 set FREQ(20m) 14000.000 set FREQ(17m) 18100.000 set FREQ(15m) 21000.000 set FREQ(12m) 24900.000 set FREQ(10m) 28000.000 set FREQ(6m) 54000.000 set FREQ(2m) 144000.000 set tmode $b_text_auto($lang) # proc clr_callinfo {} { global callinfo set callinfo(dxcc) {-1} set callinfo(country) {} set callinfo(cont) {} set callinfo(itu) {} set callinfo(zone) {} set callinfo(prefix) {} } clr_callinfo # # Here is the structure of the logfile and the entries to display # set logstructure {MY_CALL QSO_DATE TIME_ON CALLSIGN BAND MODE RST_SENT STX\ RST_RCVD\ SRX CQZ ITUZ STATE QSL_SENT QSLSDATE QSL_RCVD QSLRDATE NAME QTH TIME_OFF RIG\ FREQ TX_PWR RX_PWR CONTEST_ID DXCC PFX CONT COUNTRY CNTY IOTA VE_PROV\ QSL_VIA NOTES ANT} set db_logstructure\ {MY_CALL,QSO_DATE,TIME_ON,CALLSIGN,BAND,MODE,RST_SENT,STX,RST_RCVD,\ SRX,CQZ,ITUZ,STATE,QSL_SENT,QSLSDATE,QSL_RCVD,QSLRDATE,NAME,QTH,TIME_OFF,RIG,\ FREQ,TX_PWR,RX_PWR,CONTEST_ID,DXCC,PFX,CONT,COUNTRY,CNTY,IOTA,VE_PROV,\ QSL_VIA,NOTES,ANT} set display {QSO_DATE TIME_ON CALLSIGN BAND MODE RST_SENT STX RST_RCVD\ SRX FREQ QSL_SENT QSL_RCVD NAME QTH RIG TX_PWR CONTEST_ID} set db_todisplay {NUM,DATE_FORMAT(QSO_DATE,'%d %b\ %Y'),TIME_FORMAT(TIME_ON,'%H:%i'),CALLSIGN,BAND,MODE,RST_SENT,STX,RST_RCVD,\ SRX,FREQ,QSL_SENT,QSL_RCVD,NAME,QTH,RIG,TX_PWR,CONTEST_ID,DXCC,COUNTRY} set db_last_todisplay {DATE_FORMAT(QSO_DATE,'%d %b'), TIME_FORMAT(TIME_ON,'%H:%i'),CALLSIGN,BAND,MODE,RST_SENT,STX,RST_RCVD,\ SRX,FREQ,QSL_SENT,QSL_RCVD,NAME,QTH,RIG,TX_PWR,CONTEST_ID,DXCC,COUNTRY} set db_info_todisplay {NUM,DATE_FORMAT(QSO_DATE,'%d %b\ %Y'),TIME_FORMAT(TIME_ON,'%H:%i'),CALLSIGN,BAND,MODE,RST_SENT,STX,RST_RCVD,\ SRX,FREQ,QSL_SENT,DATE_FORMAT(QSLSDATE,'%d %b\ %Y'),QSL_RCVD,DATE_FORMAT(QSLRDATE,'%d %b\ %Y'),NAME,QTH,RIG,TX_PWR,CONTEST_ID,DXCC,COUNTRY} foreach i $logstructure { set log_index($i) [lsearch -exact $logstructure $i] #puts stderr "$log_index($i) $i" } # # layout for dxcc listing # # set bands {160m 80m 40m 30m 20m 17m 15m 12m 10m 6m 2m} array set band_index {160m 0 80m 1 40m 2 30m 3 20m 4 17m 5 15m 6 12m 7 10m 8\ 6m 9 2m 10} # # The structure of the cabrillo file header # set cab_struct {CALLSIGN CATEGORY CONTEST ARRL-SECTION CLAIMED-SCORE\ NAME ADDRESS SOAPBOX} # # The structure of the rc file # set rc_struct { {MY_CALL your_callsign}\ {MYNAME your_name}\ {PREFIX your_callsign_prefix}\ {QTH your_own_qth}\ {NAME your_full_name}\ {ADDRESS {your_mailing_address}}\ {CQZ your_cq_zone}\ {IOTA your_iota_zone}\ {ITUZ your_itu_zone}\ {LIC your_licence_year}\ {LATLONG 64N22W}\ {GRIDSQUARE your_grid_locator}\ {LOGDIR logfiles}\ {DATABASE {my_logbook logbook}}\ {LIBRARY {}}\ {DXCC_FILE dxcck2di.txt}\ {OFFSET 1}\ {EQSL 1}\ {GUI_LANG en}\ {F1_QSO {cq cq cq de $filename(MY_CALL) k}}\ {F1_CONTEST {test de $filename(MY_CALL) test k}}\ {F2_QSO {$log(RST_SENT)}}\ {F2_CONTEST {5nn $log(STX)}}\ {F3_QSO {73}}\ {F3_CONTEST {tu}}\ {F4 {$filename(MY_CALL)}}\ {F5 {$log(CALLSIGN)}}\ {F6 {$log(CALLSIGN) qso b4}}\ {F7 {$log(STX)}}\ {F8 {agn}}\ {RIG {my_rig1 my_rig2 {my rig 3} }}\ {RIG_ID {221}}\ {ANT {my_ant1 my_ant2 {my ant 3} }}\ {TX_PWR {1 5 10 50 100 500 1k}}\ {MODE {SSB CW RTTY BPSK31 QBSK31 MFSK16 SSTV FM AM}}\ {BAND {160m 80m 40m 30m 20m 17m 15m 12m 10m 6m 2m}}\ {CONTEST_ID {{QSO QSO} {CQ-WW CQZ} {CQ-WPX SER} {CQ-160 PFX} {ARRL-10 SER}\ {ARRL-160 QSO} {ARRL-DX PWR} {IARU ITUZ} {WAE LIC} {SAC SER} {JIDX CQZ}\ {SPDX SER} {Contest SER} {STX STX} {EQP QSO}}}\ {SERIAL_PORT {/dev/ttyS0}}\ {DB_USER $env(USER)}\ {DB_PASSWORD {}}\ } # # initialize the log array # foreach x $logstructure { set log($x) {} } # set log(MODE) SSB set log(RIG) K2 set log(ANT) Dipole set log(TX_PWR) 100 set log(BAND) 20m set log(FREQ) $FREQ($log(BAND)) set log(STX) 1 set log(CONTEST_ID) QSO set tabmode "QSO" # # make the rcfile if it is not there and put in default values # proc make_rc {} { global loggrc env filename rc_struct programname refresh rc_ok set rc_ok 0 toplevel .rc frame .rc.e label .rc.e.l -text "Making $env(HOME)/$loggrc " label .rc.e.lc -text "Enter your callsign" entry .rc.e.c -textvariable callsign -width 25 -relief sunken label .rc.e.lu -text "Enter your database username" entry .rc.e.u -textvariable $filename(DB_USER) -width 25 -relief sunken label .rc.e.lp -text "Enter your database password" entry .rc.e.p -textvariable db_password -width 25 -relief sunken button .rc.e.x -text OK -command { # callsign min 3 chars if {[string length $callsign] < 3} { focus .rc.e.c }\ elseif {[string length $db_password] == 0} { focus .rc.e.p } { set file [open $env(HOME)/$loggrc w 0600] set callsign [string toupper $callsign] append database $callsign "_logbook" foreach rcline $rc_struct { switch [lindex $rcline 0] { "MY_CALL" { puts $file "MY_CALL $callsign" } "DATABASE" { puts $file "DATABASE {$database logbook}" } "DB_USER" { puts $file "DB_USER $filename(DB_USER)" } "DB_PASSWORD" { puts $file "DB_PASSWORD $db_password" } "LIBRARY" { puts $file "LIBRARY $env(HOME)/logfiles" } default { puts $file $rcline } } #puts $file "[lindex $rcline 0] {[lindex $rcline 1]}" } flush $file close $file set rc_ok 1 update destroy .rc } } pack .rc.e.l .rc.e.lc .rc.e.c .rc.e.lu .rc.e.u .rc.e.lp .rc.e.p .rc.e.x\ -side top -padx .25 pack .rc.e focus .rc.e.c while {$rc_ok == 0} { after $refresh update } } # # open the rcfile and read it, if the rcfile does not exist use default # names for the logdir and the logfile # proc read_rc {} { global loggrc env filename contests log prefix if {[file readable $env(HOME)/$loggrc] == 0} { #puts "Missing: $env(HOME)/$loggrc" #puts "I am now making your rc file" #puts "please edit the rcfile: \"$env(HOME)/$loggrc\"" make_rc } puts stderr "Reading $loggrc" set file [open $env(HOME)/$loggrc r] set rcinfo [split [read $file] \n] array set filename [join $rcinfo] # puts [array get filename] puts "innlestri loggrc fyrir $filename(MY_CALL) lokið" array set contests [join $filename(CONTEST_ID)] set log(MY_CALL) $filename(MY_CALL) set prefix $filename(PREFIX) } read_rc set c_sel $filename(OFFSET) set lang $filename(GUI_LANG) wm title . "$filename(MY_CALL) $logbook_name($lang) -- written by TF3MA -- $Rev" # # make the logdir if it does not exists # set logdir $env(HOME)/$filename(LOGDIR) if {[file isdirectory $logdir] == 0 && [file isfile $logdir] == 0} { file mkdir $logdir } # # Read date and time from computer clock and display in gmt # proc do_time {} { global log set log(QSO_DATE) [clock format [clock seconds] -format %Y%m%d -gmt 1] set log(TIME_ON) [clock format [clock seconds] -format %H%M%S -gmt 1] set log(TIME_OFF) "" } # # Use ip or socket to connect to database, select one # open_db returns the databasehandle # proc open_db {dbname logbooks user password} { set db {} set db_make "\nAsk your database admin to do the following:\n mysql>\ create database $dbname ;\n mysql> grant all on $dbname.* to\ $user@localhost identified by \'$password\';" puts stderr "Connecting to server" if [catch {mysqlconnect -socket "/var/run/mysqld/mysqld.sock" -user $user\ -password $password} db] { set svar [tk_messageBox -message "$db\n\nuser: $user\npassword:\ $password\n$db_make" -type ok -icon error] puts stderr $db exit } set databases [mysqlinfo $db databases] if {[lsearch -exact $databases $dbname] == -1} { puts stderr "Opening database" if [catch {mysqlexec $db "create database $dbname"} res] { set svar [tk_messageBox -message "$res\n\n $db_make" -type ok -icon error] puts stderr "$res" puts stderr "$db_make" exit } } mysqluse $db $dbname if {$logbooks == ""} { set logbooks logbook } set svar [mysqlinfo $db tables] foreach table $logbooks { if {[lsearch -exact $svar $table] == -1} { puts stderr "Making new logbooks" create_logbook $db $table } } return $db } proc create_logbook {db logbook} { set svar [mysqlexec $db "CREATE TABLE $logbook ( NUM bigint(20) NOT NULL\ auto_increment, MY_CALL varchar(15) DEFAULT '' NOT NULL, QSO_DATE date\ NOT NULL, TIME_ON time NOT NULL, CALLSIGN varchar(15) DEFAULT '' NOT\ NULL, BAND varchar(7) DEFAULT '' NOT NULL, MODE varchar(7) DEFAULT ''\ NOT NULL, RST_SENT varchar(3), STX varchar(6), RST_RCVD varchar(3), \ SRX varchar(6), CQZ varchar(2), ITUZ varchar(2), STATE varchar(7), \ QSL_SENT char(1) DEFAULT 'I', QSLSDATE date, QSL_RCVD char(1) DEFAULT\ 'I', QSLRDATE date, NAME varchar(15), QTH varchar(50), TIME_OFF time,\ RIG varchar(15), FREQ varchar(15), TX_PWR float(10,2), RX_PWR\ float(10,2), CONTEST_ID varchar(15) DEFAULT 'QSO' NOT NULL, DXCC\ varchar(7), PFX varchar(7), CONT varchar(15), COUNTRY varchar(40), CNTY\ varchar(15), IOTA varchar(7), VE_PROV varchar(15), QSL_VIA varchar(15),\ NOTES varchar(50), ANT varchar(15), PRIMARY KEY (NUM), KEY NUM (NUM),\ KEY MY_CALL (MY_CALL), KEY QSO_DATE (QSO_DATE), KEY CALLSIGN\ (CALLSIGN), KEY BAND (BAND), KEY MODE (MODE), KEY DXCC (DXCC) );"] } # # restore last session # proc restore_session {} { global log db logbook set max [mysqlsel $db "select MAX(NUM) from $logbook;" -flatlist] if {$max != "{}"} { set log(CONTEST_ID) [mysqlsel $db "select CONTEST_ID from $logbook\ where NUM =\'$max\';" -flatlist] set log(BAND) [mysqlsel $db "select BAND from $logbook where NUM\ =\'$max\';" -flatlist] set log(FREQ) [mysqlsel $db "select FREQ from $logbook where NUM\ =\'$max\';" -flatlist] set log(MODE) [mysqlsel $db "select MODE from $logbook where NUM\ =\'$max\';" -flatlist] set log(RIG) [mysqlsel $db "select RIG from $logbook where NUM\ =\'$max\';" -flatlist] set log(TX_PWR) [mysqlsel $db "select TX_PWR from $logbook where NUM\ =\'$max\';" -flatlist] if {$log(CONTEST_ID) != "QSO"} { set log(RST_SENT) [mysqlsel $db "select RST_SENT from $logbook\ where NUM =\'$max\';" -flatlist] set log(STX) [mysqlsel $db "select STX from $logbook where NUM\ =\'$max\';" -flatlist] } } } # # read in the dxcc file used to lookup countries and zones # proc dxcc_inn {} { global filename dxcclist if {$filename(DXCC_FILE) != {}} { if {[file readable $filename(LIBRARY)/$filename(DXCC_FILE)] == 1} { puts stderr "Reading DXCC file" set listfile [open $filename(LIBRARY)/$filename(DXCC_FILE) r] set list [split [read $listfile] \n] close $listfile set i 0 foreach line $list { if {[regexp -- "^---.*" $line]} { incr i } { if {[expr {$i >= 1}]} { array set dxcclist [list [array size dxcclist]\ "[split $line :]"] } } } puts stderr "dxcc: [array size dxcclist]" } { puts stderr "Can not open DXCC file" set svar [tk_messageBox -message "DXCC file not installed\nrunning\ without DXCC file" -type ok -icon info] } } { puts stderr "No DXCC file" set svar [tk_messageBox -message "No DXCC file defined\nedit the rc\ file" -type ok -icon info] } } # # Make regular expressions out of all prefixes # and put in regexplist array, index is the same index of dxcclist # so it can be used to printout dxcc entries # proc mkreg {} { global dxcclist regexplist deletedlist for {set i 0} {$i < [array size dxcclist]} {incr i} { set pre {} set rlist {} set deletedlist($i) 0 append pre [lindex $dxcclist($i) 0] if {$pre == {}} { set pre ~ } # # deleted counries are looked up # while {[set l [string first * $pre]] > 0} { set deletedlist($i) 1 # puts stderr "$l : $pre" set pre [string replace $pre $l $l] # puts stderr "$l : $pre" } set aukapre [concat [split [lindex $dxcclist($i) 8] ,] [split\ [lindex $dxcclist($i) 9] ,]] set pre "^$pre" lappend rlist $pre foreach auka $aukapre { if {$auka != {}} { set auka "^$auka" } while {[set l [string first ~ $auka]] > 0} { set auka [string replace $auka $l $l] # puts stderr "$l:$auka" } while {[set l [string first _ $auka]] > 0} { set auka [string replace $auka $l $l \[0-9\]] # puts stderr $auka } if {[string index $auka 3] == "-"} { set rreg {} append rreg ^[string index $auka 1] \[[string index $auka\ 2]-[string index $auka 5]\] lappend rlist $rreg }\ elseif {[string index $auka 4] == "-"} { set rreg {} append rreg ^[string index $auka 1][string index $auka 2]\ \[[string index $auka 3]-[string index $auka 7]\] lappend rlist $rreg } { set rlist [concat $rlist $auka] } set reg [join $rlist |] } set reg [join $rlist |] # puts "$reg" set regexplist($i) $reg } } # # clear the log entries after adding a new entry to the logfile # proc upphaf {clear} { global log tfreeze prefix val b_text_auto lang tmode auto filename\ contests tabmode set tfreeze 0 set log(QSL_SENT) I set log(QSL_RCVD) I set log(CALLSIGN) "" set log(NAME) "" set log(QTH) "" set log(SRX) {} if {$log(MODE) == "CW"} { set log(RST_SENT) 599 set log(RST_RCVD) 599 } { set log(RST_SENT) 59 set log(RST_RCVD) 59 } switch -- $contests($log(CONTEST_ID)) { QSO { set log(SRX) {} set log(RST_SENT) {} set log(RST_RCVD) {} set log(STX) {} set tabmode "QSO" } NIL { set log(SRX) {} set log(RST_SENT) {} set log(RST_RCVD) {} set log(STX) {} set tabmode "CONT" } SER { if {$log(STX) == {}} { set log(STX) 1 } { if {$clear == 1} { incr log(STX) } } set tabmode "CONT" } PFX { set log(STX) $filename(PREFIX) set tabmode "CONT" } CQZ { set log(STX) $filename(CQZ) set tabmode "CONT" } LIC { set log(STX) $filename(LIC) set tabmode "CONT" } ITUZ { set log(STX) $filename(ITUZ) set tabmode "CONT" } PWR { set log(STX) 100 set tabmode "CONT" } UTIL { set log(RST_SENT) {} set log(RST_RCVD) {} if {$log(STX) == {}} { set log(STX) 1 } { if {$clear == 1} { incr log(STX) } } set tabmode "UTIL" } default { set tabmode "CONT" } } set tmode $b_text_auto($lang) focus .call.stod } # # read in the adif logfile and append it to the current logfile # adif file fields have the same name as the log array fields. # proc lesa_adif {filename} { global log c_sel dxcc_gluggi set adif_file [open $filename r] set safn [read $adif_file] # get rid of all NL and CR and TAB regsub -all {[\n\r\t]} $safn {} ssafn set first [string index $ssafn 0] if {$first != "<"} { # puts stderr "header" regsub -all -nocase {} $ssafn "\n" safn set ssafn [split $safn \n] set header [lindex $ssafn 0] set body [lindex $ssafn 1] # puts stderr $header # puts stderr "header ends" } { # puts stderr "no header" set body $ssafn } regsub -all -nocase {} $body "\n" safn # puts stderr $safn set num 0 foreach line [split $safn \n] { if {[expr ($num % 100)] == 0} { $dxcc_gluggi delete 1.0 end $dxcc_gluggi insert end "Reading: $num" update } incr num while {[string length $line] != 0} { set j [string first {<} $line] incr j set l [string first {:} $line] incr l -1 set m [string first {>} $line] incr m -1 set n [string length $line] set fname [string range $line $j $l] set fname [string toupper $fname] incr l +2 set w [string range $line $l $m] incr w -1 incr m 2 set line [string range $line $m $n] set fval [string range $line 0 $w] set log($fname) $fval incr w # puts stdout "$fname $fval" set line [string range $line $w $n] } if {[string length $log(TIME_ON)] == 4} { append log(TIME_ON) "00" } if {$log(CALLSIGN) != ""} { set year [string range $log(QSO_DATE) 0 3] check_country $c_sel $log(CALLSIGN) $year add_db_entry } } update } # # Statistics # proc get_db_info {firstnum} { global db callinfo country_gluggi logdir info_gluggi logbook set nr_entries [mysqlsel $db "select COUNT(NUM) from $logbook;" -flatlist] set max [mysqlsel $db "select MAX(NUM) from $logbook;" -flatlist] set date_max [mysqlsel $db "select DATE_FORMAT(QSO_DATE,'%d %b %Y') from\ $logbook where NUM = \'$max\';" -flatlist] set date_start [mysqlsel $db "select DATE_FORMAT(QSO_DATE,'%d %b %Y') from\ $logbook where NUM = \'$firstnum\';" -flatlist] set dxcc [mysqlsel $db "select COUNT(DISTINCT DXCC) from $logbook where\ NUM >= \'$firstnum\'" -list] set cfmd [mysqlsel $db "select COUNT(DISTINCT DXCC) from $logbook where\ QSL_RCVD = \"Y\" && NUM >= \'$firstnum\'" -list] set pfx [mysqlsel $db "select COUNT(DISTINCT PFX) from $logbook where NUM\ >= \'$firstnum\'" -list] set ituz [mysqlsel $db "select COUNT(DISTINCT ITUZ) from $logbook where\ NUM >= \'$firstnum\'" -list] set cqz [mysqlsel $db "select COUNT(DISTINCT CQZ) from $logbook where NUM\ >= \'$firstnum\'" -list] set cont [mysqlsel $db "select COUNT(DISTINCT CONT) from $logbook where\ NUM >= \'$firstnum\'" -list] set dxcc_ssb [mysqlsel $db "select COUNT(DISTINCT DXCC) from $logbook\ where (MODE = \"SSB\" || MODE = \"USB\" || MODE = \"LSB\") && NUM >=\ \'$firstnum\'" -list] set dxcc_ssb_qsl [mysqlsel $db "select COUNT(DISTINCT DXCC) from $logbook\ where (MODE = \"SSB\" || MODE = \"USB\" || MODE = \"LSB\") && QSL_RCVD =\ \"Y\" && NUM >= \'$firstnum\'" -list] set dxcc_cw [mysqlsel $db "select COUNT(DISTINCT DXCC) from $logbook where\ MODE = \"CW\" && NUM >= \'$firstnum\'" -list] set dxcc_cw_qsl [mysqlsel $db "select COUNT(DISTINCT DXCC) from $logbook\ where MODE = \"CW\" && QSL_RCVD = \"Y\" && NUM >= \'$firstnum\'" -list] $country_gluggi delete 1.0 end if {$max != "{}"} { $country_gluggi insert end "QSO's: [expr {($max - $firstnum + 1)}]\ From $date_start to $date_max\n" $country_gluggi insert end "Countries: $dxcc (334), SSB: $dxcc_ssb,\ CW: $dxcc_cw\n" $country_gluggi insert end "Confirmed: $cfmd (334), SSB:\ $dxcc_ssb_qsl, CW: $dxcc_cw_qsl\n" $country_gluggi insert end "Zones: $cqz (40)\n" $country_gluggi insert end "ITU: $ituz (90)\n" $country_gluggi insert end "Continents: $cont (6)\n" $country_gluggi insert end "Prefixes: $pfx\n" } } # # make the dxcc printout line # proc dxcc_line {firstnum name} { global db band_index logbook set dxcc_band [mysqlsel $db "select DXCC,BAND,QSL_RCVD from $logbook where\ DXCC = \'$name\' && NUM >= \'$firstnum\' group by DXCC,BAND,QSL_RCVD;"\ -list] set qsl_lina [list "-" "-" "-" "-" "-" "-" "-" "-" "-" "-" "-"] #puts $qsl_lina foreach band_cont $dxcc_band { set dxcc [lindex $band_cont 0] set band [lindex $band_cont 1] set qsl [lindex $band_cont 2] # puts "$band_index($band) $qsl" set qsl_lina [lreplace $qsl_lina $band_index($band) $band_index($band)\ $qsl] } return [join $qsl_lina] } # # Worked DXCC list # proc get_db_dxccinfo {firstnum} { global db callinfo country_gluggi logdir info_gluggi logbook set infofile [open $logdir/info.txt w] $info_gluggi delete 0 end set printstring " 80m 30m 17m 12m 6m" puts $infofile $printstring $info_gluggi insert end $printstring set printstring "DXCC Country 160m|40m|20m|15m|10m| 2m" puts $infofile $printstring $info_gluggi insert end $printstring set printstring " | | | | | | | | | | |" puts $infofile $printstring $info_gluggi insert end $printstring set dxcc_name [mysqlsel $db "select DISTINCT(DXCC) from $logbook where NUM\ >= \'$firstnum\' group by DXCC" -list] foreach name $dxcc_name { if {$name != "{}"} { set dxcc_country [mysqlsel $db "select COUNTRY from $logbook where\ DXCC = \'$name\' group by DXCC" -flatlist] set dxcc_country [join $dxcc_country] set printlist [dxcc_line $firstnum $name] set printstring [format "%-5s %-27s %s" $name $dxcc_country\ $printlist] $info_gluggi insert end $printstring puts $infofile $printstring } } close $infofile } # # make the zone printout line # proc zone_line {firstnum name contest} { global db band_index logbook if {$name < 10} { append n "0" $name set name $n } set zone_band [mysqlsel $db "select BAND,QSL_RCVD from $logbook where SRX\ = \'$name\' && NUM >= \'$firstnum\' && CONTEST_ID = \'$contest\' group\ by BAND,QSL_RCVD;" -list] set qsl_lina [list "-" "-" "-" "-" "-" "-" "-" "-" "-" "-" "-"] foreach band_cont $zone_band { set band [lindex $band_cont 0] set qsl [lindex $band_cont 1] # puts "$band_index($band) $qsl" set qsl_lina [lreplace $qsl_lina $band_index($band) $band_index($band)\ $qsl] } return [join $qsl_lina] } # # Worked ZONES list # proc get_db_zoneinfo {firstnum contest} { global db callinfo country_gluggi logdir info_gluggi logbook $info_gluggi delete 0 end set printstring " 80m 30m 17m 12m 6m" $info_gluggi insert end $printstring set printstring "ZONE 160m|40m|20m|15m|10m| 2m" $info_gluggi insert end $printstring set printstring " | | | | | | | | | | |" $info_gluggi insert end $printstring for {set name 1} {$name <= 40} {incr name} { set printlist [zone_line $firstnum $name $contest] set printstring [format "%-5s %-3s %s" $name " " $printlist] $info_gluggi insert end $printstring } } # # zone info for CW-WW # proc zone {firstnum} { global db dxcc_gluggi logbook log set zone_list [mysqlsel $db "select DISTINCT(SRX) from $logbook where NUM\ >= \'$firstnum\' && CONTEST_ID = \'CQ-WW\' && BAND = \'$log(BAND)\';"\ -flatlist] for {set i 1} {$i <= 40} {incr i} { set zone_entry($i) " -- " } foreach zone $zone_list { if {[string index $zone 0] == "0"} { set zone [string index $zone 1] } if {$zone < 10} { set zone_entry($zone) " $zone " } { set zone_entry($zone) " $zone " } } $dxcc_gluggi delete 1.0 end for {set i 1} {$i <= 40} {incr i} { $dxcc_gluggi insert end "$zone_entry($i)" if {[expr ($i % 10)] == 0} { $dxcc_gluggi insert end "\n" } } } # # tail_db_log -- display the 50 last entries in the log # proc tail_db_log {} { global last_gluggi db db_last_todisplay logbook $last_gluggi delete 1.0 end set max [mysqlsel $db "select MAX(NUM) from $logbook;" -flatlist] if {$max == "{}"} { set max 0 } if {$max > 50} { incr max -50 } { set max 0 } set svar [mysqlsel $db "select $db_last_todisplay from $logbook where NUM\ > $max group by NUM DESC;" -list] foreach line $svar { $last_gluggi insert 1.0 \n $last_gluggi insert 1.0 $line } } # check_db_entry, lookup the callsign/name for the entered callsign/name # as soon as the first character of the callsign is entered # start from entry sel # proc check_db_entry {c_sel to_check CNQ mode} { global info_gluggi db db_todisplay logbook if {[string length $to_check] >= 1} { $info_gluggi delete 0 end switch $mode { "like" { set svar [mysqlsel $db "select $db_todisplay from $logbook\ where $CNQ like \"$to_check%\" && NUM >= \'$c_sel\' ORDER BY\ QSO_DATE;" -list] } "equal" { if {$CNQ != "DXCC"} { set to_check [mysqlsel $db "select $CNQ from $logbook\ where NUM = \"$to_check\";" -list] } set svar [mysqlsel $db "select $db_todisplay from $logbook\ where $CNQ = \"$to_check\" && NUM >= \'$c_sel\';" -list] } } foreach line $svar { $info_gluggi insert end [join $line] } } } # # check_pre --- return the call, prefix and ext of call/pre/ext or pre/call/ext # proc check_pre {callsign} { set comp [split $callsign /] set part0 [lindex $comp 0] set part1 [lindex $comp 1] set part2 [lindex $comp 2] set call {} set prefix {} set ext {} #puts "$callsign $part0 $part1 $part2\n" #puts "$callsign\n" if {[expr {[string length $part0] >= [string length $part1]}]} { set call $part0 } { set call $part1 } if {[regexp {^[A-Z].} $part0 prefix] == 1} { # puts stderr "0: $prefix" } if {[regexp {^[A-Z].*[0-9]} $part0 prefix] == 1} { # puts stderr "1: $prefix" } if {[regexp {^[A-Z].[0-9]*} $part0 prefix] == 1} { # puts stderr "2: $prefix" } if {[regexp {^[0-9][A-Z]} $part0 prefix] == 1} { # puts stderr "3: $prefix" } if {[regexp {^[0-9].[A-Z]*[0-9]} $part0 prefix] == 1} { # puts stderr "4: $prefix" } if {[regexp {^[0-9].[A-Z]*[0-9][0-9]} $part0 prefix] == 1} { # puts stderr "5: $prefix" } if {([string length $part1] == 1) &&([regexp {[0-9]} $part1])} { regsub {[0-9]} $prefix $part1 prefix # puts stderr "6: $prefix" } if {[expr {[string length $part1] <= [string length $part0]}]} { if {[regexp {^[A-Z].} $part1 prefix] == 1} { # puts stderr "7: $prefix" } if {[regexp {^[A-Z].*[0-9]} $part1 prefix] == 1} { # puts stderr "8: $prefix" } if {[regexp {^[0-9].[A-Z]*[0-9]} $part1 prefix] == 1} { # puts stderr "9: $prefix" } } if {[regexp {^[P|M|AM|MM|QRP]} $part1] == 1} { set ext $part1 } { set ext $part2 } return "$call $prefix $ext" } # # check_country, lookup the country in the DXCC list # proc check_country {firstnum callsign qsoyear} { global dxcc_gluggi country_gluggi dxcclist regexplist deletedlist dist\ callinfo info_array set prefix {} clr_callinfo if {[string length $callsign] >= 1} { $country_gluggi delete 1.0 end $dxcc_gluggi delete 1.0 end set flag 0 set svar [check_pre $callsign] set call [lindex $svar 0] set prefix [lindex $svar 1] set callinfo(prefix) [lindex $svar 1] #gives a better match to dxcc list DXCCLIST if {[string compare $call $callsign] == 0} { set prefix $call } for {set k 0} {$k < [array size regexplist]} {incr k} { if {[expr {$qsoyear < 2000}] || $deletedlist($k) == 0} { if {[regexp -- $regexplist($k) $prefix match]} { set cntry [lindex $dxcclist($k) 0] #puts stdout "$match: $cntry" $country_gluggi insert end $dxcclist($k) $country_gluggi insert end \n if {$match == $cntry} { set flag 0 } if {($flag == 0) && [regexp -- $cntry\ [lindex $dxcclist($k) 0]]} { set callinfo(dxcc) [lindex $dxcclist($k) 0] set callinfo(country) [lindex $dxcclist($k) 1] set callinfo(cont) [lindex $dxcclist($k) 2] set callinfo(itu) [lindex $dxcclist($k) 3] set callinfo(zone) [lindex $dxcclist($k) 4] if {$match == $cntry} { set flag 1 } # puts stderr "$callsign : $regexplist($k) :\ $match" # puts stderr [array get callinfo] #set flag 1 #if {[expr [string length $cntry] > 1] } {set flag 1} } # # calculate the distance and bearing to the countrie # set Long [lindex $dxcclist($k) 6] set Lat [lindex $dxcclist($k) 7] $country_gluggi insert end \n $country_gluggi insert end [dist $Long $Lat] $country_gluggi insert end \n $dxcc_gluggi delete 1.0 end set printstring " 160m|40m|20m|15m|10m| 2m" $dxcc_gluggi insert end $printstring $dxcc_gluggi insert end \n set printlist [dxcc_line $firstnum $callinfo(dxcc)] set printstring [format "%-5s %s" $callinfo(dxcc)\ $printlist] $dxcc_gluggi insert end $printstring } } } } } # # qrz --- lookup the callsign # proc qrz {callsign} { global qrz_lookup if {$qrz_lookup == 1} { exec mozilla-firefox\ -remote "openurl(http://www.qrz.com/callsign/$callsign)" } } # # append_info, append country info to the logfile # proc append_info {} { global log callinfo if {($log(CALLSIGN) != "")} { set log(DXCC) $callinfo(dxcc) set log(CQZ) $callinfo(zone) set log(ITUZ) $callinfo(itu) set log(CONT) $callinfo(cont) set log(COUNTRY) $callinfo(country) set log(PFX) $callinfo(prefix) } } # # add a new entry to the database # proc add_db_entry {} { global logstructure log db infoentry db_info_todisplay tmode lang\ b_text_auto b_text_manual auto_date logbook val append_info set max [mysqlsel $db "select MAX(NUM) from $logbook;" -flatlist] if {$max == "{}"} { set max 0 } incr max append newentry \'$max\' foreach i $logstructure { append newentry ,\'$log($i)\' } #puts $newentry mysqlexec $db "INSERT into $logbook VALUES ($newentry)" set max [mysqlsel $db "select MAX(NUM) from $logbook;" -flatlist] set infoentry [mysqlsel $db "select $db_info_todisplay from $logbook where\ NUM = \"$max\";" -flatlist] #puts "$max $infoentry" upphaf 1 set val(Num) [lindex $infoentry 0] set val(Call) [lindex $infoentry 3] tail_db_log if {$auto_date == 1} { set tmode $b_text_auto($lang) focus .call.stod } { set tmode $b_text_manual($lang) focus .day.dag } } # # show_info show DXCC and database info # proc show_info {} { global c_sel filename logbook country_gluggi dxcc_gluggi log $country_gluggi delete 1.0 end $country_gluggi insert end "Processing the logfile -- please wait" update get_db_info $c_sel switch $log(CONTEST_ID) { CQ-WW { get_db_zoneinfo $c_sel CQ-WW } default { get_db_dxccinfo $c_sel } } tail_db_log $dxcc_gluggi delete 1.0 end $dxcc_gluggi insert end "Using Database: [lindex $filename(DATABASE) 0]\n" $dxcc_gluggi insert end "Using logbook named: $logbook" } # # get db entries to print # proc get_db_prent {val} { global db db_logstructure prent logbook set prent(MY_CALL) [mysqlsel $db "SELECT MY_CALL from $logbook where NUM\ =\'$val\';" -flatlist] set prent(CALLSIGN) [mysqlsel $db "SELECT CALLSIGN from $logbook where NUM\ =\'$val\';" -flatlist] set prent(QSO_DATE) [mysqlsel $db "SELECT DATE_FORMAT(QSO_DATE,'%d %b %Y')\ from $logbook where NUM =\'$val\';" -flatlist] set prent(QSO_DATE) [join $prent(QSO_DATE)] set prent(QSL_RCVD) [mysqlsel $db "SELECT QSL_RCVD from $logbook where NUM\ =\'$val\';" -flatlist] set prent(TIME_ON) [mysqlsel $db "SELECT TIME_FORMAT(TIME_ON,'%H:%i') from\ $logbook where NUM =\'$val\';" -flatlist] set prent(BAND) [mysqlsel $db "SELECT BAND from $logbook where NUM\ =\'$val\';" -flatlist] set prent(MODE) [mysqlsel $db "SELECT MODE from $logbook where NUM\ =\'$val\';" -flatlist] set prent(RST_SENT) [mysqlsel $db "SELECT RST_SENT from $logbook where NUM\ =\'$val\';" -flatlist] } # # Print out the selected QSL entry and append it to qsl.txt and qsl.csv # print a SWL confirmation # proc prenta_qsl {val Call Swl} { global prent env logdir filename dxcc_gluggi if {$Call == {}} return set printfile [open $logdir/qsl.txt a] set printfile_csv [open $logdir/qsl.csv a] get_db_prent $val #puts "$prent(MY_CALL) $prent(CALLSIGN) $prent(QSO_DATE) $prent(TIME_ON)\ $prent(MODE) $prent(BAND) $prent(RST_SENT)" #set old_env $env(LANG) #set env(LANG) en_US if {$Swl == "QSL"} { set qsl(1) "$prent(MY_CALL) Confirming QSO with $prent(CALLSIGN)" set qsl(2) "On $prent(QSO_DATE) at $prent(TIME_ON) UTC" set qsl(3) "Using $prent(MODE) on the $prent(BAND) Band your RS(T)\ $prent(RST_SENT)" if {$prent(QSL_RCVD) == "Y"} { set qsl(4) "Tnx QSL 73 $filename(MYNAME)" } { set qsl(4) "Pse QSL 73 $filename(MYNAME)" } set qsl(5) "-----" # } { set qsl(1) "$prent(MY_CALL) Confirming SWL with $Swl" set qsl(2) "On $prent(QSO_DATE) at $prent(TIME_ON) UTC Using\ $prent(MODE)" set qsl(3) "on the $prent(BAND) Band in QSO with $prent(CALLSIGN)" set qsl(4) "Tnx QSL 73 $filename(MYNAME)" set qsl(5) "-----" } # puts $printfile " $qsl(1)\n $qsl(2)\n $qsl(3)\n $qsl(4)\n$qsl(5)" #puts $printfile_csv "$qsl(1),$qsl(2),$qsl(3),$qsl(4)" puts $printfile_csv "\"$qsl(1)\",\"$qsl(2)\",\"$qsl(3)\",\"$qsl(4)\"" close $printfile close $printfile_csv # $dxcc_gluggi delete 1.0 end if [catch {exec labelnation -d "-----" -p $logdir/parfile -l\ -i $logdir/qsl.txt -o $logdir/qslout.ps} svar] { $dxcc_gluggi insert end "QSL labels are in the files\n \ $logdir/qsl.txt" $dxcc_gluggi insert end "\n $logdir/qsl.csv" } { $dxcc_gluggi insert end "QSL labels are in the files\n \ $logdir/qslout.ps" $dxcc_gluggi insert end "\n $logdir/qsl.csv" } } proc get_swl {} { toplevel .swl frame .swl.e label .swl.e.l -text SWL entry .swl.e.e -textvariable swl -width 15 -relief sunken button .swl.e.p -text "Print SWL" -command { prenta_qsl $val(Num) $val(Call) $swl destroy .swl } button .swl.e.x -text Close -command {destroy .swl} pack .swl.e.l .swl.e.e .swl.e.p .swl.e.x -side left -padx .25 pack .swl.e bind .swl.e.e { set swl [string toupper $swl] } focus .swl.e.e } # # Print out the logfile in ADIF format # proc adif {firstnum} { global db db_logstructure logdir logstructure filename logbook set adiffile [open $logdir/[lindex $filename(DATABASE) 0].adi w] puts $adiffile "Operator:[string length $filename(MY_CALL)] [format\ "%s" $filename(MY_CALL)]1.00" set max [mysqlsel $db "SELECT MAX(NUM) from $logbook;" -list] for {set val $firstnum} {$val <= $max} {incr val} { set db_entry [mysqlsel $db "SELECT $db_logstructure from $logbook\ where NUM = \'$val\';" -flatlist] if {[string length $db_entry] > 14} { set numer 0 foreach i $logstructure { set prent($i) [lindex $db_entry $numer] incr numer } puts -nonewline $adiffile "[format "%s" $prent(CALLSIGN)]" regsub -all -- {-} $prent(QSO_DATE) {} prent(QSO_DATE) puts -nonewline $adiffile "[format "%s" $prent(QSO_DATE)]" regsub -all -- {:} $prent(TIME_ON) {} prent(TIME_ON) puts -nonewline $adiffile "[format "%s" $prent(TIME_ON)]" puts -nonewline $adiffile "[format "%s" $prent(BAND)]" puts -nonewline $adiffile "[format "%s" $prent(MODE)]" puts -nonewline $adiffile "[format "%s" $prent(RST_SENT)]" puts -nonewline $adiffile "[format "%s" $prent(RST_RCVD)]" puts -nonewline $adiffile "[format "%s" $prent(NAME)]" puts -nonewline $adiffile "[format "%s" $prent(QTH)]" puts -nonewline $adiffile "[format "%s" $prent(STX)]" puts -nonewline $adiffile "[format "%s" $prent(SRX)]" puts -nonewline $adiffile "[format "%s" $prent(CONTEST_ID)]" puts $adiffile "" } } close $adiffile } # # Print out the logfile in cabrillo format # proc cbr {firstnum} { global db db_logstructure logdir logbook logstructure filename cab_struct\ cab_header set CBR(SSB) PH set CBR(LSB) PH set CBR(USB) PH set CBR(AM) PH set CBR(CW) CW set CBR(PSK31) BPSK31 set CBR(BPSK31) BPSK31 set CBR(QPSK31) QPSK31 set CBR(MFSK16) MFSK16 set CBR(RTTY) RTTY set CBR(SSTV) SSTV set CBR(160m) 1800 set CBR(80m) 3500 set CBR(40m) 7000 set CBR(30m) 10100 set CBR(20m) 14000 set CBR(17m) 18100 set CBR(15m) 21000 set CBR(12m) 24900 set CBR(10m) 28000 set CBR(6m) 54000 set CBR(2m) 144000 set testline\ "00000000011111111112222222222333333333344444444445555555555666666666677777777778 12345678901234567890123456789012345678901234567890123456789012345678901234567890" set cbrfile [open $logdir/[lindex $filename(DATABASE) 0].cbr w] # puts $cbrfile $testline puts $cbrfile "START-OF-LOG: 2.0" foreach hline $cab_struct { puts $cbrfile "$hline: $cab_header($hline)" } set max [mysqlsel $db "SELECT MAX(NUM) from $logbook;" -list] for {set val $firstnum} {$val <= $max} {incr val} { set db_entry [mysqlsel $db "SELECT $db_logstructure from $logbook\ where NUM = \'$val\';" -flatlist] if {[string length $db_entry] > 14} { set numer 0 foreach i $logstructure { set prent($i) [lindex $db_entry $numer] incr numer } set call [format "%-13s" $filename(MY_CALL)] regsub -all -- {:} $prent(TIME_ON) {} prent(TIME_ON) puts $cbrfile "QSO: [format "%-5s" $CBR($prent(BAND))]\ $CBR($prent(MODE)) $prent(QSO_DATE) [string range\ $prent(TIME_ON) 0 3] [format "%-13s" $filename(MY_CALL)] [format\ "%-3s" $prent(RST_SENT)] [format "%-6s" $prent(STX)] [format\ "%-13s" $prent(CALLSIGN)] [format "%-3s" $prent(RST_RCVD)]\ [format "%-6s" $prent(SRX)]" } } puts $cbrfile "END-OF-LOG:" close $cbrfile } # # Print out the logfile in ASCII format # proc ascii {firstnum} { global db db_logstructure logdir logstructure filename logbook_name logbook set testline\ "00000000011111111112222222222333333333344444444445555555555666666666677777777778 12345678901234567890123456789012345678901234567890123456789012345678901234567890" set asciifile [open $logdir/[lindex $filename(DATABASE) 0].txt w] # puts $asciifile $testline set max [mysqlsel $db "SELECT MAX(NUM) from $logbook;" -list] for {set val $firstnum} {$val <= $max} {incr val} { set db_entry [mysqlsel $db "SELECT $db_logstructure from $logbook\ where NUM = \'$val\';" -flatlist] set numer 0 foreach i $logstructure { set prent($i) [lindex $db_entry $numer] incr numer } set call [format "%-13s" $filename(MY_CALL)] puts $asciifile "$prent(QSO_DATE) $prent(TIME_ON) [format\ "%-10s" $prent(CALLSIGN)] [format "%-6s" $prent(BAND)] [format\ "%-6s" $prent(MODE)] [format "%-3s %-4s" $prent(RST_SENT)\ $prent(STX)] [format "%-3s %-4s" $prent(RST_RCVD) $prent(SRX)]\ $prent(QSL_SENT) $prent(QSL_RCVD) [format "%-10s" $prent(NAME)]\ [format "%-32s" $prent(QTH)] [format "%-6s" $prent(RIG)] [format\ "%-3s" $prent(TX_PWR)] $prent(CONTEST_ID)" } close $asciifile # print the logfile using mpage and landscape exec mpage -1 -l\ -h$logbook_name($filename(GUI_LANG))_for_$filename(MY_CALL) -X\ -H $logdir/[lindex $filename(DATABASE) 0].txt >$logdir/[lindex\ $filename(DATABASE) 0].ps } # # calculate the distance and bearing to the station # proc dist {Lat Long} { global filename # set svar [exec gcb k 64N21W $Lat$Long] #set svar [exec gcb k $filename(LATLONG) $Lat$Long] if [catch {exec gcb k $filename(LATLONG) $Lat$Long} svar] { return "" } { # puts stdout $svar return $svar } } # # save the rcfile # proc save_rc {} { global rc_struct filename env loggrc set file [open $env(HOME)/$loggrc w 0600] foreach rcline $rc_struct { puts $file "[lindex $rcline 0] {$filename([lindex $rcline 0])}" } flush $file close $file } # # edit the rcfile # proc edit_rc {} { global rc_struct filename env loggrc toplevel .edit_rc set i 1 frame .edit_rc.cmds button .edit_rc.cmds.exit -text Close -command { destroy .edit_rc } button .edit_rc.cmds.save -text Save -command { set svar [tk_messageBox -message "Save changes to $loggrc" -type yesno\ -icon question] switch -- $svar { yes { save_rc read_rc destroy .edit_rc } } } pack .edit_rc.cmds.save .edit_rc.cmds.exit -in .edit_rc.cmds -side left\ -fill both pack .edit_rc.cmds -in .edit_rc -side top frame .edit_rc.left frame .edit_rc.right foreach rcline $rc_struct { frame .edit_rc.$i label .edit_rc.$i.l -text [lindex $rcline 0] -width 15 entry .edit_rc.$i.e -textvariable filename([lindex $rcline 0])\ -relief sunken -width 50 pack .edit_rc.$i.l .edit_rc.$i.e -in .edit_rc.$i -side left if {$i <= 19} { pack .edit_rc.$i -in .edit_rc.left -side top } { pack .edit_rc.$i -in .edit_rc.right -side top } incr i } pack .edit_rc.left .edit_rc.right -in .edit_rc -side left } proc edit_db_entry {} { global db logstructure db_logstructure logbook log_index edit_line val destroy .edit_entry toplevel .edit_entry frame .edit_entry.cmds button .edit_entry.cmds.exit -text Close -command { destroy .edit_entry } button .edit_entry.cmds.save -text Save -command { set newentry {} set newentry "NUM=$val(Num)" foreach i $logstructure { append newentry ",$i=\'$edit_line($log_index($i))\'" } mysqlexec $db "UPDATE $logbook set $newentry where NUM =\'$val(Num)\';" #write_log } button .edit_entry.cmds.del -text Delete -activebackground red -command { set svar [tk_messageBox -message "Delete entry: $val(Num)" -type yesno\ -icon question] switch -- $svar { yes { mysqlexec $db "DELETE FROM $logbook where NUM =\'$val(Num)\';" set max [mysqlsel $db "select MAX(NUM) from $logbook;"\ -flatlist] set infoentry [mysqlsel $db "select $db_info_todisplay from\ $logbook where NUM = \"$max\";" -flatlist] tail_db_log destroy .edit_entry check_db_entry $c_sel $log(CALLSIGN) "CALLSIGN" "like" } } } pack .edit_entry.cmds.save .edit_entry.cmds.exit .edit_entry.cmds.del\ -in .edit_entry.cmds -side left -fill both pack .edit_entry.cmds -in .edit_entry -side top set i 0 frame .edit_entry.left frame .edit_entry.right set editline [mysqlsel $db "select $db_logstructure from $logbook where\ NUM = \"$val(Num)\";" -flatlist] foreach line $logstructure { frame .edit_entry.$i set edit_line($i) [lindex $editline $i] label .edit_entry.$i.l -text $line -width 15 entry .edit_entry.$i.e -textvariable edit_line($i) -relief sunken pack .edit_entry.$i.l .edit_entry.$i.e -in .edit_entry.$i -side left if {$i <=16} { pack .edit_entry.$i -in .edit_entry.left -side top } { pack .edit_entry.$i -in .edit_entry.right -side top } incr i } pack .edit_entry.left .edit_entry.right -in .edit_entry -side left -anchor n } # # edit the CABBRILLO header # proc edit_cab {} { global cab_struct filename env loggrc cab_header c_sel toplevel .cab_h set i 1 frame .cab_h.cmds button .cab_h.cmds.exit -text Close -command { cbr $c_sel destroy .cab_h } pack .cab_h.cmds.exit -in .cab_h.cmds -side left -fill both pack .cab_h.cmds -in .cab_h -side top set cab_header(CALLSIGN) $filename(MY_CALL) set cab_header(NAME) $filename(NAME) set cab_header(ADDRESS) $filename(ADDRESS) foreach hline $cab_struct { frame .cab_h.$i label .cab_h.$i.l -text $hline -width 15 entry .cab_h.$i.e -textvariable cab_header($hline) -relief sunken pack .cab_h.$i.l .cab_h.$i.e -in .cab_h.$i -side left pack .cab_h.$i -in .cab_h -side top incr i } } # # send # # # send_cmd, the command to K2 using the serial port # if {[info procs send_cmd] == {}} { proc send_cmd {command} { global serial_port ready f log serial_busy if {$serial_busy} return set wordslist [split $command] foreach word $wordslist { puts $serial_port "[subst $word]" update } } } # # send, the message to K2 keyer using the serial port # if {[info procs send_mess] == {}} { proc send_live {message} { global serial_port serial_busy if {$serial_busy} return puts $serial_port "KY $message;" if {[winfo exists .t.wins]} { .t.wins.s insert end "$message" .t.wins.s see end update } } proc send_mess {message} { global serial_port .wins ready f log serial_busy filename if {$serial_busy} return set wordslist [split $message] foreach word $wordslist { puts $serial_port "KY [subst $word] ;" if {[winfo exists .t.wins]} { .t.wins.s insert end "[subst $word] " .t.wins.s see end update } } } } # # rig_update, get infor from the rig using hamlib # proc rig_update {} { #global log filename inn inline ant xfil xfil_bw dxcc_gluggi #global f freq vfo mode splitmode speed tx_pwr PA serial_busy rig_on global log filename array set RMODES {0 AM 1 FM 2 CW 3 CWR 4 USB 5 WFM 6 RTTY 7 RTTYR 8 LSB\ 9 AMS 10 PKTLSB 11 PKTUSB 12 PKTFM 13 BCSSUSB 14 BCSSLSB\ 15 FAX 16 RTTY 128 CWR 256 RTTYR} array set VFO {0 A 1 B} array set BANDS {1 160m 3 80m 7 40m 10 30m 14 20m 18 17m 21 15m 24 12m 28\ 10m 29 10m 54 6m} array set MODES {1 LSB 2 USB 3 CW 6 RTTY} set vfo [my_rig get_vfo] set ffreq [my_rig get_freq] if {[my_rig cget -error_status] == 0} { #puts "$imode $ffreq $fpwr" set freq [format "%.3f" [expr {$ffreq/1000.0}]] set MHz [expr {round($ffreq) /1000000}] if {[info exists BANDS($MHz)]} { set band $BANDS($MHz) } { set band "[expr {300/$MHz}]m" } set log(BAND) $band set log(FREQ) $freq } set imode [my_rig get_mode] if {[my_rig cget -error_status] == 0} { set mode $RMODES([lindex $imode 0]) set log(MODE) $mode } set fpwr [my_rig get_level_f RFPOWER] if {[my_rig cget -error_status] == 0} { set log(TX_PWR) [expr round($fpwr*100/0.0392156876624)/10.0] } } # # init_serial, setup the serialport for i/o # proc close_serial {} { global serial_port filename serial_busy if {!$serial_busy} { close $serial_port } } proc init_serial {} { global serial_port filename serial_busy if {[catch "open $filename(SERIAL_PORT) RDWR" serial_port]} { puts stderr "$filename(SERIAL_PORT) busy" set serial_busy 1 return 1 }\ elseif {[catch "fconfigure $serial_port -mode 4800,n,8,2 -blocking false \ -buffering line "]} { puts stderr "can't set $filename(SERIAL_PORT)" set serial_busy 1 return 1 } #puts stderr [fconfigure $serial_port] # fileevent $serial_port readable rig_info set serial_bysy 0 return 0 } # # and now the GUI # frame .top # # The qso date entry # frame .day label .day.dag_l -text $box_date($lang) -width 8 -relief sunken entry .day.dag -textvariable log(QSO_DATE) -width 8 -relief sunken\ -background #bedcaa -foreground darkblue pack .day.dag_l .day.dag -side top bind .day.dag { set tmode $b_text_manual($lang) } bind .day.dag { set tmode $b_text_auto($lang) } #bind .day.dag { # if {([string length $log(QSO_DATE)] == "8")} { # focus .tim.time # } #} # # The QSO start time entry # frame .tim label .tim.time_l -text $box_time($lang) -width 5 -relief sunken entry .tim.time -textvariable log(TIME_ON) -width 4 -relief sunken\ -background #bedcaa -foreground darkblue pack .tim.time_l .tim.time -side top bind .tim.time { set tmode $b_text_manual($lang) } bind .tim.time { set tmode $b_text_auto($lang) } #bind .tim.time { # if {([string length $log(TIME_ON)] == "4")} { # focus .call.stod # } #} # # The station call entry # frame .call label .call.stod_l -text $box_station($lang) -width 10 -relief sunken entry .call.stod -textvariable log(CALLSIGN) -width 10 -relief sunken pack .call.stod_l .call.stod -side top bind .call.stod { set log(CALLSIGN) [string toupper $log(CALLSIGN)] update if {[string length $log(CALLSIGN)] >= $CHECK_LIMIT} { check_db_entry $c_sel $log(CALLSIGN) "CALLSIGN" "like" set year [string range $log(QSO_DATE) 0 3] check_country $c_sel $log(CALLSIGN) $year } } bind .call.stod { #check_entry $c_sel $log(CALLSIGN) "CALLSIGN" check_db_entry $c_sel $log(CALLSIGN) "CALLSIGN" "like" } bind .call.stod { set tfreeze 1 if {($tmode == $b_text_auto($lang)) || ($tabmode == "CONT")} { do_time qrz $log(CALLSIGN) # rig_chk; if {($tabmode == "QSO") || ($tabmode == "UTIL")} { focus .rsts.rst_sent } { focus .rstr.rst_rx } } } bind .call.stod { incr CHECK_LIMIT if {$CHECK_LIMIT > 3} {set CHECK_LIMIT 1} $dxcc_gluggi delete 1.0 end $dxcc_gluggi insert end "CHECK_LIMIT set to: $CHECK_LIMIT" } bind .call.stod { if {($tabmode == "QSO") || ($tabmode == "UTIL")} { focus .rsts.rst_sent } { focus .rstr.rst_rx } } # # The band entry # frame .bnd label .bnd.m -text $box_band($lang) -width 5 -relief sunken menubutton .bnd.m_l -relief sunken -textvariable log(BAND) -menu .bnd.m_l.sel\ -width 3 -pady 2 -background #bedcaa -foreground darkblue menu .bnd.m_l.sel foreach bnd $filename(BAND) { .bnd.m_l.sel add radio -label $bnd -variable log(BAND) -value $bnd\ -command {set log(FREQ) $FREQ($log(BAND))} } pack .bnd.m .bnd.m_l -side top bind .bnd.m {send_cmd "SW01;"} bind .bnd.m {send_cmd "SW03;"} # # The frequency entry # frame .freq label .freq.tidni_l -text $box_freq($lang) -width 9 -relief sunken label .freq.tidni -textvariable log(FREQ) -width 9 -relief sunken\ -background #bedcaa -foreground darkblue pack .freq.tidni_l .freq.tidni -side top bind .freq.tidni_l {send_cmd "DN2;"} bind .freq.tidni_l {send_cmd "DN4;"} bind .freq.tidni_l {send_cmd "DN1;"} bind .freq.tidni_l {send_cmd "UP2;"} bind .freq.tidni_l {send_cmd "UP4;"} bind .freq.tidni_l {send_cmd "UP1;"} # # The mode entry # frame .mode label .mode.mode_l -text $box_mode($lang) -width 6 -relief sunken menubutton .mode.mode -relief sunken -textvariable log(MODE)\ -menu .mode.mode.mode -width 4 -pady 2 -background #bedcaa\ -foreground darkblue menu .mode.mode.mode foreach mo $filename(MODE) { .mode.mode.mode add radio -label $mo -variable log(MODE) -value $mo } pack .mode.mode_l .mode.mode -side top bind .mode.mode_l {send_cmd "SW08;"} # # The RST sent entry # frame .rsts label .rsts.rst_sent_l -text $box_rst_sent($lang) -width 10 -relief sunken entry .rsts.rst_sent -textvariable log(RST_SENT) -width 4 -relief sunken entry .rsts.rst_sx -textvariable log(STX) -width 5 -relief sunken pack .rsts.rst_sent_l -side top pack .rsts.rst_sent .rsts.rst_sx -side left bind .rsts.rst_sent { if {((($log(MODE) == "SSB") ||($log(MODE) == "USB") ||($log(MODE) ==\ "LSB") ||($log(MODE) == "AM") ||($log(MODE) == "FM")) &&([string length\ $log(RST_SENT)] == "2")) ||([string length $log(RST_SENT)] == "3")} { if {($tabmode == "QSO") || ($tabmode == "UTIL")} { focus .rstr.rst_rcvd } { focus .rstr.rst_rx } } } bind .rsts.rst_sent { if {($tabmode == "CONT")} { focus .rstr.rst_rcvd } } bind .rsts.rst_sx { if {($tabmode == "QSO")} { focus .rstr.rst_rcvd } } # # The RST received entry # frame .rstr label .rstr.rst_rcvd_l -text $box_rst_rcvd($lang) -width 10 -relief sunken entry .rstr.rst_rcvd -textvariable log(RST_RCVD) -width 4 -relief sunken entry .rstr.rst_rx -textvariable log(SRX) -width 5 -relief sunken pack .rstr.rst_rcvd_l -side top pack .rstr.rst_rcvd .rstr.rst_rx -side left bind .rstr.rst_rcvd { if {((($log(MODE) == "SSB") ||($log(MODE) == "USB") ||($log(MODE) ==\ "LSB") ||($log(MODE) == "AM") ||($log(MODE) == "FM")) &&([string length\ $log(RST_RCVD)] == 2)) ||([string length $log(RST_RCVD)] == 3)} { if {($tabmode == "QSO")} { focus .name.nafn } { focus .rstr.rst_rx } } } bind .rstr.rst_rx { if {($tabmode == "QSO")} { focus .name.nafn } } bind .rstr.rst_rx { set log(SRX) [string toupper $log(SRX)] } bind .rstr.rst_rx { set log(SRX) [string toupper $log(SRX)] if {($tabmode != "UTIL")} { add_db_entry } } bind .rstr.rst_rx { set log(SRX) [string toupper $log(SRX)] if {($tabmode != "UTIL")} { add_db_entry } } # # The QSL entry # frame .qsl label .qsl.qsl_l -text $box_qsl($lang) -width 5 -relief sunken menubutton .qsl.qsl_rq -relief sunken -textvariable log(QSL_SENT)\ -menu .qsl.qsl_rq.mode -width 1 -pady 2 menu .qsl.qsl_rq.mode .qsl.qsl_rq.mode add radio -label "Ignore" -variable log(QSL_SENT) -value I .qsl.qsl_rq.mode add radio -label "Requested" -variable log(QSL_SENT) -value R menubutton .qsl.qsl_se -relief sunken -textvariable log(QSL_RCVD)\ -menu .qsl.qsl_se.mode -width 1 -pady 2 menu .qsl.qsl_se.mode .qsl.qsl_se.mode add radio -label "Ignore" -variable log(QSL_RCVD) -value I .qsl.qsl_se.mode add radio -label "Requested" -variable log(QSL_RCVD) -value R pack .qsl.qsl_l -side top pack .qsl.qsl_rq .qsl.qsl_se -side left # # The OP name entry # frame .name label .name.nafn_l -text $box_name($lang) -width 10 -relief sunken entry .name.nafn -textvariable log(NAME) -width 10 -relief sunken pack .name.nafn_l .name.nafn -side top bind .name.nafn { #check_entry $c_sel $log(NAME) "NAME" check_db_entry $c_sel $log(NAME) "NAME" "like" } bind .name.nafn { if {($tabmode == "CONT")} { focus .call.stod } } # # The QTH, etc entry # frame .qthe label .qthe.qth_l -text $box_qth($lang) -width 30 -relief sunken entry .qthe.qth -textvariable log(QTH) -width 30 -relief sunken pack .qthe.qth_l .qthe.qth -side top bind .qthe.qth { #check_entry $c_sel $log(QTH) "QTH" check_db_entry $c_sel $log(QTH) "QTH" "like" } # # The rig used entry # frame .rig label .rig.rig_l -text $box_rig($lang) -width 7 -relief sunken menubutton .rig.rig -relief sunken -textvariable log(RIG) -menu .rig.rig.sel\ -width 6 -pady 2 menu .rig.rig.sel .rig.rig.sel add cascade -label "Rig" -menu .rig.rig.rig menu .rig.rig.rig foreach rig $filename(RIG) { .rig.rig.rig add radio -label $rig -variable log(RIG) -value $rig } .rig.rig.sel add separator .rig.rig.sel add cascade -label "Power" -menu .rig.rig.pwr menu .rig.rig.pwr foreach pwr $filename(TX_PWR) { .rig.rig.pwr add radio -label $pwr -variable log(TX_PWR) -value $pwr } .rig.rig.sel add separator .rig.rig.sel add cascade -label "Antenna" -menu .rig.rig.ant menu .rig.rig.ant foreach antenna $filename(ANT) { .rig.rig.ant add radio -label $antenna -variable log(ANT) -value $antenna } pack .rig.rig_l .rig.rig -side top bind .rig.rig.sel { switch -- $log(RIG) { K2 {set log(TX_PWR) 100} K2/QRP {set log(TX_PWR) 5} } } # RANT on and off bind .rig.rig { send_cmd "sw50;sw21;sw01;sw05;sw05;" } # # NOTES entry # frame .notese label .notese.notes_l -text $box_notes($lang) -width 10 -relief sunken entry .notese.notes -textvariable log(NOTES) -width 10 -relief sunken pack .notese.notes_l .notese.notes -side top # # The QSO end time entry # frame .tim_e label .tim_e.time_l -text $box_time_off($lang) -width 5 -relief sunken entry .tim_e.time -textvariable log(TIME_OFF) -width 4 -relief sunken bind .tim_e.time { if {($log(CONTEST_ID) != "QSO")} { add_db_entry } } pack .tim_e.time_l .tim_e.time -side top pack .day .tim .call .bnd .freq .mode .rsts .rstr .qsl .name .qthe .rig .tim_e\ -in .top -side left #pack .day .tim .call .bnd .mode .rsts .rstr .qsl .name .qthe .rig .notese\ # .tim_e -in .top -side left frame .bot # # Normal QSO or Contest mode # # label .logmode_l -text "Logmode" menubutton .logmode -relief sunken -textvariable log(CONTEST_ID)\ -menu .logmode.mode -width 10 menu .logmode.mode foreach cid [array names contests] { .logmode.mode add radio -label $cid -variable log(CONTEST_ID) -value $cid } bind .logmode.mode { if {$log(CONTEST_ID) == "ARRL-10"} { set log(BAND) 10m } if {$log(CONTEST_ID) == "ARRL-160" || $log(CONTEST_ID) == "CQ-160"} { set log(BAND) 160m } set save_call $log(CALLSIGN) upphaf 0 set log(CALLSIGN) $save_call } bind .logmode { zone $c_sel } menubutton .timemode -relief sunken -textvariable tmode -menu .timemode.mode\ -width 5 menu .timemode.mode .timemode.mode add radio -label $b_text_auto($lang) -variable tmode\ -value $b_text_auto($lang) .timemode.mode add radio -label $b_text_manual($lang) -variable tmode\ -value $b_text_manual($lang) # # Button for setting the QSO start time to current time # button .s_time -text $b_text_time($lang) -command { do_time } bind . {do_time} # # Button for setting the QSO end time to current time # button .e_time -text $b_text_time_off($lang) -command { set log(TIME_OFF) [clock format [clock seconds] -format %H%M%S -gmt 1] } # # Button for clearing the entries # button .clear -text $b_text_clear($lang) -command { #set infoentry $listi(0) set val(Num) 0 set val(Call) {} upphaf 0 } bind . { #set infoentry $listi(0) set val(Num) 0 set val(Call) {} upphaf 0 } # # Button for logging the enterd QSO # button .log -text $b_text_log($lang) -command { if {$log(CALLSIGN) != ""} { add_db_entry } } bind . { if {$log(CALLSIGN) != ""} { add_db_entry } } # # Button for file operations and quit # menubutton .file -text $b_text_file($lang) -menu .file.e -relief raised\ -padx .5c -pady .1c set exitmenu [menu .file.e] set exportmenu [menu .file.exp] .file.e add cascade -label "Export" -menu .file.exp .file.exp add command -label "Export file as CBR" -command { edit_cab } .file.exp add command -label "Export file as ADIF" -command { adif $c_sel } .file.exp add command -label "Export ADIF for eQSL" -command { set c_sel $filename(EQSL) incr c_sel adif $c_sel set filename(EQSL) [mysqlsel $db "select MAX(NUM) from $logbook;" -flatlist] save_rc set c_sel $filename(OFFSET) } .file.exp add command -label "Export file as ASCII" -command { ascii $c_sel } set importmenu [menu .file.imp] .file.e add cascade -label "Import" -menu .file.imp .file.imp add command -label "Import ADIF file" -command { set adif_file [tk_getOpenFile -initialdir $logdir -filetypes {{adif .adi}\ {adif .adif}}] if {$adif_file != ""} {lesa_adif $adif_file} } set rangemenu [menu .file.range] .file.e add cascade -label "Range" -menu .file.range .file.range add command -label "Set Range from QSO#" -command {set c_sel\ $val(Num)} .file.range add command -label "Set Range from 1" -command {set c_sel 1} .file.range add command -label "Set Range from OFFSET#" -command {set c_sel\ $filename(OFFSET)} .file.e add check -label "QRZ Lookup" -variable qrz_lookup -onvalue 1\ -offvalue 0 .file.e add check -label "Auto Date" -variable auto_date -onvalue 1 -offvalue 0 .file.e add command -label "Edit $loggrc" -command { edit_rc } .file.e add command -label "Backup database" -command { exec mysqldump --user=$filename(DB_USER) --password=$filename(DB_PASSWORD)\ --opt [lindex $filename(DATABASE) 0] >\ $env(HOME)/$filename(LOGDIR)/[lindex $filename(DATABASE) 0].sql $dxcc_gluggi delete 1.0 end $dxcc_gluggi insert end "Backup in:" $dxcc_gluggi insert end\ "$env(HOME)/$filename(LOGDIR)/[lindex $filename(DATABASE) 0].sql\n" $dxcc_gluggi insert end "To restore: mysql -p [lindex $filename(DATABASE)\ 0] < [lindex $filename(DATABASE) 0].sql" } .file.e add command -label "About $programname" -command { $country_gluggi delete 1.0 end $country_gluggi insert end $Credit $country_gluggi insert end $Help update } .file.e add command -label "MATerm" -command {if {[info procs morse] == {}}\ {source /usr/local/bin/MATerm} {morse}} .file.e add separator .file.e add command -label "Quit program" -activebackground red -command { if {$block == 0} { set block 1 } mysqlclose $db exit } frame .edit label .edit.qsl -text QSL label .edit.val -textvariable val(Call) -width 11 -relief sunken -anchor w\ -background lightyellow button .edit.qsl_s -text $b_text_sent($lang) -command { mysqlexec $db "UPDATE $logbook set QSL_SENT=\'Y\',\ QSLSDATE=\'$log(QSO_DATE)\' where NUM =\'$val(Num)\';" prenta_qsl $val(Num) $val(Call) QSL } button .edit.qsl_r -text $b_text_recvd($lang) -command { mysqlexec $db "UPDATE $logbook set QSL_RCVD=\'Y\',\ QSLRDATE=\'$log(QSO_DATE)\' where NUM =\'$val(Num)\';" } button .edit.qsl_p -text SWL -command { get_swl } menubutton .edit.log -relief sunken -textvariable logbook\ -menu .edit.log.logbook -width 10 menu .edit.log.logbook foreach table [lreplace $filename(DATABASE) 0 0] { .edit.log.logbook add radio -label $table -variable logbook -value $table\ -command { show_info set t_index [lsearch -exact $filename(DATABASE) $logbook] set t_new [lreplace $filename(DATABASE) $t_index $t_index] set filename(DATABASE) [linsert $t_new 1 $logbook] save_rc } } button .edit.upd -text $b_text_upd($lang) -command {show_info} button .edit.ptt -text PTT -relief raised -width 3 -background red\ -activebackground orange -borderwidth 5.0 -padx .5 -pady .25 bind .edit.ptt {send_cmd "TX;"} bind .edit.ptt {send_cmd "RX;"} button .edit.edit -text $b_text_edit($lang) -command { edit_db_entry } pack .edit.qsl .edit.val .edit.qsl_s .edit.qsl_r .edit.qsl_p .edit.log\ .edit.upd .edit.ptt -side left #.logmode_l #.timemode_l pack .file -in .bot -side left -pady .1c -padx .25c pack .logmode -in .bot -side left -pady .1c -padx .25c pack .s_time .log .clear .e_time -in .bot -side left -pady .1c -padx .25c pack .edit -in .bot -side left -pady .1c -padx .25c pack .top .bot -side top -expand y frame .last label .last.label -text $b_text_last($lang) label .last.num -textvariable val(Num) -width 5 -relief sunken\ -background lightyellow label .last.inf -text $b_text_info($lang) label .last.qso -textvariable infoentry -width 115 -relief sunken -anchor w\ -background lightyellow bind .last.qso { set val(Num) [lindex $infoentry 0] edit_db_entry } bind .last.qso { set val(Num) [lindex $infoentry 0] set val(Call) [lindex $infoentry 3] } checkbutton .last.on -selectcolor #bedcaa -indicatoron 1 -variable rig_on\ -offvalue 0 -onvalue 1 pack .last.label .last.qso .last.on -side left pack .last -side top -fill both -expand true # # Here is the display of old QSO's with the station # frame .info set info_gluggi [listbox .info.sambond -height 17 -width 70\ -yscrollcommand {.info.scroll set} -setgrid true -font $font] scrollbar .info.scroll -command {.info.sambond yview} pack .info.scroll -side right -fill y pack .info.sambond -side left -fill both -expand true bind .info.sambond { set sel_lina [$info_gluggi get [$info_gluggi nearest %y]] set value [lindex [split $sel_lina] 0] if {[regexp -nocase {[A-Z]} $value] || [string length $value] == 0} { check_country $c_sel $value 1966 } { set val(Num) $value set val(Call) [lindex [split $sel_lina] 5] check_country $c_sel $val(Call) 1966 set infoentry [mysqlsel $db "select $db_info_todisplay from $logbook\ where NUM = \"$value\";" -flatlist] } } bind .info.sambond { set sel_lina [$info_gluggi get [$info_gluggi nearest %y]] set value [lindex [split $sel_lina] 0] #if {[regexp -all {[0-9][^A-Z]} $value]} {} if {(([regexp -all {[^A-Z]} $value]) &&([string length $value] == 1))\ ||([regexp -all {[0-9][^A-Z]} $value])} { set val(Num) $value edit_db_entry } { #check_entry $c_sel $value "DXCC" set value [lindex [split $sel_lina] 0] check_db_entry $c_sel $value "DXCC" "equal" } } bind .info.sambond { set sel_lina [$info_gluggi get [$info_gluggi nearest %y]] set value [lindex [split $sel_lina] 0] set val(Num) $value check_db_entry $c_sel $value "QSO_DATE" "equal" } frame .haegri frame .dxcc set dxcc_gluggi [text .dxcc.country -wrap word -height 4 -width 50\ -yscrollcommand { .dxcc.scroll set} -setgrid true] scrollbar .dxcc.scroll -command {.dxcc.country yview} pack .dxcc.scroll -side right -fill y pack .dxcc.country -side left -fill both -expand true # # Here is the display of the dxcc country list # frame .lookup set country_gluggi [text .lookup.country -wrap word -height 7 -width 50\ -yscrollcommand { .lookup.scroll set} -setgrid true] scrollbar .lookup.scroll -command {.lookup.country yview} pack .lookup.scroll -side right -fill y pack .lookup.country -side left -fill both -expand true #pack .info .lookup -side left -fill both -expand true # # Here is the display of last 50 entries # frame .lastten set last_gluggi [text .lastten.log -wrap none -height 10 -width 50\ -yscrollcommand { .lastten.scroll set} -setgrid true] scrollbar .lastten.scroll -command {.lastten.log yview} pack .lastten.scroll -side right -fill y pack .lastten.log -side left -fill both -expand true pack .dxcc .lookup .lastten -in .haegri -side top -fill both -expand true pack .info .haegri -side left -fill both -expand true # # CW terminal, quick keys, send N and T for 9 and 0 # proc cw_term {} { global cursor_pos pre_cursor_pos cw_word live_key destroy .cwterm toplevel .cwterm if {[info exist live_key]} { set live_key [expr {!$live_key}] } { set live_key 1 } if {![info exists pre_cursor_pos]} { set pre_cursor_pos 1.0 } text .cwterm.t -width 40 -height 5 -yscrollcommand ".cwterm.txs set"\ -wrap word scrollbar .cwterm.txs -orient vertical -command ".cwterm.t yview" bind .cwterm.t { set cursor_pos [.cwterm.t index insert] set key [.cwterm.t get "$cursor_pos -1 chars"] if {[.cwterm.t compare "$cursor_pos" > "$pre_cursor_pos"] == 1} { if {$live_key == 0} { if {$key == " " || $key == "\n"} { # if {[info exists cw_word]} {send_mess "$cw_word "} if {[info exists cww_word]} {send_mess "$cww_word "} set cw_word {} set cww_word {} } append cww_word $key } { send_live $key } } set cw_word [.cwterm.t get "$cursor_pos -1 chars wordstart"\ "$cursor_pos"] set pre_cursor_pos $cursor_pos } pack .cwterm.t .cwterm.txs -side left -fill y -padx .25 -padx .25 focus .cwterm.t } proc rst_stx {rst stx} { set y [format "%3u %03u" $rst $stx] #regsub -all "0" $y "T" y #regsub -all "9" $y "N" y send_mess $y } bind all { if {$log(CONTEST_ID) == "QSO"} { #send_mess "CQ CQ CQ de $filename(MY_CALL) k" send_mess "[subst $filename(F1_QSO)]" } { #send_mess "Test de $filename(MY_CALL) k" send_mess "$filename(F1_CONTEST)" } } bind all { if {$log(CONTEST_ID) == "QSO"} { send_mess "[subst $filename(F2_QSO)]" } { send_mess "$filename(F2_CONTEST)" } } bind all { if {$log(CONTEST_ID) == "QSO"} { send_mess "[subst $filename(F3_QSO)]" } { send_mess "$filename(F3_CONTEST)" } } bind all {send_mess "$filename(F4)"} bind all {send_mess "$filename(F5)"} bind all { if {$log(CONTEST_ID) == "QSO"} { send_mess "BK" } { send_mess "[subst $filename(F6)]" } } bind all { if {$log(CONTEST_ID) == "QSO"} { send_mess "5nn" } { send_mess "[subst $filename(F7)]" } } bind all {send_mess "$filename(F8)"} bind all {send_mess "@"} bind all {cw_term} # # Initialize the time and othe things # do_time update # # start by reading in the information in the # all the logfiles and country list files # # FIXME: Need a real way to detect if the database is running under windows # Use this line instead of testing the socket: #if {[file readable $env(HOME)/$loggrc] == 1} set database [lindex $filename(DATABASE) 0] set logbooks [lreplace $filename(DATABASE) 0 0] set db [open_db $database $logbooks $filename(DB_USER) $filename(DB_PASSWORD)] puts "[lindex [mysqlinfo $db tables] 0]" set logbook [lindex [mysqlinfo $db tables] 0] $dxcc_gluggi insert end "Using Database: $database]\n" $dxcc_gluggi insert end "Using logbook named: $logbook " restore_session tail_db_log if {$c_sel != "{}"} { get_db_info $c_sel get_db_dxccinfo $c_sel } upphaf 1 dxcc_inn mkreg focus .call.stod # # process command line arguments # foreach arg $argv { switch -regexp -- $arg { -h { puts stderr "Options: --h help" puts stderr "Options: --u update country information in the logfile" } -u { puts stderr "Updating country info in logfile: $filename(DATABASE)\ ---please wait" puts stderr "Done" exit } } } update focus .call.stod # # initialize the rig_info, if the serialport is not busy # update init_serial #set RIG_ID 221 if {$use_hamlib == 1} { Rig my_rig $filename(RIG_ID) } # # the main program loops forever...... # while {$block == 1} { after $refresh update if {($tmode == $b_text_auto($lang)) &&($tfreeze == 0) &&($auto_date == 1)} { do_time } incr dog -1 if {$dog <= 0} { set dog 100 incr db_dog -1 # issue mysqlping so the server does not hangup on me if {$db_dog <= 0} { set db_dog 1000 set db_status [mysqlping $db] # puts "DB_status: $db_status" } if {$use_hamlib == 1} { set rig_status [my_rig get_powerstat] set status [my_rig cget -error_status] # puts "$rig_status status" if {$rig_status == 1 || $status == 0} { rig_update set rig_on 1 # puts on } { set rig_on 0 my_rig open } } } }