Merge tag 'v3.21.73' of git://git.berlios.de/fldigi

Conflicts:
	doc/Makefile.am
	po/dl-fldigi.pot
	po/es.po
	po/fr.po
	po/it.po
	po/pl.po
	src/Makefile.am
	src/dialogs/fl_digi.cxx
	src/include/configuration.h
	src/include/fl_digi.h
	src/rigcontrol/rigio.cxx
pull/1/head
James Coxon 2013-11-29 16:23:07 +00:00
commit 1d7d18fabd
123 zmienionych plików z 61073 dodań i 16257 usunięć

Wyświetl plik

@ -1,4 +1,86 @@
2013-05-13 David Freese <w1hkj@w1hkj.com>
=Version 3.21.73=
2013-07-28 David Freese <w1hkj@w1hkj.com>
627bddc: qrunner mod
98b61eb: Pskmail-test
2013-07-24 John Phelps <kl4yfd@gmail.com>
989a111: Doxygen for fldigi * Added scripts to generate Doxygen documentation from fldigi git repository / source * Also executes "cppcheck" and includes those results on Doxygen page (if installed on system) * Generates patches and log for the last 125 commits: includes links on Doxygen page
2013-07-24 David Freese <w1hkj@w1hkj.com>
86bb08b: CPPcheck errors
4a9724c: Modem class
3b9dff0: Rigcat Thread
55df4c7: Missing header
65640ca: fldigi-shell
59a9029: Fl::focus on OS X
edc0c9f: Data files
6794811: KML thread
fe82181: Fl::flush
59d9fbb: ADIF_RW thread
dfb6eaa: trx semaphore
35e8135: Digiscope buffer
2013-07-07 Robert Stiles <kk5vd@yahoo.com>
c75ac9a: Portaudio exceptions
2013-07-07 David Freese <w1hkj@w1hkj.com>
18534e4: mxe-win32 regex
0f5ede7: PSKMAIL/ARQ socket
e624bc0: Thor update
07f9cb8: record_loader fix
6e16b41: Code cleanup
50c1c12: Pskmail Notify RsID
4b9c578: MFSK shut down
2013-06-27 Robert Stiles <kk5vd@yahoo.com>
af5e09a: Cwidth test for zero
2013-06-21 David Freese <w1hkj@w1hkj.com>
b6ee3f7: XMLRPC
389c189: MXE compile
2013-06-19 Stefan Fendt <smfendt@gmail.com>
dfc2bd8: RTTY decoder
2013-06-09 Dennis Engdahl <engdahl@snowcrest.net>
7d62b22: RigCAT user commands
2013-06-08 David Freese <w1hkj@w1hkj.com>
3850862: TX state
9b26ff6: pskmail events
e12a373: * Changed extended rsid iaw doc/rsid_codes.gnumeric
2013-06-01 Remi Chateauneu <remi.chateauneu@gmail.com>
982f335: KML/Synop/RTTY/Navtex
3bb70e4: Port to MXE / MingW
34b3baf: QSL VIA
6cd7017: XML parser
2013-05-31 David Freese <w1hkj@w1hkj.com>
2c9c73f: ARQ support changes
f8e26f3: xmlrpcpp
237cc8f: PortAudio
dc7173c: SysV ARQ interface
1ea46c6: METAR format
e1004fc: RSID logic
=Version 3.21.72=
a933da1: RsID Timeout
ff1d69a: PSKMAIL
@ -1929,7 +2011,7 @@
2009-02-25 Stelios Bounanos <vcs@enotty.net>
a2fc0c8: Add better support for proportional fonts
a2fc0c8db: Add better support for proportional fonts
f6466f2: Fix font name/number compatibility code
eb1ec8a: Fix printf format string

Wyświetl plik

@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may
dnl contain other characters or be empty
m4_define(FLDIGI_MAJOR, [3])
m4_define(FLDIGI_MINOR, [21])
m4_define(FLDIGI_PATCH, [.72])
m4_define(FLDIGI_PATCH, [.73])
m4_define(FLARQ_MAJOR, [4])
m4_define(FLARQ_MINOR, [3])
m4_define(FLARQ_PATCH, [.4])
@ -196,13 +196,6 @@ AC_FLDIGI_BIND
# Set HAVE_FLUID Makefile conditional
AC_FLDIGI_FLTK
### XML-RPC library
# Set ac_cv_xmlrpc to yes/no
# Substitute XMLRPC_CFLAGS and XMLRPC_LIBS in Makefile
# Define USE_XMLRPC in config.h
# Set ENABLE_XMLRPC Makefile conditional
AC_FLDIGI_XMLRPC
### OSS
# Set ac_cv_oss to yes/no
# Define USE_OSS in config.h
@ -348,6 +341,5 @@ if test "x$ac_cv_want_fldigi" = "xyes"; then
pulseaudio .................. $ac_cv_pulseaudio
hamlib ...................... $ac_cv_hamlib
xmlrpc ...................... $ac_cv_xmlrpc
])
fi

Wyświetl plik

@ -13,6 +13,9 @@ France;FRA;490.0;E;FRC;CROSS Corsen;48 24 N;05 03 W;II;FF
France;FRA;490.0;S;FRL;CROSS La Garde;43 06 N;05 59 E;III;FF
Germany;DEU;490.0;L;DDH47;Pinneberg;53 43 N;09 55 E;I;DD
Iceland;ISL;490.0;R;TFA;Reykiavik;64 05 N;21 51 W;I;IS
Italy;ICH;490.0;I;IAR;La Maddalena;41 13 N;09 25 E;III;II
Italy;IQM;490.0;E;IAR;Mondolfo;43 45 N;13 05 E;III;II
Italy;ICI;490.0;W;IAR;Sellia Marina;38 54 N;16 44 E;III;II
Portugal;POR;490.0;G;CTV;Monsanto;38 44 N;09 11 W;II;PP
Romania;ROU;490.0;L;YOI;Constanta;44 12 N;28 40 E;III;RO
Scotland;SCT;490.0;C;GPK;Portpatrick;54 51 N;05 07 W;I;EE
@ -113,8 +116,9 @@ Iran;IRN;518.0;H;EOI;Bandar Abbas;27 08 N;57 04 E;IX;EE
Ireland;IRL;518.0;O;EJM;Malin Head Coastguard;55 22 N;07 21 W;I;EE
Ireland;IRL;518.0;W;EJK;Valentia Coastguard;51 27 N;09 49 W;I;EE
Israel;ISR;518.0;P;4XO;Haifa;32 49 N;35 00 E;III;EE
Italy;ITA;518.0;R;IAR;Roma;41 48 N;12 31 E;III;EE/II
Italy;ITA;518.0;U;IOX;Trieste;45 41 N;13 46 E;III;EE/II
Italy;ICH;518.0;R;IAR;La Maddalena;41 13 N;09 25 E;III;EE
Italy;IQM;518.0;U;IAR;Mondolfo;43 45 N;13 05 E;III;EE
Italy;ICI;518.0;V;IAR;Sellia Marina;38 54 N;16 44 E;III;EE
Japan;JPN;518.0;G;JNB;Naha;26 09 N;127 46 E;XI;EE
Japan;JPN;518.0;H;JNR;Moji;33 52 N;130 36 E;XI;EE
Japan;JPN;518.0;I;JGC;Yokohama;35 22 N;118 43 E;XI;EE

1 Azores AZR 490.0 J CTH Horta 38 32 N 28 38 W II PP
13 France FRA 490.0 S FRL CROSS La Garde 43 06 N 05 59 E III FF
14 Germany DEU 490.0 L DDH47 Pinneberg 53 43 N 09 55 E I DD
15 Iceland ISL 490.0 R TFA Reykiavik 64 05 N 21 51 W I IS
16 Italy ICH 490.0 I IAR La Maddalena 41 13 N 09 25 E III II
17 Italy IQM 490.0 E IAR Mondolfo 43 45 N 13 05 E III II
18 Italy ICI 490.0 W IAR Sellia Marina 38 54 N 16 44 E III II
19 Portugal POR 490.0 G CTV Monsanto 38 44 N 09 11 W II PP
20 Romania ROU 490.0 L YOI Constanta 44 12 N 28 40 E III RO
21 Scotland SCT 490.0 C GPK Portpatrick 54 51 N 05 07 W I EE
116 Ireland IRL 518.0 O EJM Malin Head Coastguard 55 22 N 07 21 W I EE
117 Ireland IRL 518.0 W EJK Valentia Coastguard 51 27 N 09 49 W I EE
118 Israel ISR 518.0 P 4XO Haifa 32 49 N 35 00 E III EE
119 Italy ITA ICH 518.0 R IAR Roma La Maddalena 41 48 N 41 13 N 12 31 E 09 25 E III EE/II EE
120 Italy ITA IQM 518.0 U IOX IAR Trieste Mondolfo 45 41 N 43 45 N 13 46 E 13 05 E III EE/II EE
121 Italy ICI 518.0 V IAR Sellia Marina 38 54 N 16 44 E III EE
122 Japan JPN 518.0 G JNB Naha 26 09 N 127 46 E XI EE
123 Japan JPN 518.0 H JNR Moji 33 52 N 130 36 E XI EE
124 Japan JPN 518.0 I JGC Yokohama 35 22 N 118 43 E XI EE

Plik diff jest za duży Load Diff

11548
data/nsd_bbsss.txt 100644

Plik diff jest za duży Load Diff

Plik diff jest za duży Load Diff

Wyświetl plik

@ -122,7 +122,6 @@ SectionEnd
SectionIn RO
SetOutPath $INSTDIR
File "${FLDIGI_BINARY}"
File /nonfatal "${MINGWM_DLL}" "${PTW32_DLL}"
!ifdef FLDIGI_LOCALE_DIR
File /r "${FLDIGI_LOCALE_PATH}/${FLDIGI_LOCALE_DIR}"
!endif
@ -139,9 +138,6 @@ SectionEnd
!endif
SetOutPath $INSTDIR
File "${FLARQ_BINARY}"
!ifndef HAVE_FLDIGI
File /nonfatal "${MINGWM_DLL}" "${PTW32_DLL}"
!endif
StrCpy $WANT_FLARQ "true"
SectionEnd
!endif
@ -221,8 +217,6 @@ Section "Uninstall"
!ifdef HAVE_FLARQ
Delete /REBOOTOK $INSTDIR\${FLARQ_BINARY}
!endif
Delete /REBOOTOK $INSTDIR\${MINGWM_DLL}
Delete /REBOOTOK $INSTDIR\${PTW32_DLL}
Delete /REBOOTOK $INSTDIR\uninstall.exe
# Remove shortcuts, if any

15531
data/wmo_list.txt 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -10,9 +10,7 @@ ASCIIDOC_HTML =
if WANT_FLDIGI
ASCIIDOC_MAN_INST += dl-fldigi.1
if ENABLE_XMLRPC
ASCIIDOC_MAN_INST += dl-fldigi-shell.1
endif
ASCIIDOC_MAN_INST += dl-fldigi-shell.1
ASCIIDOC_HTML += guide.html
endif

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -2,13 +2,19 @@ AC_DEFUN([AC_FLDIGI_NP_COMPAT], [
AC_REQUIRE([AC_FLDIGI_MACOSX])
AC_REQUIRE([AC_FLDIGI_WIN32])
AM_CONDITIONAL([COMPAT_REGEX], [test "x$ac_cv_header_regex_h" != "xyes"])
if test "x$target_mingw32" = "xyes"; then
sem_libs="pthreadGC2"
# Newer versions of mingw32 comes with pthread.
sem_libs="pthreadGC2 pthread"
# pretend that the regex.h check failed so that we use the bundled regex code
ac_cv_header_regex_h=no
AC_DEFINE([HAVE_REGEX_H], 0, [Define to 1 if you have the <regex.h> header file.])
else
sem_libs="pthread rt"
fi
AM_CONDITIONAL([COMPAT_REGEX], [test "x$ac_cv_header_regex_h" != "xyes"])
other_libs=""
if test "x$ac_cv_want_ptw32" = "xyes"; then

Wyświetl plik

@ -1,24 +0,0 @@
AC_DEFUN([AC_FLDIGI_XMLRPC], [
AC_ARG_WITH([xmlrpc],
AC_HELP_STRING([--with-xmlrpc], [enable xmlrpc server support @<:@autodetect@:>@]),
[case "${withval}" in
yes|no) ac_cv_want_xmlrpc="${withval}" ;;
*) AC_MSG_ERROR([bad value "${withval}" for --with-xmlrpc]) ;;
esac],
[ac_cv_want_xmlrpc=check])
if test "x$ac_cv_want_xmlrpc" = "xno"; then
AC_DEFINE(USE_XMLRPC, 0, [Define to 1 if we are using xmlrpc])
ac_cv_xmlrpc=no
else
ac_cv_xmlrpc=yes
AC_DEFINE(USE_XMLRPC, 1, [Define to 1 if we are using xmlrpc])
fi
if test "x$ac_cv_xmlrpc" = "xyes"; then
AC_DEFINE_UNQUOTED([XMLRPC_BUILD_VERSION], ["Builtin"], [XMLRPC-C version])
else
AC_DEFINE_UNQUOTED([XMLRPC_BUILD_VERSION], [""], [XMLRPC-C version])
fi
AM_CONDITIONAL([ENABLE_XMLRPC], [test "x$ac_cv_xmlrpc" = "xyes"])
])

Plik diff jest za duży Load Diff

4006
po/es.po

Plik diff jest za duży Load Diff

3941
po/fr.po

Plik diff jest za duży Load Diff

4012
po/it.po

Plik diff jest za duży Load Diff

12371
po/pl.po

Plik diff jest za duży Load Diff

Wyświetl plik

@ -158,7 +158,7 @@ sub execute($)
}
print Dumper(\@line) if ($debug);
my $r = decode(@line);
print $OUT $r, "\n" if ($r ne "");
if (defined $r) { print $OUT $r, "\n"};
}
else {
print $OUT $line[0] . ": command not found. Do you need ``help''?\n";

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,115 @@
#! /bin/bash -e
#
# KL4YFD 2013
# Released under GNU GPL
#
# This script generates DOXYGEN documentation from the fldigi source tree
# Checks are done to ensure needed binaries and files exists first
cd $( dirname ${BASH_SOURCE[0]} )
function usage
{
printf "\n\nThis script generates Doxygen documentation from the "
printf "\nfldigi sourcecode. By default, the tool \"cppcheck\" is also called. \nNote: This analysis takes longer than compilation and produces about 1.8GiB of data."
printf "\n\nUsage:"
printf "\n\tGenerate Doxygen documentation:\t ./gen_doxygen_docs.sh run"
printf "\n\tClean up after Doxygen run:\t ./gen_doxygen_docs.sh clean"
printf "\n\tClean up after Doxygen run:\t ./gen_doxygen_docs.sh nocppcheck"
printf "\n\tPrint this usage summary:\t ./gen_doxygen_docs.sh help \n\n"
}
function doxygen_clean {
rm -Rf HTML
printf "\ndoxygen documentation deleted!\n"
}
case "$1" in
"run")
doxygen_clean
../tests/cppcheck/gen_cppcheck_results.sh clean
# Continue with rest of script...
break
;;
"nocppcheck")
cppcheck_clean
exit
;;
"clean")
doxygen_clean
../tests/cppcheck/gen_cppcheck_results.sh clean
exit
;;
"--help" | "help")
usage
exit
;;
*)
usage
exit
;;
esac
printf "\nUsing support binaries:\n"
# Ensure the binary "doxygen" is on the system
if ! which doxygen ; then
printf "\n\nERROR: Generating the Fldigi Doxygen documents requires the program: doxygen"
printf "\n\tPlease install this program to continue."
printf "\n\n === ABORTING === \n\n"
exit 1
fi
# Ensure the binary "dot" is on the system
if ! which dot ; then
printf "\n\nERROR: Generating the Fldigi Doxygen documents requires the program: dot"
printf "\n\tThis program is part of the package: graphviz \n\n"
printf "\n\tPlease install this program to continue."
printf "\n\n === ABORTING === \n\n"
exit 1
fi
# Ensure the binary "mscgen" is on the system
if ! which mscgen ; then
printf "\n\nERROR: Generating the Fldigi Doxygen documents requires the program: mscgen"
printf "\n\tPlease install this program to continue."
printf "\n\n === ABORTING === \n\n"
exit 1
fi
# Ensure the Doxygen config file exists
if [ ! -e ./fldigi_doxyfile.txt ]; then
printf "\n\nERROR: Doxygen configuration file: \"fldigi_doxyfile.txt\" not found."
printf "\n\n === ABORTING === \n\n"
exit 1
fi
doxygen fldigi_doxyfile.txt
# Go create some really useful information using git
cd HTML
mkdir __git; cd __git
git format-patch --summary -n HEAD~125 # Create patches for the last 125 commits
git log --stat -n 125 > gitlog.txt # Dump the history of the last 125 commits
cd ..
cd ..
if ! which cppcheck ; then
printf "\n\nWARNING: Binary \"cppcheck\" not found."
printf "\n\n\t Skipping sourcecode analysis. Install cppcheck and re-run.\n\n"
else
../tests/cppcheck/gen_cppcheck_results.sh run
fi
printf "\n\n === DOXYGEN documentation generation complete. ==="
printf "\n\nDocumentation Directory: $(pwd)/HTML"
printf "\nMain file: $(pwd)/HTML/index.html\n\n"
# Open the main-Doxygen page in a web-browser.
if which xdg-open ; then
xdg-open ./HTML/index.html # Ubuntu, Linux, etc...
else
open ./HTML/index.html # OSX, Unix, etc..
fi

Wyświetl plik

@ -0,0 +1,17 @@
scripts/doxygen/readme.txt
This directory contains the run-script: gen_doxygen_docs.sh and
configuration file: fldigi_doxyfile.txt used for auto-generating
DOXYGEN source-code documentation.
This documentation can be extremely useful for both learning and debugging fldigi/flarq.
== Usage ==
1) Execute: ' ./gen_doxygen_docs.sh run ' on a Unix-Like system. (OSX, Linux, etc...)
- the script will complain usefully if anything is missing
- NOTE: this will generate 1.8GiB of data and take longer than compilation.
2) Once generation completes, a web-browser will automatically open the file: HTML/index.html
- URL Example: file:///tmp/fldigi/scripts/doxygen/HTML/index.html

Wyświetl plik

@ -0,0 +1,47 @@
#!/bin/sh
# This script copies KML files created by fldigi, to a remote machine,
# where the resulting URL can be given to Google Maps.
# The script path name ùust be entered in the parameter "Command"
# of the KML configuration tab. it will started each time new
# KML files are created or updated.
HOST=$1
if [ "$HOST" == "" ]
then
read -p "Host name:" HOST
fi
USER=$2
if [ "$USER" == "" ]
then
read -p "FTP user:" USER
fi
PASSWD=$3
if [ "$PASSWD" == "" ]
then
read -p "FTP password:" PASSWD
fi
DIRECTORY=$4
if [ "$DIRECTORY" == "" ]
then
read -p "FTP target directory:" DIRECTORY
fi
cd ~/.fldigi/kml
#cat > toto <<END_SCRIPT
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
cd $DIRECTORY
prompt
mput *.kml
quit
END_SCRIPT
cd -
echo "FTP remote copy to $HOST done"

Wyświetl plik

@ -13,7 +13,7 @@ if test "x$PKG_CONFIG" != "x"; then
else
hamlib_dir="${HAMLIB_LIBS#*-L}"
hamlib_dir="${HAMLIB_LIBS%% *}"
if test "x$hamlib_dir" = "x"; then
if test "x$hamlib_dir" = "x"; then\
hamlib_dir=/usr/lib
fi
fi

Wyświetl plik

@ -35,6 +35,8 @@ fldigi_bin=dl-fldigi.exe
flarq_name=Flarq
flarq_bin=flarq.exe
def=
if test "x$WANT_FLDIGI" != "xyes" && test "x$WANT_FLARQ" != "xyes"; then
echo "E: refusing to create empty installer" >&2
exit 1
@ -48,43 +50,6 @@ if test "x$WANT_FLARQ" = "xyes"; then
def="$def -DHAVE_FLARQ -DFLARQ_NAME=$flarq_name -DFLARQ_BINARY=$flarq_bin -DFLARQ_VERSION=$FLARQ_VERSION"
fi
# Look for pthreadGC2.dll and mingwm10.dll
MINGWM_DLL=mingwm10.dll
PTW32_DLL=pthreadGC2.dll
if ! test -r "$build/$MINGWM_DLL" || ! test -r "$build/$PTW32_DLL"; then
IFS_saved="$IFS"
IFS=:
MINGWM_PATH=""
PTW32_PATH=""
for dir in $LIB_PATH; do
test "x$MINGWM_PATH" = "x" && test -r "$dir/$MINGWM_DLL" && MINGWM_PATH="$dir/$MINGWM_DLL"
test "x$PTW32_PATH" = "x" && test -r "$dir/$PTW32_DLL" && PTW32_PATH="$dir/$PTW32_DLL"
done
IFS="$IFS_saved"
fi
if ! test -r "$build/$MINGWM_DLL"; then
if test "x$MINGWM_PATH" != "x"; then
cp "$MINGWM_PATH" "$build"
elif test -r /usr/share/doc/mingw32-runtime/${MINGWM_DLL}.gz; then
# Debian and Ubuntu
gzip -dc /usr/share/doc/mingw32-runtime/${MINGWM_DLL}.gz > "$build/$MINGWM_DLL"
fi
fi
if ! test -r "$build/$PTW32_DLL"; then
if test "x$PTW32_PATH" != "x"; then
cp "$PTW32_PATH" "$build"
else
# look for dll in PTW32_LIBS
dir=$(echo $PTW32_LIBS | sed -r 's/.*-L([[:graph:]]+).*/\1/g')
lib=$(echo $PTW32_LIBS | sed -r 's/.*-l(pthreadGC[[:graph:]]+).*/\1/g')
lib="${lib}.dll"
if test -r "$dir/$lib"; then
cp "$dir/$lib" "$build"
fi
fi
fi
def="$def -DMINGWM_DLL=$MINGWM_DLL -DPTW32_DLL=$PTW32_DLL"
if test "x$USE_NLS" = "xyes" && make -C "$srcdir/../po" install prefix="$build" >/dev/null; then
def="$def -DFLDIGI_LOCALE_PATH=$build/share -DFLDIGI_LOCALE_DIR=locale"
fi

Wyświetl plik

@ -0,0 +1,103 @@
#! /bin/bash
#
# KL4YFD 2013
# Released under GNU GPL
#
# This script runs automatic source-code checks using the tool: "cppcheck"
# Checks are done to ensure needed binary exists first
cd $( dirname ${BASH_SOURCE[0]} )
INCLUDEDIR="../../../src/include"
SRCDIR="../../../src"
RESULTSDIR="results"
THREADS=8
function usage
{
printf "\n\nThis script executes the tool \"cppcheck\" and "
printf "\nsorts the results into separate files by severity / type\n Note: This analysis takes about the same time as compilation."
printf "\n\nUsage:"
printf "\n\tRun cppcheck tests:\t ./gen_cppcheck_results.sh run"
printf "\n\tClean up all files:\t ./gen_cppcheck_results.sh clean"
printf "\n\tPrint this usage:\t ./gen_cppcheck_results.sh help \n\n"
}
function cppcheck_clean {
rm -Rf $RESULTSDIR
printf "\ncppcheck results deleted!\n"
}
case "$1" in
"run")
cppcheck_clean
# Continue with rest of script...
break
;;
"clean")
cppcheck_clean
exit
;;
"--help" | "help")
usage
exit
;;
*)
usage
exit
;;
esac
# Ensure the binary "cppcheck" is on the system
if ! which cppcheck ; then
printf "\n\nERROR: Running the Fldigi cppcheck tests requires the program: cppcheck"
printf "\n\t Please install this program to continue."
printf "\n\n === ABORTING === \n\n"
exit 1
fi
mkdir $RESULTSDIR
cppcheck --inline-suppr --inconclusive --enable=all -I $INCLUDEDIR -j $THREADS --force --verbose $SRCDIR 2> $RESULTSDIR/ALL.txt
cd $RESULTSDIR
# Separate out the results into files based on their "cppcheck types"
cat ALL.txt | grep "(error)" > error.txt
cat ALL.txt | grep "(warning)" > warning.txt
cat ALL.txt | grep "(style)" > style.txt
cat ALL.txt | grep "(performance)" > performance.txt
cat ALL.txt | grep "(portability)" > portability.txt
cat ALL.txt | grep "(information)" > information.txt
cat ALL.txt | grep "(debug)" > debug.txt
# Separate out the tests with inconclusive results
cat ALL.txt | grep "(error, inconclusive)" > error_inconclusive.txt
cat ALL.txt | grep "(warning, inconclusive)" > warning_inconclusive.txt
cat ALL.txt | grep "(style, inconclusive)" > style_inconclusive.txt
cat ALL.txt | grep "(performance, inconclusive)" > performance_inconclusive.txt
cat ALL.txt | grep "(portability, inconclusive)" > portability_inconclusive.txt
cat ALL.txt | grep "(information, inconclusive)" > information_inconclusive.txt
#cat ALL.txt | grep "(debug, inconclusive)" > debug.txt # debug is for Messages from cppcheck itself, not a test-result. Therefore no such combination.
# Just in case... Catch everything _not_ in the above blocks.
cat ALL.txt | grep --invert-match "(error)" \
| grep --invert-match "(warning)" \
| grep --invert-match "(style)" \
| grep --invert-match "(performance)" \
| grep --invert-match "(portability)" \
| grep --invert-match "(information)" \
| grep --invert-match "(debug)" \
| grep --invert-match "(error, inconclusive)" \
| grep --invert-match "(warning, inconclusive)" \
| grep --invert-match "(style, inconclusive)" \
| grep --invert-match "(performance, inconclusive)" \
| grep --invert-match "(portability, inconclusive)" \
| grep --invert-match "(information, inconclusive)" > leftover.txt
cd ..
printf "\n\n === cppcheck source-code analysis complete. ==="
printf "\n\nResults saved in: $(pwd)/results \n\n"

Wyświetl plik

@ -44,6 +44,8 @@ EXTRA_flarq_SOURCES = $(FLARQ_WIN32_RES_SRC) $(COMMON_WIN32_RES_SRC)
dl_fldigi_SOURCES =
flarq_SOURCES =
dl_fldigi_SOURCES += $(XMLRPC_SRC)
if ENABLE_HAMLIB
dl_fldigi_SOURCES += $(HAMLIB_SRC)
endif
@ -51,10 +53,6 @@ if NEED_HAMLIB_LOCATOR
dl_fldigi_SOURCES += $(LOCATOR_SRC)
endif
if ENABLE_XMLRPC
dl_fldigi_SOURCES += $(XMLRPC_SRC)
endif
if ENABLE_BENCHMARK
dl_fldigi_SOURCES += $(BENCHMARK_SRC)
endif
@ -116,13 +114,17 @@ endif
install-exec-local:
if WANT_FLDIGI
if ENABLE_XMLRPC
if test -f $(srcdir)/../scripts/dl-fldigi-shell; then \
$(mkinstalldirs) $(DESTDIR)/$(bindir); \
$(INSTALL_SCRIPT) $(srcdir)/../scripts/dl-fldigi-shell $(DESTDIR)/$(bindir); \
fi
if test -f $(srcdir)/../scripts/ftp_kml_files.sh; then \
$(mkinstalldirs) $(DESTDIR)/$(bindir); \
$(INSTALL_SCRIPT) $(srcdir)/../scripts/ftp_kml_files.sh $(DESTDIR)/$(bindir); \
fi
endif
endif
# TODO: xpm files should probably go to $(datadir)/pixmaps/fldigi instead of $(datadir)/pixmaps
install-data-local:
if WANT_FLDIGI
@ -142,6 +144,26 @@ if WANT_FLDIGI
$(mkinstalldirs) $(DESTDIR)/$(pkgdatadir); \
$(INSTALL_DATA) $(srcdir)/../data/NAVTEX_Stations.csv $(DESTDIR)/$(pkgdatadir); \
fi
if test -f $(srcdir)/../data/nsd_bbsss.txt; then \
$(mkinstalldirs) $(DESTDIR)/$(datadir)/fldigi; \
$(INSTALL_DATA) $(srcdir)/../data/nsd_bbsss.txt $(DESTDIR)/$(pkgdatadir); \
fi
if test -f $(srcdir)/../data/station_table.txt; then \
$(mkinstalldirs) $(DESTDIR)/$(datadir)/fldigi; \
$(INSTALL_DATA) $(srcdir)/../data/station_table.txt $(DESTDIR)/$(pkgdatadir); \
fi
if test -f $(srcdir)/../data/ToR-Stats-SHIP.csv; then \
$(mkinstalldirs) $(DESTDIR)/$(datadir)/fldigi; \
$(INSTALL_DATA) $(srcdir)/../data/ToR-Stats-SHIP.csv $(DESTDIR)/$(pkgdatadir); \
fi
if test -f $(srcdir)/../data/wmo_list.txt; then \
$(mkinstalldirs) $(DESTDIR)/$(datadir)/fldigi; \
$(INSTALL_DATA) $(srcdir)/../data/wmo_list.txt $(DESTDIR)/$(pkgdatadir); \
fi
if test -f $(srcdir)/../kml/styles.kml; then \
$(mkinstalldirs) $(DESTDIR)/$(pkgdatadir)/kml; \
$(INSTALL_DATA) $(srcdir)/../kml/styles.kml $(DESTDIR)/$(pkgdatadir)/kml; \
fi
endif
if WANT_FLARQ
if test -f $(srcdir)/../data/flarq.xpm; then \
@ -167,8 +189,11 @@ if WANT_FLARQ
rm -f $(DESTDIR)/$(datadir)/applications/flarq.desktop
endif
FLDIGI_FL_SRC = dialogs/confdialog.fl \
logbook/lgbook.fl dialogs/notifydialog.fl
FLDIGI_FL_SRC = \
dialogs/confdialog.fl \
dialogs/notifydialog.fl \
dialogs/record_browse.fl \
logbook/lgbook.fl
FLARQ_FL_SRC = flarq-src/arqdialogs.fl
if HAVE_FLUID
@ -262,6 +287,7 @@ dl_fldigi_SOURCES += \
dialogs/Viewer.cxx \
dialogs/htmlstrings.cxx \
dialogs/notifydialog.cxx \
dialogs/record_browse.cxx \
dtmf/dtmf.cxx \
thor/thor.cxx \
thor/thorvaricode.cxx \
@ -330,6 +356,8 @@ dl_fldigi_SOURCES += \
include/jalocha/pj_lowpass3.h \
include/jalocha/pj_mfsk.h \
include/jalocha/pj_struc.h \
include/coordinate.h \
include/kmlserver.h \
include/locator.h \
include/log.h \
include/logger.h \
@ -352,6 +380,7 @@ dl_fldigi_SOURCES += \
include/newinstall.h \
include/notify.h \
include/notifydialog.h \
include/record_browse.h \
include/olivia.h \
include/pkg.h \
include/picture.h \
@ -378,8 +407,10 @@ dl_fldigi_SOURCES += \
include/rsid.h \
include/rtty.h \
include/view_rtty.h \
include/navtex.h \
include/synop.h \
include/nullmodem.h \
include/record_loader.h \
include/record_loader_gui.h \
include/rx_extract.h \
include/speak.h \
include/serial.h \
@ -466,9 +497,11 @@ dl_fldigi_SOURCES += \
misc/charsetdistiller.cxx \
misc/charsetlist.cxx \
misc/configuration.cxx \
misc/coordinate.cxx \
misc/debug.cxx \
misc/dxcc.cxx \
misc/icons.cxx \
misc/kmlserver.cxx \
misc/log.cxx \
misc/macroedit.cxx \
misc/macros.cxx \
@ -480,6 +513,7 @@ dl_fldigi_SOURCES += \
misc/pixmaps.cxx \
misc/pixmaps_tango.cxx \
misc/re.cxx \
misc/record_loader.cxx \
misc/socket.cxx \
misc/stacktrace.cxx \
misc/status.cxx \
@ -493,6 +527,7 @@ dl_fldigi_SOURCES += \
mt63/mt63.cxx \
mt63/mt63base.cxx \
navtex/navtex.cxx \
include/navtex.h \
olivia/olivia.cxx \
psk/psk.cxx \
psk/pskcoeff.cxx \
@ -518,6 +553,7 @@ dl_fldigi_SOURCES += \
ssdv/ssdv_rx.cxx \
ssdv/rs8.c \
ssb/ssb.cxx \
synop-src/synop.cxx \
throb/throb.cxx \
trx/modem.cxx \
trx/nullmodem.cxx \
@ -749,7 +785,7 @@ flarq_SOURCES += \
widgets/Fl_Text_Editor_mod.cxx \
widgets/FTextView.cxx
# Additional non-source files that we distribute
# Additional files that we distribute
EXTRA_DIST = \
$(srcdir)/../scripts/mkappbundle.sh \
$(srcdir)/../scripts/mkhamlibstatic.sh \
@ -763,6 +799,9 @@ EXTRA_DIST = \
$(srcdir)/../data/dl-fldigi.desktop \
$(srcdir)/../data/dl-fldigi-hab.desktop \
$(srcdir)/../data/NAVTEX_Stations.csv \
$(srcdir)/../data/nsd_bbsss.txt \
$(srcdir)/../data/station_table.txt \
$(srcdir)/../data/ToR-Stats-SHIP.csv \
$(srcdir)/../data/mac/Info.plist.in \
$(srcdir)/../data/mac/fldigi.icns \
$(srcdir)/../data/win32/fldigi.ico \
@ -770,6 +809,9 @@ EXTRA_DIST = \
$(srcdir)/../data/flarq.xpm \
$(srcdir)/../data/mac/flarq.icns \
$(srcdir)/../data/win32/flarq.ico \
$(srcdir)/synop-src/synop_tool.cxx \
$(srcdir)/synop-src/README \
$(srcdir)/synop-src/Makefile \
$(FLDIGI_FL_SRC) \
$(FLARQ_FL_SRC)

Wyświetl plik

@ -45,14 +45,12 @@ static void GetVendorID (char *vid)
BOOL GetMachInfo(LPSTR MachineName, LPSTR ProcessorName)
{
SYSTEM_INFO sysinf;
int family, model, stepping;
int family;
char VendorId [VIDSIZE+2];
ZeroMemory(&sysinf, sizeof(SYSTEM_INFO));
GetSystemInfo(&sysinf);
family = sysinf.wProcessorLevel;
model = HIBYTE(sysinf.wProcessorRevision);
stepping = LOBYTE(sysinf.wProcessorRevision);
switch (sysinf.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_UNKNOWN:

Wyświetl plik

@ -1137,8 +1137,10 @@ regex_compile (pattern, size, syntax, bufp)
{ /* Caller did not allocate a buffer. Do it for them. */
bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
}
if (!bufp->buffer) return REG_ESPACE;
if (!bufp->buffer) {
free(compile_stack.stack);
return REG_ESPACE;
}
bufp->allocated = INIT_BUF_SIZE;
}
@ -4815,8 +4817,11 @@ regexec (preg, string, nmatch, pmatch, eflags)
regs.num_regs = nmatch;
regs.start = TALLOC (nmatch, regoff_t);
regs.end = TALLOC (nmatch, regoff_t);
if (regs.start == NULL || regs.end == NULL)
return (int) REG_NOMATCH;
if (regs.start == NULL || regs.end == NULL) {
free (regs.start);
free (regs.end);
return (int) REG_NOMATCH;
}
}
/* Perform the searching operation. */

Wyświetl plik

@ -840,7 +840,7 @@ int cw::handle_event(int cw_event, const char **c)
cw_receive_state == RS_AFTER_TONE) {
// Look up the representation
//cout << "CW_QUERY medium time after keyup: " << rx_rep_buf;
*c = morse::rx_lookup(rx_rep_buf);
*c = morse.rx_lookup(rx_rep_buf);
//cout <<": " << *c <<flush;
if (*c == NULL) {
// invalid decode... let user see error
@ -1128,7 +1128,7 @@ void cw::send_ch(int ch)
// convert character code to a morse representation
if ((chout < 256) && (chout >= 0)) {
code = tx_lookup(chout); //cw_tx_lookup(ch);
code = morse.tx_lookup(chout); //cw_tx_lookup(ch);
firstelement = true;
} else {
code = 0x04; // two extra dot spaces
@ -1163,7 +1163,7 @@ void cw::send_ch(int ch)
FL_AWAKE();
if (ch != -1) {
string prtstr = tx_print(ch);
string prtstr = morse.tx_print(ch);
if (prtstr.length() == 1)
put_echo_char(progdefaults.rx_lowercase ? tolower(prtstr[0]) : prtstr[0]);
else
@ -1186,7 +1186,7 @@ int cw::tx_process()
prosigns != progdefaults.CW_prosigns) {
use_paren = progdefaults.CW_use_paren;
prosigns = progdefaults.CW_prosigns;
morse::init();
morse.init();
}
c = get_tx_char();

Wyświetl plik

@ -145,7 +145,7 @@ static CW_TABLE cw_table[] = {
* is viewable as an integer in the range 2 (".") to 255 ("-------"), and can
* be used as an index into a fast lookup array.
*/
unsigned int morse::tokenize_representation(const char *representation)
unsigned int cMorse::tokenize_representation(const char *representation)
{
unsigned int token; /* Return token value */
const char *sptr; /* Pointer through string */
@ -184,7 +184,7 @@ unsigned int morse::tokenize_representation(const char *representation)
/* ---------------------------------------------------------------------- */
void morse::init()
void cMorse::init()
{
CW_TABLE *cw; /* Pointer to table entry */
unsigned int i;
@ -230,7 +230,7 @@ void morse::init()
}
}
const char *morse::rx_lookup(char *r)
const char *cMorse::rx_lookup(char *r)
{
int token;
CW_TABLE *cw;
@ -244,7 +244,7 @@ const char *morse::rx_lookup(char *r)
return cw->prt;
}
const char *morse::tx_print(int c)
const char *cMorse::tx_print(int c)
{
if (cw_tx_lookup[toupper(c)].prt)
return cw_tx_lookup[toupper(c)].prt;
@ -252,7 +252,7 @@ const char *morse::tx_print(int c)
return "";
}
unsigned long morse::tx_lookup(int c)
unsigned long cMorse::tx_lookup(int c)
{
return cw_tx_lookup[toupper(c)].code;
}

Wyświetl plik

@ -44,6 +44,8 @@ using namespace std;
#include "digiscope.h"
#include "trx.h"
#include "debug.h"
#include "synop.h"
#include "main.h"
#include "dl_fldigi/hbtint.h"
@ -89,6 +91,25 @@ void rtty::tx_init(SoundBase *sc)
videoText();
}
// Customizes output of Synop decoded data.
struct rtty_callback : public synop_callback {
// Callback for writing decoded synop messages.
void print(const char * str, size_t nb, bool bold ) const {
// Could choose: FTextBase::CTRL,XMIT,RECV
int style = bold ? FTextBase::XMIT : FTextBase::RECV;
for( size_t i = 0; i < nb; ++i ) {
unsigned char c = str[i];
put_rx_char(progdefaults.rx_lowercase ? tolower(c) : c, style );
}
}
// Should we log new Synop messages to the current Adif log file ?
bool log_adif(void) const { return progdefaults.SynopAdifDecoding ;}
// Should we log new Synop messages to KML file ?
bool log_kml(void) const { return progdefaults.SynopKmlDecoding ;}
bool interleaved(void) const { return progdefaults.SynopInterleaved ;}
};
void rtty::rx_init()
{
rxstate = RTTY_RX_STATE_IDLE;
@ -113,12 +134,22 @@ void rtty::rx_init()
lastchar = 0;
// Synop file is reloaded each time we enter this modem. Ideally do that when the file is changed.
static bool wmo_loaded = false ;
if( wmo_loaded == false ) {
wmo_loaded = true ;
SynopDB::Init(PKGDATADIR);
}
/// Used by weather reports decoding.
synop::setup<rtty_callback>();
synop::instance()->init();
}
void rtty::init()
{
bool wfrev = wf->Reverse();
bool wfsb = wf->USB();
// Probably not necessary because similar to modem::set_reverse
reverse = wfrev ^ !wfsb;
stopflag = false;
@ -452,7 +483,16 @@ bool rtty::rx(bool bit) // original modified for probability test
if (is_mark()) {
if ((metric >= progStatus.sldrSquelchValue && progStatus.sqlonoff) || !progStatus.sqlonoff) {
c = decode_char();
if ( c != 0 ) {
if( progdefaults.SynopAdifDecoding || progdefaults.SynopKmlDecoding ) {
if (c != 0 && c != '\r') {
synop::instance()->add(c);
} else {
if( synop::instance()->enabled() )
synop::instance()->flush(false);
put_rx_char(c);
}
} else if ( c != 0 ) {
// supress <CR><CR> and <LF><LF> sequences
// these were observed during the RTTY contest 2/9/2013
if (c == '\r' && lastchar == '\r');

Wyświetl plik

@ -27,8 +27,8 @@
#include "debug.h"
#include "status.h"
#include "rx_extract.h"
#include "kmlserver.h"
extern void WefaxDestDirSet(Fl_File_Chooser *w, void *userdata);
extern void NvtxCatalogSet(Fl_File_Chooser *w, void *userdata);
#if USE_HAMLIB
#include "hamlib.h"
#endif
@ -2933,6 +2933,27 @@ if (o->value()) {
};
}
Fl_Check_Button *btnSynopAdifDecoding=(Fl_Check_Button *)0;
static void cb_btnSynopAdifDecoding(Fl_Check_Button* o, void*) {
progdefaults.SynopAdifDecoding=o->value();
progdefaults.changed = true;
}
Fl_Check_Button *btnSynopKmlDecoding=(Fl_Check_Button *)0;
static void cb_btnSynopKmlDecoding(Fl_Check_Button* o, void*) {
progdefaults.SynopKmlDecoding=o->value();
progdefaults.changed = true;
}
Fl_Check_Button *btnSynopInterleaved=(Fl_Check_Button *)0;
static void cb_btnSynopInterleaved(Fl_Check_Button* o, void*) {
progdefaults.SynopInterleaved=o->value();
progdefaults.changed = true;
}
Fl_Group *tabTHOR=(Fl_Group *)0;
Fl_Input2 *txtTHORSecondary=(Fl_Input2 *)0;
@ -3002,21 +3023,13 @@ static void cb_btnNvtxAdifLog(Fl_Check_Button* o, void*) {
progdefaults.changed = true;
}
Fl_Output *txtNvtxCatalog=(Fl_Output *)0;
Fl_Check_Button *btnNvtxKmlLog=(Fl_Check_Button *)0;
static void cb_txtNvtxCatalog(Fl_Output* o, void*) {
progdefaults.NVTX_Catalog=o->value();
static void cb_btnNvtxKmlLog(Fl_Check_Button* o, void*) {
progdefaults.NVTX_KmlLog=o->value();
progdefaults.changed = true;
}
Fl_Button *btnSelectNvtxCatalog=(Fl_Button *)0;
static void cb_btnSelectNvtxCatalog(Fl_Button*, void*) {
Fl_File_Chooser *fc = new Fl_File_Chooser(".",NULL,Fl_File_Chooser::SINGLE,"Navtex stations file");
fc->callback(NvtxCatalogSet);
fc->show();
}
Fl_Group *tabWefax=(Fl_Group *)0;
Fl_Check_Button *btnWefaxAdifLog=(Fl_Check_Button *)0;
@ -3916,11 +3929,13 @@ static void cb_chkRSidNotifyOnly(Fl_Check_Button* o, void*) {
progdefaults.rsid_notify_only = o->value();
notify_create_rsid_event(progdefaults.rsid_notify_only);
if (progdefaults.rsid_notify_only) {
chkRSidAutoDisable->value(0);
chkRSidAutoDisable->deactivate();
chkRetainFreqLock->deactivate();
chkDisableFreqChange->deactivate();
}
else {
chkRetainFreqLock->activate();
chkDisableFreqChange->activate();
}
else
chkRSidAutoDisable->activate();
progdefaults.changed = true;
}
@ -4362,6 +4377,11 @@ static void cb_btn_wx_full(Fl_Check_Button* o, void*) {
progdefaults.changed = true;
}
static void cb_End(Fl_Input* o, void*) {
progdefaults.wx_eoh = o->value();
progdefaults.changed = true;
}
Fl_Check_Button *btn_wx_station_name=(Fl_Check_Button *)0;
static void cb_btn_wx_station_name(Fl_Check_Button* o, void*) {
@ -4424,6 +4444,85 @@ static void cb_btn_metar_search(Fl_Button*, void*) {
get_METAR_station();
}
Fl_Group *tabKML=(Fl_Group *)0;
Fl_Input *btnKmlSaveDir=(Fl_Input *)0;
static void cb_btnKmlSaveDir(Fl_Input* o, void*) {
progdefaults.kml_save_dir=o->value();
progdefaults.changed = true;
kml_init();
}
Fl_Input *inputKmlRootFile=(Fl_Input *)0;
Fl_Counter *cntKmlMergeDistance=(Fl_Counter *)0;
static void cb_cntKmlMergeDistance(Fl_Counter* o, void*) {
progdefaults.kml_merge_distance = o->value();
progdefaults.changed = true;
kml_init();
}
Fl_Counter *cntKmlRetentionTime=(Fl_Counter *)0;
static void cb_cntKmlRetentionTime(Fl_Counter* o, void*) {
progdefaults.kml_retention_time = o->value();
progdefaults.changed = true;
kml_init();
}
Fl_Spinner2 *cntKmlRefreshInterval=(Fl_Spinner2 *)0;
static void cb_cntKmlRefreshInterval(Fl_Spinner2* o, void*) {
progdefaults.kml_refresh_interval = (int)(o->value());
progdefaults.changed = true;
kml_init();
}
Fl_Choice *selKmlBalloonStyle=(Fl_Choice *)0;
static void cb_selKmlBalloonStyle(Fl_Choice* o, void*) {
progdefaults.kml_balloon_style = o->value();
progdefaults.changed = true;
kml_init();
}
Fl_Input *btnKmlCommand=(Fl_Input *)0;
static void cb_btnKmlCommand(Fl_Input* o, void*) {
progdefaults.kml_command=o->value();
progdefaults.changed = true;
kml_init();
}
Fl_Button *btlTestKmlCommand=(Fl_Button *)0;
static void cb_btlTestKmlCommand(Fl_Button*, void*) {
KmlServer::SpawnProcess();
}
Fl_Button *btnSelectKmlDestDir=(Fl_Button *)0;
static void cb_btnSelectKmlDestDir(Fl_Button*, void*) {
Fl_File_Chooser *fc = new Fl_File_Chooser(".",NULL,Fl_File_Chooser::DIRECTORY,"Input File");
fc->callback(KmlDestDirSet);
fc->show();
}
Fl_Button *btlPurge=(Fl_Button *)0;
static void cb_btlPurge(Fl_Button*, void*) {
KmlServer::GetInstance()->Reset();
}
Fl_Check_Button *btnKmlPurgeOnStartup=(Fl_Check_Button *)0;
static void cb_btnKmlPurgeOnStartup(Fl_Check_Button* o, void*) {
progdefaults.kml_purge_on_startup = o->value();
progdefaults.changed = true;
}
Fl_Group *tabQRZ=(Fl_Group *)0;
Fl_Tabs *tabsQRZ=(Fl_Tabs *)0;
@ -4916,7 +5015,7 @@ Fl_Double_Window* ConfigureDialog() {
o->selection_color((Fl_Color)51);
o->labelsize(18);
o->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE));
{ tabsConfigure = new Fl_Tabs(-5, 0, 600, 372);
{ tabsConfigure = new Fl_Tabs(-5, 0, 600, 374);
tabsConfigure->color(FL_LIGHT1);
tabsConfigure->selection_color(FL_LIGHT1);
{ tabOperator = new Fl_Group(0, 25, 540, 345, _("Operator"));
@ -5039,7 +5138,6 @@ Fl_Double_Window* ConfigureDialog() {
{ tabsUI = new Fl_Tabs(0, 25, 540, 346);
tabsUI->selection_color(FL_LIGHT1);
{ tabBrowser = new Fl_Group(0, 50, 540, 320, _("Browser"));
tabBrowser->hide();
{ Fl_Group* o = new Fl_Group(24, 59, 496, 300);
o->box(FL_ENGRAVED_FRAME);
{ Fl_Spinner2* o = cntChannels = new Fl_Spinner2(40, 69, 50, 24, _("Channels, first channel starts at waterfall lower limit"));
@ -5742,6 +5840,7 @@ ab and newline are automatically included."));
tabWF_UI->end();
} // Fl_Group* tabWF_UI
{ tabColorsFonts = new Fl_Group(0, 50, 540, 320, _("Colors/Fonts"));
tabColorsFonts->hide();
{ tabsColors = new Fl_Tabs(0, 55, 540, 313);
{ Fl_Group* o = new Fl_Group(0, 80, 540, 283, _("Rx/Tx"));
{ CHARSETstatus = new Fl_Menu_Button(99, 109, 165, 26, _("Char set"));
@ -6425,7 +6524,6 @@ an merging"));
tabsModems->selection_color(FL_LIGHT1);
tabsModems->align(Fl_Align(FL_ALIGN_TOP_RIGHT));
{ tabCW = new Fl_Group(0, 50, 540, 320, _("CW"));
tabCW->hide();
{ tabsCW = new Fl_Tabs(0, 50, 540, 320);
tabsCW->selection_color(FL_LIGHT1);
{ Fl_Group* o = new Fl_Group(0, 75, 540, 295, _("General"));
@ -7396,6 +7494,7 @@ an merging"));
tabPSK->end();
} // Fl_Group* tabPSK
{ tabRTTY = new Fl_Group(0, 50, 540, 320, _("RTTY"));
tabRTTY->hide();
{ tabsRTTY = new Fl_Tabs(0, 50, 540, 320);
tabsRTTY->selection_color(FL_LIGHT1);
{ Fl_Group* o = new Fl_Group(0, 75, 540, 295, _("Rx"));
@ -7597,6 +7696,33 @@ ency"));
} // Fl_Check_Button* chkPseudoFSK
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(0, 75, 540, 295, _("Synop"));
o->align(Fl_Align(FL_ALIGN_TOP_LEFT));
o->hide();
{ Fl_Check_Button* o = btnSynopAdifDecoding = new Fl_Check_Button(124, 120, 126, 22, _("SYNOP to ADIF"));
btnSynopAdifDecoding->tooltip(_("Decodes SYNOP messages (Ex: Deutsche Wetterdienst) to ADIF log file"));
btnSynopAdifDecoding->down_box(FL_DOWN_BOX);
btnSynopAdifDecoding->callback((Fl_Callback*)cb_btnSynopAdifDecoding);
btnSynopAdifDecoding->align(Fl_Align(132|FL_ALIGN_INSIDE));
o->value(progdefaults.SynopAdifDecoding);
} // Fl_Check_Button* btnSynopAdifDecoding
{ Fl_Check_Button* o = btnSynopKmlDecoding = new Fl_Check_Button(124, 158, 119, 22, _("SYNOP to KML"));
btnSynopKmlDecoding->tooltip(_("Decodes SYNOP messages (Ex: Deutsche Wetterdienst) to KML documents (Ex: Goog\
le Earth)"));
btnSynopKmlDecoding->down_box(FL_DOWN_BOX);
btnSynopKmlDecoding->callback((Fl_Callback*)cb_btnSynopKmlDecoding);
btnSynopKmlDecoding->align(Fl_Align(132|FL_ALIGN_INSIDE));
o->value(progdefaults.SynopKmlDecoding);
} // Fl_Check_Button* btnSynopKmlDecoding
{ Fl_Check_Button* o = btnSynopInterleaved = new Fl_Check_Button(124, 197, 210, 22, _("Interleave SYNOP and text"));
btnSynopInterleaved->tooltip(_("Interleave text with decoded SYNOP messages, or replacement."));
btnSynopInterleaved->down_box(FL_DOWN_BOX);
btnSynopInterleaved->callback((Fl_Callback*)cb_btnSynopInterleaved);
btnSynopInterleaved->align(Fl_Align(132|FL_ALIGN_INSIDE));
o->value(progdefaults.SynopInterleaved);
} // Fl_Check_Button* btnSynopInterleaved
o->end();
} // Fl_Group* o
tabsRTTY->end();
} // Fl_Tabs* tabsRTTY
tabRTTY->end();
@ -7708,25 +7834,17 @@ ency"));
} // Fl_Group* tabTHOR
{ tabNavtex = new Fl_Group(0, 50, 540, 320, _("Navtex"));
tabNavtex->hide();
{ Fl_Group* o = new Fl_Group(6, 60, 527, 300);
o->box(FL_ENGRAVED_FRAME);
{ Fl_Check_Button* o = btnNvtxAdifLog = new Fl_Check_Button(81, 87, 235, 30, _("Log Navtex messages to Adif file"));
btnNvtxAdifLog->down_box(FL_DOWN_BOX);
btnNvtxAdifLog->callback((Fl_Callback*)cb_btnNvtxAdifLog);
o->value(progdefaults.NVTX_AdifLog);
} // Fl_Check_Button* btnNvtxAdifLog
{ Fl_Output* o = txtNvtxCatalog = new Fl_Output(81, 145, 270, 22, _("Navtex stations file:"));
txtNvtxCatalog->tooltip(_("Use Open to select descriptor file"));
txtNvtxCatalog->color(FL_LIGHT2);
txtNvtxCatalog->callback((Fl_Callback*)cb_txtNvtxCatalog);
txtNvtxCatalog->align(Fl_Align(FL_ALIGN_TOP_LEFT));
o->value(fl_filename_name(progdefaults.NVTX_Catalog.c_str()));
} // Fl_Output* txtNvtxCatalog
{ btnSelectNvtxCatalog = new Fl_Button(386, 147, 80, 20, _("Directory..."));
btnSelectNvtxCatalog->callback((Fl_Callback*)cb_btnSelectNvtxCatalog);
} // Fl_Button* btnSelectNvtxCatalog
o->end();
} // Fl_Group* o
{ Fl_Check_Button* o = btnNvtxAdifLog = new Fl_Check_Button(83, 150, 235, 30, _("Log Navtex messages to Adif file"));
btnNvtxAdifLog->down_box(FL_DOWN_BOX);
btnNvtxAdifLog->callback((Fl_Callback*)cb_btnNvtxAdifLog);
o->value(progdefaults.NVTX_AdifLog);
} // Fl_Check_Button* btnNvtxAdifLog
{ Fl_Check_Button* o = btnNvtxKmlLog = new Fl_Check_Button(82, 196, 270, 30, _("Log Navtex messages to KML"));
btnNvtxKmlLog->tooltip(_("Logs messages to Keyhole Markup Language (Google Earth, Marble, Gaia, etc...)"));
btnNvtxKmlLog->down_box(FL_DOWN_BOX);
btnNvtxKmlLog->callback((Fl_Callback*)cb_btnNvtxKmlLog);
o->value(progdefaults.NVTX_KmlLog);
} // Fl_Check_Button* btnNvtxKmlLog
tabNavtex->end();
} // Fl_Group* tabNavtex
{ tabWefax = new Fl_Group(0, 50, 540, 320, _("Wefax"));
@ -8563,36 +8681,36 @@ nce.\nYou may change the state from either location.\n..."));
} // Fl_Tabs* tabsSoundCard
tabSoundCard->end();
} // Fl_Group* tabSoundCard
{ tabID = new Fl_Group(0, 23, 540, 348, _("ID"));
{ tabID = new Fl_Group(0, 23, 540, 350, _("ID"));
tabID->hide();
{ tabsID = new Fl_Tabs(0, 23, 540, 345);
{ tabRsID = new Fl_Group(0, 48, 540, 320, _("RsID"));
{ Fl_Group* o = new Fl_Group(2, 55, 535, 193, _("Reed-Solomon ID (Rx)"));
{ tabsID = new Fl_Tabs(0, 23, 540, 347);
{ tabRsID = new Fl_Group(0, 50, 540, 320, _("RsID"));
{ Fl_Group* o = new Fl_Group(2, 55, 535, 210, _("Reed-Solomon ID (Rx)"));
o->box(FL_ENGRAVED_FRAME);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
{ chkRSidNotifyOnly = new Fl_Check_Button(11, 88, 90, 20, _("Notify only"));
{ chkRSidNotifyOnly = new Fl_Check_Button(10, 112, 168, 20, _("Notify only"));
chkRSidNotifyOnly->tooltip(_("Check this to be notified when an RSID is received\nwithout changing modem an\
d frequency"));
chkRSidNotifyOnly->down_box(FL_DOWN_BOX);
chkRSidNotifyOnly->callback((Fl_Callback*)cb_chkRSidNotifyOnly);
chkRSidNotifyOnly->value(progdefaults.rsid_notify_only);
} // Fl_Check_Button* chkRSidNotifyOnly
{ bRSIDRxModes = new Fl_Button(348, 86, 130, 24, _("Receive modes"));
{ bRSIDRxModes = new Fl_Button(10, 81, 130, 24, _("Receive modes"));
bRSIDRxModes->callback((Fl_Callback*)cb_bRSIDRxModes);
} // Fl_Button* bRSIDRxModes
{ Fl_Check_Button* o = chkRSidWideSearch = new Fl_Check_Button(11, 119, 90, 20, _("Searches passband"));
{ Fl_Check_Button* o = chkRSidWideSearch = new Fl_Check_Button(10, 143, 203, 20, _("Searches passband"));
chkRSidWideSearch->tooltip(_("ON - search over entire waterfall\nOFF - limit search to +/- 200 Hz"));
chkRSidWideSearch->down_box(FL_DOWN_BOX);
chkRSidWideSearch->callback((Fl_Callback*)cb_chkRSidWideSearch);
o->value(progdefaults.rsidWideSearch);
} // Fl_Check_Button* chkRSidWideSearch
{ chkRSidMark = new Fl_Check_Button(11, 151, 90, 20, _("Mark prev freq/mode"));
{ chkRSidMark = new Fl_Check_Button(10, 175, 203, 20, _("Mark prev freq/mode"));
chkRSidMark->tooltip(_("Insert RX text marker before\nchanging frequency and modem"));
chkRSidMark->down_box(FL_DOWN_BOX);
chkRSidMark->callback((Fl_Callback*)cb_chkRSidMark);
chkRSidMark->value(progdefaults.rsid_mark);
} // Fl_Check_Button* chkRSidMark
{ chkRSidAutoDisable = new Fl_Check_Button(11, 183, 90, 20, _("Disables detector"));
{ chkRSidAutoDisable = new Fl_Check_Button(10, 207, 203, 20, _("Disables detector"));
chkRSidAutoDisable->tooltip(_("Disable further detection when RSID is received"));
chkRSidAutoDisable->down_box(FL_DOWN_BOX);
chkRSidAutoDisable->callback((Fl_Callback*)cb_chkRSidAutoDisable);
@ -8600,9 +8718,9 @@ d frequency"));
chkRSidAutoDisable->value(progdefaults.rsid_auto_disable);
if (progdefaults.rsid_notify_only) chkRSidAutoDisable->deactivate();
} // Fl_Check_Button* chkRSidAutoDisable
{ Fl_Value_Slider2* o = sldrRSIDresolution = new Fl_Value_Slider2(12, 215, 145, 22, _("Sensitivity"));
sldrRSIDresolution->tooltip(_("2 = low sensitivity / decreased false detection\n5 = high sensitivity / incre\
ased false detection"));
{ Fl_Value_Slider2* o = sldrRSIDresolution = new Fl_Value_Slider2(10, 233, 145, 22, _("Sensitivity"));
sldrRSIDresolution->tooltip(_("2 = normal sensitivity / decreased false detection\n5 = high sensitivity / in\
creased false detection"));
sldrRSIDresolution->type(1);
sldrRSIDresolution->box(FL_DOWN_BOX);
sldrRSIDresolution->color(FL_BACKGROUND_COLOR);
@ -8611,10 +8729,10 @@ ased false detection"));
sldrRSIDresolution->labelfont(0);
sldrRSIDresolution->labelsize(14);
sldrRSIDresolution->labelcolor(FL_FOREGROUND_COLOR);
sldrRSIDresolution->minimum(1);
sldrRSIDresolution->minimum(2);
sldrRSIDresolution->maximum(5);
sldrRSIDresolution->step(1);
sldrRSIDresolution->value(5);
sldrRSIDresolution->value(2);
sldrRSIDresolution->textsize(14);
sldrRSIDresolution->callback((Fl_Callback*)cb_sldrRSIDresolution);
sldrRSIDresolution->align(Fl_Align(FL_ALIGN_RIGHT));
@ -8622,7 +8740,7 @@ ased false detection"));
o->value(progdefaults.rsid_resolution);
o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);
} // Fl_Value_Slider2* sldrRSIDresolution
{ Fl_Value_Slider2* o = sldrRSIDsquelch = new Fl_Value_Slider2(246, 215, 145, 22, _("Squelch open (sec)"));
{ Fl_Value_Slider2* o = sldrRSIDsquelch = new Fl_Value_Slider2(246, 233, 145, 22, _("Squelch open (sec)"));
sldrRSIDsquelch->tooltip(_("Open squelch for nn sec if RSID detected"));
sldrRSIDsquelch->type(1);
sldrRSIDsquelch->box(FL_DOWN_BOX);
@ -8641,30 +8759,36 @@ ased false detection"));
o->value(progdefaults.rsid_squelch);
o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);
} // Fl_Value_Slider2* sldrRSIDsquelch
{ Fl_Check_Button* o = chkRSidShowAlert = new Fl_Check_Button(246, 119, 90, 20, _("Disable alert dialog"));
{ Fl_Check_Button* o = chkRSidShowAlert = new Fl_Check_Button(246, 143, 203, 20, _("Disable alert dialog"));
chkRSidShowAlert->tooltip(_("Do not show RsID alert dialog box"));
chkRSidShowAlert->down_box(FL_DOWN_BOX);
chkRSidShowAlert->callback((Fl_Callback*)cb_chkRSidShowAlert);
o->value(progdefaults.disable_rsid_warning_dialog_box);
} // Fl_Check_Button* chkRSidShowAlert
{ Fl_Check_Button* o = chkRetainFreqLock = new Fl_Check_Button(246, 151, 90, 20, _("Retain tx freq lock"));
chkRetainFreqLock->tooltip(_("Do not show RsID alert dialog box"));
{ Fl_Check_Button* o = chkRetainFreqLock = new Fl_Check_Button(246, 175, 203, 20, _("Retain tx freq lock"));
chkRetainFreqLock->tooltip(_("Retain TX lock frequency (Lk) when changing to RX RsID frequency"));
chkRetainFreqLock->down_box(FL_DOWN_BOX);
chkRetainFreqLock->callback((Fl_Callback*)cb_chkRetainFreqLock);
o->value(progdefaults.retain_freq_lock);
} // Fl_Check_Button* chkRetainFreqLock
{ Fl_Check_Button* o = chkDisableFreqChange = new Fl_Check_Button(246, 183, 90, 20, _("Disable freq change"));
chkDisableFreqChange->tooltip(_("Do not show RsID alert dialog box"));
{ Fl_Check_Button* o = chkDisableFreqChange = new Fl_Check_Button(246, 207, 203, 20, _("Disable freq change"));
chkDisableFreqChange->tooltip(_("Do not automatically change to RX RsID frequency"));
chkDisableFreqChange->down_box(FL_DOWN_BOX);
chkDisableFreqChange->callback((Fl_Callback*)cb_chkDisableFreqChange);
o->value(progdefaults.disable_rsid_freq_change);
} // Fl_Check_Button* chkDisableFreqChange
{ Fl_Group* o = new Fl_Group(186, 74, 330, 60, _("The RsID notification message contents and \ndisplay characteristics are conf\
igured on the\n\"Notifications\" configure dialog."));
o->box(FL_BORDER_BOX);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
o->end();
} // Fl_Group* o
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(3, 250, 265, 97, _("Pre-Signal Tone"));
{ Fl_Group* o = new Fl_Group(3, 267, 265, 97, _("Pre-Signal Tone"));
o->box(FL_ENGRAVED_FRAME);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
{ Fl_Counter* o = val_pretone = new Fl_Counter(59, 288, 140, 21, _("Seconds"));
{ Fl_Counter* o = val_pretone = new Fl_Counter(59, 305, 140, 21, _("Seconds"));
val_pretone->tooltip(_("Use for triggering amplifier carrier detect"));
val_pretone->minimum(0);
val_pretone->maximum(10);
@ -8673,13 +8797,13 @@ ased false detection"));
} // Fl_Counter* val_pretone
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(271, 250, 265, 97, _("Reed-Solomon ID (Tx)"));
{ Fl_Group* o = new Fl_Group(271, 267, 265, 97, _("Reed-Solomon ID (Tx)"));
o->box(FL_ENGRAVED_FRAME);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
{ bRSIDTxModes = new Fl_Button(348, 277, 130, 24, _("Transmit modes"));
{ bRSIDTxModes = new Fl_Button(348, 294, 130, 24, _("Transmit modes"));
bRSIDTxModes->callback((Fl_Callback*)cb_bRSIDTxModes);
} // Fl_Button* bRSIDTxModes
{ Fl_Check_Button* o = btn_post_rsid = new Fl_Check_Button(348, 312, 97, 17, _("End of xmt ID"));
{ Fl_Check_Button* o = btn_post_rsid = new Fl_Check_Button(348, 329, 97, 17, _("End of xmt ID"));
btn_post_rsid->tooltip(_("Add RsID signal to end of transmission"));
btn_post_rsid->down_box(FL_DOWN_BOX);
btn_post_rsid->callback((Fl_Callback*)cb_btn_post_rsid);
@ -8689,7 +8813,7 @@ ased false detection"));
} // Fl_Group* o
tabRsID->end();
} // Fl_Group* tabRsID
{ tabVideoID = new Fl_Group(0, 48, 540, 320, _("Video"));
{ tabVideoID = new Fl_Group(0, 50, 540, 320, _("Video"));
tabVideoID->hide();
{ Fl_Group* o = new Fl_Group(2, 55, 536, 189, _("Video Preamble ID"));
o->box(FL_ENGRAVED_FRAME);
@ -8765,7 +8889,7 @@ ased false detection"));
} // Fl_Group* o
tabVideoID->end();
} // Fl_Group* tabVideoID
{ tabCwID = new Fl_Group(0, 48, 540, 320, _("CW"));
{ tabCwID = new Fl_Group(0, 50, 540, 320, _("CW"));
tabCwID->hide();
{ sld = new Fl_Group(2, 56, 536, 127, _("CW Postamble ID"));
sld->box(FL_ENGRAVED_FRAME);
@ -9205,73 +9329,80 @@ ased false detection"));
{ Fl_Group* o = new Fl_Group(27, 60, 490, 300, _("Weather query specification"));
o->box(FL_ENGRAVED_FRAME);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
{ Fl_Input* o = inpWXsta = new Fl_Input(92, 92, 43, 24, _("METAR station ID code"));
{ Fl_Input* o = inpWXsta = new Fl_Input(66, 92, 43, 24, _("METAR station ID code"));
inpWXsta->tooltip(_("for example KMDQ for \nHuntsville-Madison Executive Airport, AL"));
inpWXsta->callback((Fl_Callback*)cb_inpWXsta);
inpWXsta->align(Fl_Align(FL_ALIGN_RIGHT));
o->value(progdefaults.wx_sta.c_str());
} // Fl_Input* inpWXsta
{ Fl_Check_Button* o = btn_wx_full = new Fl_Check_Button(229, 130, 70, 15, _("Full report"));
{ Fl_Check_Button* o = btn_wx_full = new Fl_Check_Button(230, 130, 70, 15, _("Full report"));
btn_wx_full->tooltip(_("Insert full METAR report"));
btn_wx_full->down_box(FL_DOWN_BOX);
btn_wx_full->callback((Fl_Callback*)cb_btn_wx_full);
o->value(progdefaults.wx_full);
} // Fl_Check_Button* btn_wx_full
{ Fl_Check_Button* o = btn_wx_station_name = new Fl_Check_Button(229, 158, 70, 15, _("METAR station location"));
{ Fl_Input* o = new Fl_Input(230, 156, 266, 25, _("End of header string:"));
o->tooltip(_("Text defining end of METAR header\nTypically \'Connection: close\'\nUsed to s\
earch for station name"));
o->callback((Fl_Callback*)cb_End);
o->when(FL_WHEN_CHANGED);
o->value(progdefaults.wx_eoh.c_str());
} // Fl_Input* o
{ Fl_Check_Button* o = btn_wx_station_name = new Fl_Check_Button(230, 192, 70, 15, _("METAR station location"));
btn_wx_station_name->tooltip(_("Add geopolitical name of METAR station"));
btn_wx_station_name->down_box(FL_DOWN_BOX);
btn_wx_station_name->callback((Fl_Callback*)cb_btn_wx_station_name);
o->value(progdefaults.wx_station_name);
} // Fl_Check_Button* btn_wx_station_name
{ Fl_Check_Button* o = btn_wx_condx = new Fl_Check_Button(229, 186, 70, 15, _("Conditions"));
{ Fl_Check_Button* o = btn_wx_condx = new Fl_Check_Button(230, 218, 70, 15, _("Conditions"));
btn_wx_condx->tooltip(_("current wx conditions"));
btn_wx_condx->down_box(FL_DOWN_BOX);
btn_wx_condx->callback((Fl_Callback*)cb_btn_wx_condx);
o->value(progdefaults.wx_condx);
} // Fl_Check_Button* btn_wx_condx
{ Fl_Check_Button* o = btn_wx_fahrenheit = new Fl_Check_Button(227, 214, 70, 15, _("Fahrenheit"));
{ Fl_Check_Button* o = btn_wx_fahrenheit = new Fl_Check_Button(230, 245, 70, 15, _("Fahrenheit"));
btn_wx_fahrenheit->tooltip(_("report Fahrenheit"));
btn_wx_fahrenheit->down_box(FL_DOWN_BOX);
btn_wx_fahrenheit->callback((Fl_Callback*)cb_btn_wx_fahrenheit);
o->value(progdefaults.wx_fahrenheit);
} // Fl_Check_Button* btn_wx_fahrenheit
{ Fl_Check_Button* o = btn_wx_celsius = new Fl_Check_Button(358, 214, 70, 15, _("Celsius"));
{ Fl_Check_Button* o = btn_wx_celsius = new Fl_Check_Button(358, 245, 70, 15, _("Celsius"));
btn_wx_celsius->tooltip(_("report Celsius"));
btn_wx_celsius->down_box(FL_DOWN_BOX);
btn_wx_celsius->callback((Fl_Callback*)cb_btn_wx_celsius);
o->value(progdefaults.wx_celsius);
} // Fl_Check_Button* btn_wx_celsius
{ Fl_Check_Button* o = btn_wx_mph = new Fl_Check_Button(227, 242, 70, 15, _("Miles / Hour"));
{ Fl_Check_Button* o = btn_wx_mph = new Fl_Check_Button(230, 271, 70, 15, _("Miles / Hour"));
btn_wx_mph->tooltip(_("report miles per hour"));
btn_wx_mph->down_box(FL_DOWN_BOX);
btn_wx_mph->callback((Fl_Callback*)cb_btn_wx_mph);
o->value(progdefaults.wx_mph);
} // Fl_Check_Button* btn_wx_mph
{ Fl_Check_Button* o = btn_wx_kph = new Fl_Check_Button(358, 242, 70, 15, _("kilometers / hour"));
{ Fl_Check_Button* o = btn_wx_kph = new Fl_Check_Button(358, 271, 70, 15, _("kilometers / hour"));
btn_wx_kph->tooltip(_("report kilometers per hour"));
btn_wx_kph->down_box(FL_DOWN_BOX);
btn_wx_kph->callback((Fl_Callback*)cb_btn_wx_kph);
o->value(progdefaults.wx_kph);
} // Fl_Check_Button* btn_wx_kph
{ Fl_Check_Button* o = btn_wx_inches = new Fl_Check_Button(227, 271, 70, 15, _("Inches Mg."));
{ Fl_Check_Button* o = btn_wx_inches = new Fl_Check_Button(230, 298, 70, 15, _("Inches Mg."));
btn_wx_inches->tooltip(_("report inches mercury"));
btn_wx_inches->down_box(FL_DOWN_BOX);
btn_wx_inches->callback((Fl_Callback*)cb_btn_wx_inches);
o->value(progdefaults.wx_inches);
} // Fl_Check_Button* btn_wx_inches
{ Fl_Check_Button* o = btn_wx_mbars = new Fl_Check_Button(358, 271, 70, 15, _("mbars"));
{ Fl_Check_Button* o = btn_wx_mbars = new Fl_Check_Button(358, 298, 70, 15, _("mbars"));
btn_wx_mbars->tooltip(_("report millibars"));
btn_wx_mbars->down_box(FL_DOWN_BOX);
btn_wx_mbars->callback((Fl_Callback*)cb_btn_wx_mbars);
o->value(progdefaults.wx_mbars);
} // Fl_Check_Button* btn_wx_mbars
{ Fl_Box* o = new Fl_Box(67, 212, 156, 19, _("Temperature"));
{ Fl_Box* o = new Fl_Box(65, 245, 156, 19, _("Temperature"));
o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
} // Fl_Box* o
{ Fl_Box* o = new Fl_Box(67, 240, 156, 19, _("Wind speed/dir"));
{ Fl_Box* o = new Fl_Box(65, 271, 156, 19, _("Wind speed/dir"));
o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
} // Fl_Box* o
{ Fl_Box* o = new Fl_Box(67, 269, 156, 19, _("Barometric pressure"));
{ Fl_Box* o = new Fl_Box(65, 298, 156, 19, _("Barometric pressure"));
o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
} // Fl_Box* o
{ btn_metar_search = new Fl_Button(308, 92, 130, 24, _("Search on web"));
@ -9281,15 +9412,100 @@ ased false detection"));
} // Fl_Group* o
tabWX->end();
} // Fl_Group* tabWX
{ tabKML = new Fl_Group(0, 50, 540, 320, _("KML"));
tabKML->hide();
{ Fl_Input* o = btnKmlSaveDir = new Fl_Input(26, 75, 390, 24, _("KML files directory"));
btnKmlSaveDir->tooltip(_("Where generated KML documents are stored."));
btnKmlSaveDir->callback((Fl_Callback*)cb_btnKmlSaveDir);
btnKmlSaveDir->align(Fl_Align(69));
o->value(progdefaults.kml_save_dir.c_str());
} // Fl_Input* btnKmlSaveDir
{ Fl_Input* o = inputKmlRootFile = new Fl_Input(25, 119, 300, 24, _("KML root file"));
inputKmlRootFile->align(Fl_Align(FL_ALIGN_TOP_LEFT));
o->value("fldigi.kml");
} // Fl_Input* inputKmlRootFile
{ Fl_Counter* o = cntKmlMergeDistance = new Fl_Counter(26, 155, 100, 24, _("Minimum distance for splitting aliases (Meters)"));
cntKmlMergeDistance->tooltip(_("Minimum distance for splitting alias nodes (Meters)"));
cntKmlMergeDistance->minimum(0);
cntKmlMergeDistance->maximum(100000);
cntKmlMergeDistance->step(10);
cntKmlMergeDistance->value(1000);
cntKmlMergeDistance->callback((Fl_Callback*)cb_cntKmlMergeDistance);
cntKmlMergeDistance->align(Fl_Align(FL_ALIGN_RIGHT));
o->value(progdefaults.kml_merge_distance);
o->lstep(1000);
} // Fl_Counter* cntKmlMergeDistance
{ Fl_Counter* o = cntKmlRetentionTime = new Fl_Counter(25, 191, 100, 24, _("Data retention time, in hours (0 for no limit)"));
cntKmlRetentionTime->tooltip(_("Number of hours data is kept for each node. Zero means keeping everything."));
cntKmlRetentionTime->minimum(0);
cntKmlRetentionTime->maximum(500);
cntKmlRetentionTime->step(1);
cntKmlRetentionTime->callback((Fl_Callback*)cb_cntKmlRetentionTime);
cntKmlRetentionTime->align(Fl_Align(FL_ALIGN_RIGHT));
o->value(progdefaults.kml_retention_time);
o->lstep(24);
} // Fl_Counter* cntKmlRetentionTime
{ Fl_Spinner2* o = cntKmlRefreshInterval = new Fl_Spinner2(24, 227, 50, 24, _("KML refresh interval (seconds)"));
cntKmlRefreshInterval->tooltip(_("Refresh time interval written in KML file (Seconds)"));
cntKmlRefreshInterval->box(FL_NO_BOX);
cntKmlRefreshInterval->color(FL_BACKGROUND_COLOR);
cntKmlRefreshInterval->selection_color(FL_BACKGROUND_COLOR);
cntKmlRefreshInterval->labeltype(FL_NORMAL_LABEL);
cntKmlRefreshInterval->labelfont(0);
cntKmlRefreshInterval->labelsize(14);
cntKmlRefreshInterval->labelcolor(FL_FOREGROUND_COLOR);
cntKmlRefreshInterval->value(10);
cntKmlRefreshInterval->callback((Fl_Callback*)cb_cntKmlRefreshInterval);
cntKmlRefreshInterval->align(Fl_Align(FL_ALIGN_RIGHT));
cntKmlRefreshInterval->when(FL_WHEN_RELEASE);
o->minimum(1); o->maximum(3600); o->step(1);
o->value(progdefaults.kml_refresh_interval);
o->labelsize(FL_NORMAL_SIZE);
} // Fl_Spinner2* cntKmlRefreshInterval
{ Fl_Choice* o = selKmlBalloonStyle = new Fl_Choice(24, 263, 201, 24, _("KML balloon display style"));
selKmlBalloonStyle->tooltip(_("KML balloon in plain text, or HTML, in plain tables or matrices."));
selKmlBalloonStyle->down_box(FL_BORDER_BOX);
selKmlBalloonStyle->callback((Fl_Callback*)cb_selKmlBalloonStyle);
selKmlBalloonStyle->align(Fl_Align(FL_ALIGN_RIGHT));
selKmlBalloonStyle->when(FL_WHEN_CHANGED);
o->add("Plain text|HTML tables|Single HTML matrix");o->value(progdefaults.kml_balloon_style);
} // Fl_Choice* selKmlBalloonStyle
{ Fl_Input* o = btnKmlCommand = new Fl_Input(24, 299, 246, 24, _("Command run on KML creation"));
btnKmlCommand->tooltip(_("Command started when KML files are generated. Subprocesses are started once, \
and restarted if needed."));
btnKmlCommand->callback((Fl_Callback*)cb_btnKmlCommand);
btnKmlCommand->align(Fl_Align(72));
o->value(progdefaults.kml_command.c_str());
} // Fl_Input* btnKmlCommand
{ btlTestKmlCommand = new Fl_Button(24, 335, 191, 24, _("Test command"));
btlTestKmlCommand->tooltip(_("Execute command on KML files."));
btlTestKmlCommand->callback((Fl_Callback*)cb_btlTestKmlCommand);
} // Fl_Button* btlTestKmlCommand
{ btnSelectKmlDestDir = new Fl_Button(425, 75, 101, 24, _("Change dir..."));
btnSelectKmlDestDir->tooltip(_("Choose directory to store KML documents"));
btnSelectKmlDestDir->callback((Fl_Callback*)cb_btnSelectKmlDestDir);
} // Fl_Button* btnSelectKmlDestDir
{ btlPurge = new Fl_Button(336, 119, 190, 24, _("Cleanup KML data now !"));
btlPurge->tooltip(_("Cleanups KML documents, empties Google Earth display."));
btlPurge->callback((Fl_Callback*)cb_btlPurge);
} // Fl_Button* btlPurge
{ Fl_Check_Button* o = btnKmlPurgeOnStartup = new Fl_Check_Button(322, 231, 172, 15, _("Cleanup on startup"));
btnKmlPurgeOnStartup->tooltip(_("Empties KML documents when starting program."));
btnKmlPurgeOnStartup->down_box(FL_DOWN_BOX);
btnKmlPurgeOnStartup->callback((Fl_Callback*)cb_btnKmlPurgeOnStartup);
o->value(progdefaults.kml_purge_on_startup);
} // Fl_Check_Button* btnKmlPurgeOnStartup
tabKML->end();
} // Fl_Group* tabKML
tabsMisc->end();
} // Fl_Tabs* tabsMisc
tabMisc->end();
} // Fl_Group* tabMisc
{ tabQRZ = new Fl_Group(0, 25, 540, 345, _("Web"));
{ tabQRZ = new Fl_Group(0, 25, 540, 349, _("Web"));
tabQRZ->tooltip(_("Callsign database"));
tabQRZ->hide();
{ tabsQRZ = new Fl_Tabs(0, 25, 540, 345);
{ Fl_Group* o = new Fl_Group(0, 46, 540, 324, _("Call Lookup"));
{ tabsQRZ = new Fl_Tabs(0, 25, 540, 349);
{ Fl_Group* o = new Fl_Group(0, 50, 540, 324, _("Call Lookup"));
{ Fl_Group* o = new Fl_Group(27, 52, 490, 122, _("Web Browser lookup"));
o->box(FL_ENGRAVED_FRAME);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
@ -9829,11 +10045,11 @@ void WefaxDestDirSet(Fl_File_Chooser *w, void *userdata) {
}
}
void NvtxCatalogSet(Fl_File_Chooser *w, void *userdata) {
void KmlDestDirSet(Fl_File_Chooser *w, void *userdata) {
/* http://www.fltk.org/documentation.php/doc-1.1/Fl_File_Chooser.html */
if( ( w->value() != NULL ) && ( ! w->shown() ) ) {
txtNvtxCatalog->value( w->value() );
txtNvtxCatalog->redraw();
cb_txtNvtxCatalog( txtNvtxCatalog, NULL );
btnKmlSaveDir->value( w->value() );
btnKmlSaveDir->redraw();
cb_btnKmlSaveDir( btnKmlSaveDir, NULL );
}
}

Wyświetl plik

@ -104,10 +104,10 @@ decl {\#include "status.h"} {private local
decl {\#include "rx_extract.h"} {private local
}
decl {extern void WefaxDestDirSet(Fl_File_Chooser *w, void *userdata);} {private local
decl {\#include "kmlserver.h"} {private local
}
decl {extern void NvtxCatalogSet(Fl_File_Chooser *w, void *userdata);} {private local
decl {extern void WefaxDestDirSet(Fl_File_Chooser *w, void *userdata);} {private local
}
decl {\#if USE_HAMLIB
@ -307,7 +307,7 @@ static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {}
xywh {627 44 540 400} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible
} {
Fl_Tabs tabsConfigure {open
xywh {-5 0 600 372} color 50 selection_color 50
xywh {-5 0 600 374} color 50 selection_color 50
} {
Fl_Group tabOperator {
label Operator
@ -417,7 +417,7 @@ btnApplyConfig->activate();}
} {
Fl_Group tabBrowser {
label Browser
xywh {0 50 540 320} hide
xywh {0 50 540 320}
} {
Fl_Group {} {open
xywh {24 59 496 300} box ENGRAVED_FRAME
@ -1280,7 +1280,7 @@ WF_UI();}
}
Fl_Group tabColorsFonts {
label {Colors/Fonts} open
xywh {0 50 540 320}
xywh {0 50 540 320} hide
} {
Fl_Tabs tabsColors {open
xywh {0 55 540 313}
@ -2555,8 +2555,8 @@ behaves inside the waterfall} xywh {34 207 150 22} down_box BORDER_BOX align 8
xywh {0 25 540 347} selection_color 50 align 9
} {
Fl_Group tabCW {
label CW
xywh {0 50 540 320} hide
label CW selected
xywh {0 50 540 320}
} {
Fl_Tabs tabsCW {open
xywh {0 50 540 320} selection_color 50
@ -3407,13 +3407,13 @@ progdefaults.changed = true;}
}
Fl_Group tabRTTY {
label RTTY
xywh {0 50 540 320}
xywh {0 50 540 320} hide
} {
Fl_Tabs tabsRTTY {open
xywh {0 50 540 320} selection_color 50
} {
Fl_Group {} {
label Rx open selected
label Rx open
xywh {0 75 540 295} align 5
} {
Fl_Group {} {
@ -3641,6 +3641,32 @@ if (o->value()) {
code0 {o->value(progdefaults.PseudoFSK);}
}
}
Fl_Group {} {
label Synop open
xywh {0 75 540 295} align 5 hide
} {
Fl_Check_Button btnSynopAdifDecoding {
label {SYNOP to ADIF}
callback {progdefaults.SynopAdifDecoding=o->value();
progdefaults.changed = true;}
tooltip {Decodes SYNOP messages (Ex: Deutsche Wetterdienst) to ADIF log file} xywh {124 120 126 22} down_box DOWN_BOX align 148
code0 {o->value(progdefaults.SynopAdifDecoding);}
}
Fl_Check_Button btnSynopKmlDecoding {
label {SYNOP to KML}
callback {progdefaults.SynopKmlDecoding=o->value();
progdefaults.changed = true;}
tooltip {Decodes SYNOP messages (Ex: Deutsche Wetterdienst) to KML documents (Ex: Google Earth)} xywh {124 158 119 22} down_box DOWN_BOX align 148
code0 {o->value(progdefaults.SynopKmlDecoding);}
}
Fl_Check_Button btnSynopInterleaved {
label {Interleave SYNOP and text}
callback {progdefaults.SynopInterleaved=o->value();
progdefaults.changed = true;}
tooltip {Interleave text with decoded SYNOP messages, or replacement.} xywh {124 197 210 22} down_box DOWN_BOX align 148
code0 {o->value(progdefaults.SynopInterleaved);}
}
}
}
}
Fl_Group tabTHOR {
@ -3725,30 +3751,19 @@ progdefaults.changed = true;}
label Navtex
xywh {0 50 540 320} hide
} {
Fl_Group {} {open
xywh {6 60 527 300} box ENGRAVED_FRAME
} {
Fl_Check_Button btnNvtxAdifLog {
label {Log Navtex messages to Adif file}
callback {progdefaults.NVTX_AdifLog=o->value();
Fl_Check_Button btnNvtxAdifLog {
label {Log Navtex messages to Adif file}
callback {progdefaults.NVTX_AdifLog=o->value();
progdefaults.changed = true;}
xywh {81 87 235 30} down_box DOWN_BOX
code0 {o->value(progdefaults.NVTX_AdifLog);}
}
Fl_Output txtNvtxCatalog {
label {Navtex stations file:}
callback {progdefaults.NVTX_Catalog=o->value();
xywh {83 150 235 30} down_box DOWN_BOX
code0 {o->value(progdefaults.NVTX_AdifLog);}
}
Fl_Check_Button btnNvtxKmlLog {
label {Log Navtex messages to KML}
callback {progdefaults.NVTX_KmlLog=o->value();
progdefaults.changed = true;}
tooltip {Use Open to select descriptor file} xywh {81 145 270 22} color 52 align 5
code0 {o->value(fl_filename_name(progdefaults.NVTX_Catalog.c_str()));}
}
Fl_Button btnSelectNvtxCatalog {
label {Directory...}
callback {Fl_File_Chooser *fc = new Fl_File_Chooser(".",NULL,Fl_File_Chooser::SINGLE,"Navtex stations file");
fc->callback(NvtxCatalogSet);
fc->show();}
xywh {386 147 80 20}
}
tooltip {Logs messages to Keyhole Markup Language (Google Earth, Marble, Gaia, etc...)} xywh {82 196 270 30} down_box DOWN_BOX
code0 {o->value(progdefaults.NVTX_KmlLog);}
}
}
Fl_Group tabWefax {
@ -4778,32 +4793,34 @@ if (o->value()) {
}
Fl_Group tabID {
label ID open
xywh {0 23 540 348} hide
xywh {0 23 540 350} hide
} {
Fl_Tabs tabsID {open
xywh {0 23 540 345}
xywh {0 23 540 347}
} {
Fl_Group tabRsID {
label RsID open
xywh {0 48 540 320}
xywh {0 50 540 320}
} {
Fl_Group {} {
label {Reed-Solomon ID (Rx)} open
xywh {2 55 535 193} box ENGRAVED_FRAME align 21
xywh {2 55 535 210} box ENGRAVED_FRAME align 21
} {
Fl_Check_Button chkRSidNotifyOnly {
label {Notify only}
callback {progdefaults.rsid_notify_only = o->value();
notify_create_rsid_event(progdefaults.rsid_notify_only);
if (progdefaults.rsid_notify_only) {
chkRSidAutoDisable->value(0);
chkRSidAutoDisable->deactivate();
chkRetainFreqLock->deactivate();
chkDisableFreqChange->deactivate();
}
else {
chkRetainFreqLock->activate();
chkDisableFreqChange->activate();
}
else
chkRSidAutoDisable->activate();
progdefaults.changed = true;}
tooltip {Check this to be notified when an RSID is received
without changing modem and frequency} xywh {11 88 90 20} down_box DOWN_BOX
without changing modem and frequency} xywh {10 112 168 20} down_box DOWN_BOX
code0 {chkRSidNotifyOnly->value(progdefaults.rsid_notify_only);}
}
Fl_Button bRSIDRxModes {
@ -4812,14 +4829,14 @@ without changing modem and frequency} xywh {11 88 90 20} down_box DOWN_BOX
mode_browser->callback(0);
mode_browser->show(&progdefaults.rsid_rx_modes);
progdefaults.changed = true;}
xywh {348 86 130 24}
xywh {10 81 130 24}
}
Fl_Check_Button chkRSidWideSearch {
label {Searches passband}
callback {progdefaults.rsidWideSearch=o->value();
progdefaults.changed = true;}
tooltip {ON - search over entire waterfall
OFF - limit search to +/- 200 Hz} xywh {11 119 90 20} down_box DOWN_BOX
OFF - limit search to +/- 200 Hz} xywh {10 143 203 20} down_box DOWN_BOX
code0 {o->value(progdefaults.rsidWideSearch);}
}
Fl_Check_Button chkRSidMark {
@ -4827,14 +4844,14 @@ OFF - limit search to +/- 200 Hz} xywh {11 119 90 20} down_box DOWN_BOX
callback {progdefaults.rsid_mark = o->value();
progdefaults.changed = true;}
tooltip {Insert RX text marker before
changing frequency and modem} xywh {11 151 90 20} down_box DOWN_BOX
changing frequency and modem} xywh {10 175 203 20} down_box DOWN_BOX
code0 {chkRSidMark->value(progdefaults.rsid_mark);}
}
Fl_Check_Button chkRSidAutoDisable {
label {Disables detector}
callback {progdefaults.rsid_auto_disable = o->value();
progdefaults.changed = true;}
tooltip {Disable further detection when RSID is received} xywh {11 183 90 20} down_box DOWN_BOX
tooltip {Disable further detection when RSID is received} xywh {10 207 203 20} down_box DOWN_BOX
code0 {if (progdefaults.rsid_notify_only) progdefaults.rsid_auto_disable = false;}
code1 {chkRSidAutoDisable->value(progdefaults.rsid_auto_disable);}
code2 {if (progdefaults.rsid_notify_only) chkRSidAutoDisable->deactivate();}
@ -4843,8 +4860,8 @@ progdefaults.changed = true;}
label Sensitivity
callback {progdefaults.rsid_resolution = (int)o->value();
progdefaults.changed = true;}
tooltip {2 = low sensitivity / decreased false detection
5 = high sensitivity / increased false detection} xywh {12 215 145 22} type Horizontal align 8 minimum 1 maximum 5 step 1 value 5 textsize 14
tooltip {2 = normal sensitivity / decreased false detection
5 = high sensitivity / increased false detection} xywh {10 233 145 22} type Horizontal align 8 minimum 2 maximum 5 step 1 value 2 textsize 14
code0 {o->value(progdefaults.rsid_resolution);}
code2 {o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);}
class Fl_Value_Slider2
@ -4853,7 +4870,7 @@ progdefaults.changed = true;}
label {Squelch open (sec)}
callback {progdefaults.rsid_squelch = (int)o->value();
progdefaults.changed = true;}
tooltip {Open squelch for nn sec if RSID detected} xywh {246 215 145 22} type Horizontal align 8 maximum 20 step 1 textsize 14
tooltip {Open squelch for nn sec if RSID detected} xywh {246 233 145 22} type Horizontal align 8 maximum 20 step 1 textsize 14
code0 {o->value(progdefaults.rsid_squelch);}
code2 {o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);}
class Fl_Value_Slider2
@ -4862,39 +4879,45 @@ progdefaults.changed = true;}
label {Disable alert dialog}
callback {progdefaults.disable_rsid_warning_dialog_box = o->value();
progdefaults.changed = true;}
tooltip {Do not show RsID alert dialog box} xywh {246 119 90 20} down_box DOWN_BOX
tooltip {Do not show RsID alert dialog box} xywh {246 143 203 20} down_box DOWN_BOX
code0 {o->value(progdefaults.disable_rsid_warning_dialog_box);}
}
Fl_Check_Button chkRetainFreqLock {
label {Retain tx freq lock}
callback {progdefaults.retain_freq_lock = o->value();
progdefaults.changed = true;}
tooltip {Do not show RsID alert dialog box} xywh {246 151 90 20} down_box DOWN_BOX
tooltip {Retain TX lock frequency (Lk) when changing to RX RsID frequency} xywh {246 175 203 20} down_box DOWN_BOX
code0 {o->value(progdefaults.retain_freq_lock);}
}
Fl_Check_Button chkDisableFreqChange {
label {Disable freq change}
callback {progdefaults.disable_rsid_freq_change = o->value();
progdefaults.changed = true;}
tooltip {Do not show RsID alert dialog box} xywh {246 183 90 20} down_box DOWN_BOX
tooltip {Do not automatically change to RX RsID frequency} xywh {246 207 203 20} down_box DOWN_BOX
code0 {o->value(progdefaults.disable_rsid_freq_change);}
}
Fl_Group {} {
label {The RsID notification message contents and
display characteristics are configured on the
"Notifications" configure dialog.} open
xywh {186 74 330 60} box BORDER_BOX align 21
} {}
}
Fl_Group {} {
label {Pre-Signal Tone} open
xywh {3 250 265 97} box ENGRAVED_FRAME align 21
xywh {3 267 265 97} box ENGRAVED_FRAME align 21
} {
Fl_Counter val_pretone {
label Seconds
callback {progdefaults.pretone = o->value();
progdefaults.changed = true;}
tooltip {Use for triggering amplifier carrier detect} xywh {59 288 140 21} minimum 0 maximum 10
tooltip {Use for triggering amplifier carrier detect} xywh {59 305 140 21} minimum 0 maximum 10
code0 {o->value(progdefaults.pretone);}
}
}
Fl_Group {} {
label {Reed-Solomon ID (Tx)} open
xywh {271 250 265 97} box ENGRAVED_FRAME align 21
xywh {271 267 265 97} box ENGRAVED_FRAME align 21
} {
Fl_Button bRSIDTxModes {
label {Transmit modes}
@ -4902,20 +4925,20 @@ progdefaults.changed = true;}
mode_browser->callback(0);
mode_browser->show(&progdefaults.rsid_tx_modes);
progdefaults.changed = true;}
xywh {348 277 130 24}
xywh {348 294 130 24}
}
Fl_Check_Button btn_post_rsid {
label {End of xmt ID}
callback {progdefaults.rsid_post=o->value();
progdefaults.changed = true;}
tooltip {Add RsID signal to end of transmission} xywh {348 312 97 17} down_box DOWN_BOX
tooltip {Add RsID signal to end of transmission} xywh {348 329 97 17} down_box DOWN_BOX
code0 {o->value(progdefaults.rsid_post);}
}
}
}
Fl_Group tabVideoID {
label Video open
xywh {0 48 540 320} hide
xywh {0 50 540 320} hide
} {
Fl_Group {} {
label {Video Preamble ID} open
@ -4987,7 +5010,7 @@ progdefaults.changed = true;}
}
Fl_Group tabCwID {
label CW
xywh {0 48 540 320} hide
xywh {0 50 540 320} hide
} {
Fl_Group sld {
label {CW Postamble ID} open
@ -5022,10 +5045,10 @@ progdefaults.changed = true;}
}
}
Fl_Group tabMisc {
label Misc
label Misc open
xywh {0 25 540 345} hide
} {
Fl_Tabs tabsMisc {
Fl_Tabs tabsMisc {open
xywh {0 25 540 345} selection_color 50
} {
Fl_Group tabCPUspeed {
@ -5378,83 +5401,92 @@ progdefaults.changed = true;}
callback {progdefaults.wx_sta = o->value();
progdefaults.changed = true;}
tooltip {for example KMDQ for
Huntsville-Madison Executive Airport, AL} xywh {92 92 43 24} align 8
Huntsville-Madison Executive Airport, AL} xywh {66 92 43 24} align 8
code0 {o->value(progdefaults.wx_sta.c_str());}
}
Fl_Check_Button btn_wx_full {
label {Full report}
callback {progdefaults.wx_full=o->value();
progdefaults.changed = true;}
tooltip {Insert full METAR report} xywh {229 130 70 15} down_box DOWN_BOX
tooltip {Insert full METAR report} xywh {230 130 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_full);}
}
Fl_Input {} {
label {End of header string:}
callback {progdefaults.wx_eoh = o->value();
progdefaults.changed = true;}
tooltip {Text defining end of METAR header
Typically 'Connection: close'
Used to search for station name} xywh {230 156 266 25} when 1
code0 {o->value(progdefaults.wx_eoh.c_str());}
}
Fl_Check_Button btn_wx_station_name {
label {METAR station location}
callback {progdefaults.wx_station_name = o->value();
progdefaults.changed = true;}
tooltip {Add geopolitical name of METAR station} xywh {229 158 70 15} down_box DOWN_BOX
tooltip {Add geopolitical name of METAR station} xywh {230 192 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_station_name);}
}
Fl_Check_Button btn_wx_condx {
label Conditions
callback {progdefaults.wx_condx=o->value();
progdefaults.changed = true;}
tooltip {current wx conditions} xywh {229 186 70 15} down_box DOWN_BOX
tooltip {current wx conditions} xywh {230 218 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_condx);}
}
Fl_Check_Button btn_wx_fahrenheit {
label Fahrenheit
callback {progdefaults.wx_fahrenheit=o->value();
progdefaults.changed = true;}
tooltip {report Fahrenheit} xywh {227 214 70 15} down_box DOWN_BOX
tooltip {report Fahrenheit} xywh {230 245 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_fahrenheit);}
}
Fl_Check_Button btn_wx_celsius {
label Celsius
callback {progdefaults.wx_celsius=o->value();
progdefaults.changed = true;}
tooltip {report Celsius} xywh {358 214 70 15} down_box DOWN_BOX
tooltip {report Celsius} xywh {358 245 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_celsius);}
}
Fl_Check_Button btn_wx_mph {
label {Miles / Hour}
callback {progdefaults.wx_mph=o->value();
progdefaults.changed = true;}
tooltip {report miles per hour} xywh {227 242 70 15} down_box DOWN_BOX
tooltip {report miles per hour} xywh {230 271 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_mph);}
}
Fl_Check_Button btn_wx_kph {
label {kilometers / hour}
callback {progdefaults.wx_kph=o->value();
progdefaults.changed = true;}
tooltip {report kilometers per hour} xywh {358 242 70 15} down_box DOWN_BOX
tooltip {report kilometers per hour} xywh {358 271 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_kph);}
}
Fl_Check_Button btn_wx_inches {
label {Inches Mg.}
callback {progdefaults.wx_inches=o->value();
progdefaults.changed = true;}
tooltip {report inches mercury} xywh {227 271 70 15} down_box DOWN_BOX
tooltip {report inches mercury} xywh {230 298 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_inches);}
}
Fl_Check_Button btn_wx_mbars {
label mbars
callback {progdefaults.wx_mbars=o->value();
progdefaults.changed = true;}
tooltip {report millibars} xywh {358 271 70 15} down_box DOWN_BOX
tooltip {report millibars} xywh {358 298 70 15} down_box DOWN_BOX
code0 {o->value(progdefaults.wx_mbars);}
}
Fl_Box {} {
label Temperature
xywh {67 212 156 19} align 20
xywh {65 245 156 19} align 20
}
Fl_Box {} {
label {Wind speed/dir}
xywh {67 240 156 19} align 20
xywh {65 271 156 19} align 20
}
Fl_Box {} {
label {Barometric pressure}
xywh {67 269 156 19} align 20
xywh {65 298 156 19} align 20
}
Fl_Button btn_metar_search {
label {Search on web}
@ -5464,18 +5496,105 @@ progdefaults.changed = true;}
}
}
}
Fl_Group tabKML {
label KML open
xywh {0 50 540 320} hide
} {
Fl_Input btnKmlSaveDir {
label {KML files directory}
callback {progdefaults.kml_save_dir=o->value();
progdefaults.changed = true;
kml_init();}
tooltip {Where generated KML documents are stored.} xywh {26 75 390 24} align 69
code0 {o->value(progdefaults.kml_save_dir.c_str());}
}
Fl_Input inputKmlRootFile {
label {KML root file}
xywh {25 119 300 24} align 5
code0 {o->value("fldigi.kml");}
}
Fl_Counter cntKmlMergeDistance {
label {Minimum distance for splitting aliases (Meters)}
callback {progdefaults.kml_merge_distance = o->value();
progdefaults.changed = true;
kml_init();}
tooltip {Minimum distance for splitting alias nodes (Meters)} xywh {26 155 100 24} align 8 minimum 0 maximum 100000 step 10 value 1000
code0 {o->value(progdefaults.kml_merge_distance);}
code1 {o->lstep(1000);}
}
Fl_Counter cntKmlRetentionTime {
label {Data retention time, in hours (0 for no limit)}
callback {progdefaults.kml_retention_time = o->value();
progdefaults.changed = true;
kml_init();}
tooltip {Number of hours data is kept for each node. Zero means keeping everything.} xywh {25 191 100 24} align 8 minimum 0 maximum 500 step 1
code0 {o->value(progdefaults.kml_retention_time);}
code1 {o->lstep(24);}
}
Fl_Spinner cntKmlRefreshInterval {
label {KML refresh interval (seconds)}
callback {progdefaults.kml_refresh_interval = (int)(o->value());
progdefaults.changed = true;
kml_init();}
tooltip {Refresh time interval written in KML file (Seconds)} xywh {24 227 50 24} align 8 value 10
code0 {o->minimum(1); o->maximum(3600); o->step(1);}
code1 {o->value(progdefaults.kml_refresh_interval);}
code2 {o->labelsize(FL_NORMAL_SIZE);}
class Fl_Spinner2
}
Fl_Choice selKmlBalloonStyle {
label {KML balloon display style}
callback {progdefaults.kml_balloon_style = o->value();
progdefaults.changed = true;
kml_init();}
tooltip {KML balloon in plain text, or HTML, in plain tables or matrices.} xywh {24 263 201 24} down_box BORDER_BOX align 8 when 1
code0 {o->add("Plain text|HTML tables|Single HTML matrix");o->value(progdefaults.kml_balloon_style);}
} {}
Fl_Input btnKmlCommand {
label {Command run on KML creation}
callback {progdefaults.kml_command=o->value();
progdefaults.changed = true;
kml_init();}
tooltip {Command started when KML files are generated. Subprocesses are started once, and restarted if needed.} xywh {24 299 246 24} align 72
code0 {o->value(progdefaults.kml_command.c_str());}
}
Fl_Button btlTestKmlCommand {
label {Test command}
callback {KmlServer::SpawnProcess();}
tooltip {Execute command on KML files.} xywh {24 335 191 24}
}
Fl_Button btnSelectKmlDestDir {
label {Change dir...}
callback {Fl_File_Chooser *fc = new Fl_File_Chooser(".",NULL,Fl_File_Chooser::DIRECTORY,"Input File");
fc->callback(KmlDestDirSet);
fc->show();}
tooltip {Choose directory to store KML documents} xywh {425 75 101 24}
}
Fl_Button btlPurge {
label {Cleanup KML data now !}
callback {KmlServer::GetInstance()->Reset();}
tooltip {Cleanups KML documents, empties Google Earth display.} xywh {336 119 190 24}
}
Fl_Check_Button btnKmlPurgeOnStartup {
label {Cleanup on startup}
callback {progdefaults.kml_purge_on_startup = o->value();
progdefaults.changed = true;}
tooltip {Empties KML documents when starting program.} xywh {322 231 172 15} down_box DOWN_BOX
code0 {o->value(progdefaults.kml_purge_on_startup);}
}
}
}
}
Fl_Group tabQRZ {
label Web
tooltip {Callsign database} xywh {0 25 540 345} hide
tooltip {Callsign database} xywh {0 25 540 349} hide
} {
Fl_Tabs tabsQRZ {open
xywh {0 25 540 345}
xywh {0 25 540 349}
} {
Fl_Group {} {
label {Call Lookup} open
xywh {0 46 540 324}
xywh {0 50 540 324}
} {
Fl_Group {} {
label {Web Browser lookup} open
@ -6124,13 +6243,13 @@ if( ( w->value() != NULL ) && ( ! w->shown() ) ) {
}} {}
}
Function {NvtxCatalogSet(Fl_File_Chooser *w, void *userdata)} {return_type void
Function {KmlDestDirSet(Fl_File_Chooser *w, void *userdata)} {open return_type void
} {
code {/* http://www.fltk.org/documentation.php/doc-1.1/Fl_File_Chooser.html */
if( ( w->value() != NULL ) && ( ! w->shown() ) ) {
txtNvtxCatalog->value( w->value() );
txtNvtxCatalog->redraw();
cb_txtNvtxCatalog( txtNvtxCatalog, NULL );
btnKmlSaveDir->value( w->value() );
btnKmlSaveDir->redraw();
cb_btnKmlSaveDir( btnKmlSaveDir, NULL );
}} {}
}

Wyświetl plik

@ -340,6 +340,9 @@ extern Fl_Counter2 *cntrAUTOCRLF;
extern Fl_Check_Button *btnCRCRLF;
extern Fl_Check_Button *chkUOStx;
extern Fl_Check_Button *chkPseudoFSK;
extern Fl_Check_Button *btnSynopAdifDecoding;
extern Fl_Check_Button *btnSynopKmlDecoding;
extern Fl_Check_Button *btnSynopInterleaved;
extern Fl_Group *tabTHOR;
extern Fl_Input2 *txtTHORSecondary;
extern Fl_Check_Button *valTHOR_FILTER;
@ -351,8 +354,7 @@ extern Fl_Check_Button *valTHOR_SOFTBITS;
extern Fl_Counter2 *valTHOR_PATHS;
extern Fl_Group *tabNavtex;
extern Fl_Check_Button *btnNvtxAdifLog;
extern Fl_Output *txtNvtxCatalog;
extern Fl_Button *btnSelectNvtxCatalog;
extern Fl_Check_Button *btnNvtxKmlLog;
extern Fl_Group *tabWefax;
extern Fl_Check_Button *btnWefaxAdifLog;
extern Fl_Check_Button *btnWefaxEmbeddedGui;
@ -550,6 +552,18 @@ extern Fl_Check_Button *btn_wx_inches;
extern Fl_Check_Button *btn_wx_mbars;
#include "weather.h"
extern Fl_Button *btn_metar_search;
extern Fl_Group *tabKML;
extern Fl_Input *btnKmlSaveDir;
extern Fl_Input *inputKmlRootFile;
extern Fl_Counter *cntKmlMergeDistance;
extern Fl_Counter *cntKmlRetentionTime;
extern Fl_Spinner2 *cntKmlRefreshInterval;
extern Fl_Choice *selKmlBalloonStyle;
extern Fl_Input *btnKmlCommand;
extern Fl_Button *btlTestKmlCommand;
extern Fl_Button *btnSelectKmlDestDir;
extern Fl_Button *btlPurge;
extern Fl_Check_Button *btnKmlPurgeOnStartup;
extern Fl_Group *tabQRZ;
extern Fl_Tabs *tabsQRZ;
extern Fl_Round_Button *btnQRZWEBnotavailable;
@ -621,6 +635,6 @@ void closeDialog();
void createConfig();
class Fl_File_Chooser ;
void WefaxDestDirSet(Fl_File_Chooser *w, void *userdata);
void NvtxCatalogSet(Fl_File_Chooser *w, void *userdata);
void KmlDestDirSet(Fl_File_Chooser *w, void *userdata);
void make_window();
#endif

Wyświetl plik

@ -42,23 +42,6 @@
#include <algorithm>
#include <map>
// this tests depends on a modified FL/filename.H in the Fltk-1.3.0
// change
//# if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
// to
//# if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) && !defined(__WOE32__)
#ifdef __MINGW32__
# if FLDIGI_FLTK_API_MAJOR == 1 && FLDIGI_FLTK_API_MINOR < 3
# undef dirent
# include <dirent.h>
# else
# include <dirent.h>
# endif
#else
# include <dirent.h>
#endif
#ifndef __WOE32__
#include <sys/wait.h>
#endif
@ -91,6 +74,7 @@
#if USE_HAMLIB
#include "hamlib.h"
#endif
#include "timeops.h"
#include "rigio.h"
#include "nullmodem.h"
#include "psk.h"
@ -137,9 +121,7 @@
#include "soundconf.h"
#include "htmlstrings.h"
#if USE_XMLRPC
# include "xmlrpc.h"
#endif
#if BENCHMARK_MODE
# include "benchmark.h"
#endif
@ -158,6 +140,7 @@
#include "flmisc.h"
#include "arq_io.h"
#include "kmlserver.h"
#include "notifydialog.h"
#include "macroedit.h"
@ -166,6 +149,8 @@
#include "charsetdistiller.h"
#include "charsetlist.h"
#include "outputencoder.h"
#include "record_loader.h"
#include "record_browse.h"
#include "ssdv_rx.h"
@ -218,14 +203,14 @@ ssdv_rx *ssdv = (ssdv_rx *)0;
MixerBase* mixer = 0;
Fl_Group *mnuFrame;
static Fl_Group *mnuFrame;
Fl_Menu_Bar *mnu;
Fl_Light_Button *btnAutoSpot = (Fl_Light_Button *)0;
Fl_Light_Button *btnTune = (Fl_Light_Button *)0;
Fl_Light_Button *btnRSID = (Fl_Light_Button *)0;
Fl_Light_Button *btnTxRSID = (Fl_Light_Button *)0;
Fl_Button *btnMacroTimer = (Fl_Button *)0;
static Fl_Button *btnMacroTimer = (Fl_Button *)0;
Panel *text_panel = 0;
Fl_Group *mvgroup = 0;
@ -234,21 +219,20 @@ Fl_Group *macroFrame1 = 0;
Fl_Group *macroFrame2 = 0;
FTextRX *ReceiveText = 0;
FTextTX *TransmitText = 0;
Raster *FHdisp;
static Raster *FHdisp;
Fl_Box *minbox;
int oix;
int minRxHeight;
pskBrowser *mainViewer = (pskBrowser *)0;
Fl_Input2 *txtInpSeek = (Fl_Input2 *)0;
Fl_Box *StatusBar = (Fl_Box *)0;
static Fl_Box *StatusBar = (Fl_Box *)0;
Fl_Box *Status2 = (Fl_Box *)0;
Fl_Box *Status1 = (Fl_Box *)0;
Fl_Counter2 *cntTxLevel = (Fl_Counter2 *)0;
Fl_Counter2 *cntCW_WPM=(Fl_Counter2 *)0;
Fl_Button *btnCW_Default=(Fl_Button *)0;
Fl_Box *WARNstatus = (Fl_Box *)0;
static Fl_Button *btnCW_Default=(Fl_Button *)0;
static Fl_Box *WARNstatus = (Fl_Box *)0;
Fl_Button *MODEstatus = (Fl_Button *)0;
Fl_Button *btnMacro[NUMMACKEYS * NUMKEYROWS];
Fl_Button *btnAltMacros1 = (Fl_Button *)0;
@ -267,7 +251,7 @@ Fl_Input2 *inpNotes;
Fl_Input2 *inpAZ; // WA5ZNU
Fl_Button *qsoTime;
Fl_Button *btnQRZ;
Fl_Button *qsoClear;
static Fl_Button *qsoClear;
Fl_Button *qsoSave;
Fl_Box *txtRigName = (Fl_Box *)0;
cFreqControl *qsoFreqDisp = (cFreqControl *)0;
@ -284,78 +268,75 @@ Fl_Input2 *inpName;
Fl_Input2 *inpRstIn;
Fl_Input2 *inpRstOut;
Fl_Group *TopFrame1 = (Fl_Group *)0;
Fl_Input2 *inpFreq1;
Fl_Input2 *inpTimeOff1;
Fl_Input2 *inpTimeOn1;
Fl_Button *btnTimeOn1;
static Fl_Group *TopFrame1 = (Fl_Group *)0;
static Fl_Input2 *inpFreq1;
static Fl_Input2 *inpTimeOff1;
static Fl_Input2 *inpTimeOn1;
static Fl_Button *btnTimeOn1;
Fl_Input2 *inpCall1;
Fl_Input2 *inpName1;
Fl_Input2 *inpRstIn1;
Fl_Input2 *inpRstOut1;
Fl_Input2 *inpXchgIn1;
Fl_Input2 *outSerNo1;
Fl_Input2 *inpSerNo1;
static Fl_Input2 *inpRstIn1;
static Fl_Input2 *inpRstOut1;
static Fl_Input2 *inpXchgIn1;
static Fl_Input2 *outSerNo1;
static Fl_Input2 *inpSerNo1;
cFreqControl *qsoFreqDisp1 = (cFreqControl *)0;
Fl_Group *RigControlFrame = (Fl_Group *)0;
Fl_Group *RigViewerFrame = (Fl_Group *)0;
Fl_Group *QsoInfoFrame = (Fl_Group *)0;
Fl_Group *QsoInfoFrame1 = (Fl_Group *)0;
Fl_Group *QsoInfoFrame1A = (Fl_Group *)0;
static Fl_Group *QsoInfoFrame1 = (Fl_Group *)0;
static Fl_Group *QsoInfoFrame1A = (Fl_Group *)0;
Fl_Group *QsoInfoFrame1B = (Fl_Group *)0;
Fl_Group *QsoInfoFrameLeft = (Fl_Group *)0;
Fl_Group *QsoInfoFrameCenter = (Fl_Group *)0;
Fl_Group *QsoInfoFrameRight = (Fl_Group *)0;
Fl_Group *QsoInfoFrame2 = (Fl_Group *)0;
Fl_Group *QsoButtonFrame = (Fl_Group *)0;
static Fl_Group *QsoInfoFrame2 = (Fl_Group *)0;
static Fl_Group *QsoButtonFrame = (Fl_Group *)0;
Fl_Group *TopFrame2 = (Fl_Group *)0;
cFreqControl *qsoFreqDisp2 = (cFreqControl *)0;
Fl_Input2 *inpTimeOff2;
Fl_Input2 *inpTimeOn2;
Fl_Button *btnTimeOn2;
cFreqControl *qsoFreqDisp2 = (cFreqControl *)0;
static Fl_Input2 *inpTimeOff2;
static Fl_Input2 *inpTimeOn2;
static Fl_Button *btnTimeOn2;
Fl_Input2 *inpCall2;
Fl_Input2 *inpName2;
Fl_Input2 *inpRstIn2;
Fl_Input2 *inpRstOut2;
static Fl_Input2 *inpName2;
static Fl_Input2 *inpRstIn2;
static Fl_Input2 *inpRstOut2;
Fl_Button *qso_opPICK2;
Fl_Button *qsoClear2;
Fl_Button *qsoSave2;
static Fl_Button *qsoClear2;
static Fl_Button *qsoSave2;
Fl_Button *btnQRZ2;
Fl_Group *TopFrame3 = (Fl_Group *)0;
cFreqControl *qsoFreqDisp3 = (cFreqControl *)0;
Fl_Input2 *inpTimeOff3;
Fl_Input2 *inpTimeOn3;
Fl_Button *btnTimeOn3;
static Fl_Group *TopFrame3 = (Fl_Group *)0;
cFreqControl *qsoFreqDisp3 = (cFreqControl *)0;
static Fl_Input2 *inpTimeOff3;
static Fl_Input2 *inpTimeOn3;
static Fl_Button *btnTimeOn3;
Fl_Input2 *inpCall3;
Fl_Input2 *outSerNo2;
Fl_Input2 *inpSerNo2;
Fl_Input2 *inpXchgIn2;
Fl_Button *qso_opPICK3;
Fl_Button *qsoClear3;
Fl_Button *qsoSave3;
static Fl_Input2 *outSerNo2;
static Fl_Input2 *inpSerNo2;
static Fl_Input2 *inpXchgIn2;
static Fl_Button *qso_opPICK3;
static Fl_Button *qsoClear3;
static Fl_Button *qsoSave3;
Fl_Input2 *inpCall4;
Fl_Browser *qso_opBrowser = (Fl_Browser *)0;
Fl_Button *qso_btnAddFreq = (Fl_Button *)0;
Fl_Button *qso_btnSelFreq = (Fl_Button *)0;
Fl_Button *qso_btnDelFreq = (Fl_Button *)0;
Fl_Button *qso_btnClearList = (Fl_Button *)0;
Fl_Button *qso_btnAct = 0;
Fl_Input2 *qso_inpAct = 0;
static Fl_Button *qso_btnAddFreq = (Fl_Button *)0;
static Fl_Button *qso_btnSelFreq = (Fl_Button *)0;
static Fl_Button *qso_btnDelFreq = (Fl_Button *)0;
static Fl_Button *qso_btnClearList = (Fl_Button *)0;
static Fl_Button *qso_btnAct = 0;
static Fl_Input2 *qso_inpAct = 0;
Fl_Group *MixerFrame;
static Fl_Group *MixerFrame;
Fl_Value_Slider2 *valRcvMixer = (Fl_Value_Slider2 *)0;
Fl_Value_Slider2 *valXmtMixer = (Fl_Value_Slider2 *)0;
Fl_Pack *wfpack = (Fl_Pack *)0;
Fl_Pack *hpack = (Fl_Pack *)0;
static Fl_Pack *wfpack = (Fl_Pack *)0;
static Fl_Pack *hpack = (Fl_Pack *)0;
Fl_Value_Slider2 *mvsquelch = (Fl_Value_Slider2 *)0;
Fl_Button *btnClearMViewer = 0;
static Fl_Button *btnClearMViewer = 0;
Fl_Group *TopFrameHAB;
Fl_Choice *habFlight;
@ -398,54 +379,47 @@ int w_habString = 430;
int HAB_width = -1;
int HAB_height = 0;
int pad = 1;
int Hentry = 24;
int Wbtn = Hentry;
int x_qsoframe = Wbtn;
static const int pad = 1;
static const int Hentry = 24;
static const int Wbtn = Hentry;
static int x_qsoframe = Wbtn;
int Hmenu = 22;
int Hqsoframe = pad + 3 * (Hentry + pad);
int Hstatus = 22;
int Hmacros = 22;
int w_inpFreq = 80;
int w_inpTime = 40;
int w_inpCall = 120;
int w_inpName = 90;
int w_inpRstIn = 30;
int w_inpRstOut = 30;
int w_SerNo = 40;
int sw = 22;
static const int Hqsoframe = pad + 3 * (Hentry + pad);
int Hstatus = 22;
int Hmacros = 22;
static const int w_inpFreq = 80;
static const int w_inpTime = 40;
static const int w_inpCall = 120;
static const int w_inpName = 90;
static const int w_inpRstIn = 30;
static const int w_inpRstOut = 30;
static const int w_SerNo = 40;
static const int sw = 22;
int wlabel = 30;
static const int wlabel = 30;
int wf1 = 436;
//int wf1 = pad + w_inpFreq + pad + 2*w_inpTime + pad + w_inpCall +
// pad + w_inpName + pad + w_inpRstIn + pad + w_inpRstOut + pad;
static const int wf1 = 436;
int w_inpTime2 = 40;
int w_inpCall2 = 100;
int w_inpName2 = 80;
int w_inpRstIn2 = 30;
int w_inpRstOut2 = 30;
static const int w_inpTime2 = 40;
static const int w_inpCall2 = 100;
static const int w_inpName2 = 80;
static const int w_inpRstIn2 = 30;
static const int w_inpRstOut2 = 30;
int w_fm1 = 25;
int w_fm2 = 15;
int w_fm3 = 15;
int w_fm4 = 25;
int w_fm5 = 25;
int w_fm6 = 30;
int w_fm7 = 35;
int w_inpState = 25;
int w_inpProv = 25;
int w_inpCountry = 60;
int w_inpLOC = 55;
int w_inpAZ = 30;
static const int w_fm1 = 25;
static const int w_fm2 = 15;
static const int w_fm3 = 15;
static const int w_fm4 = 25;
static const int w_fm5 = 25;
static const int w_fm6 = 30;
static const int w_fm7 = 35;
static const int w_inpState = 25;
static const int w_inpProv = 25;
static const int w_inpCountry = 60;
static const int w_inpLOC = 55;
static const int w_inpAZ = 30;
int w_inpQth = wf1 - w_fm1 - w_fm2 - w_fm3 - w_fm4 - w_fm5 - w_fm6 -
w_inpState - w_inpProv - w_inpLOC - w_inpAZ - w_inpCountry;
int w_Xchg = wf1 - 2*w_fm7 - w_fm5 - 2*pad - 2 * w_SerNo;
int qh = Hqsoframe / 2;
static const int qh = Hqsoframe / 2;
int IMAGE_WIDTH;
int Hwfall;
@ -456,19 +430,14 @@ int WNOM = 650;//progStatus.mainW ? progStatus.mainW : WMIN;
int Wwfall;
int altMacros = 0;
bool bSaveFreqList = false;
string strMacroName[NUMMACKEYS];
waterfall *wf = (waterfall *)0;
Digiscope *digiscope = (Digiscope *)0;
//Digiscope *wfscope = (Digiscope *)0;
Fl_Slider2 *sldrSquelch = (Fl_Slider2 *)0;
Progress *pgrsSquelch = (Progress *)0;
Fl_RGB_Image *feld_image = 0;
Fl_Pixmap *addrbookpixmap = 0;
static Fl_Pixmap *addrbookpixmap = 0;
#if !defined(__APPLE__) && !defined(__WOE32__) && USE_X
Pixmap fldigi_icon_pixmap;
@ -507,10 +476,10 @@ void cb_rtty75N(Fl_Widget *w, void *arg);
void cb_rtty75W(Fl_Widget *w, void *arg);
void cb_rttyCustom(Fl_Widget *w, void *arg);
Fl_Widget *modem_config_tab;
Fl_Menu_Item *quick_change;
static Fl_Widget *modem_config_tab;
static const Fl_Menu_Item *quick_change;
Fl_Menu_Item quick_change_psk[] = {
static const Fl_Menu_Item quick_change_psk[] = {
{ mode_info[MODE_PSK31].name, 0, cb_init_mode, (void *)MODE_PSK31 },
{ mode_info[MODE_PSK63].name, 0, cb_init_mode, (void *)MODE_PSK63 },
{ mode_info[MODE_PSK63F].name, 0, cb_init_mode, (void *)MODE_PSK63F },
@ -521,7 +490,7 @@ Fl_Menu_Item quick_change_psk[] = {
{ 0 }
};
Fl_Menu_Item quick_change_qpsk[] = {
static const Fl_Menu_Item quick_change_qpsk[] = {
{ mode_info[MODE_QPSK31].name, 0, cb_init_mode, (void *)MODE_QPSK31 },
{ mode_info[MODE_QPSK63].name, 0, cb_init_mode, (void *)MODE_QPSK63 },
{ mode_info[MODE_QPSK125].name, 0, cb_init_mode, (void *)MODE_QPSK125 },
@ -530,7 +499,7 @@ Fl_Menu_Item quick_change_qpsk[] = {
{ 0 }
};
Fl_Menu_Item quick_change_pskr[] = {
static const Fl_Menu_Item quick_change_pskr[] = {
{ mode_info[MODE_PSK125R].name, 0, cb_init_mode, (void *)MODE_PSK125R },
{ mode_info[MODE_PSK250R].name, 0, cb_init_mode, (void *)MODE_PSK250R },
{ mode_info[MODE_PSK500R].name, 0, cb_init_mode, (void *)MODE_PSK500R },
@ -538,7 +507,7 @@ Fl_Menu_Item quick_change_pskr[] = {
{ 0 }
};
Fl_Menu_Item quick_change_psk_multiR[] = {
static const Fl_Menu_Item quick_change_psk_multiR[] = {
{ mode_info[MODE_4X_PSK63R].name, 0, cb_init_mode, (void *)MODE_4X_PSK63R },
{ mode_info[MODE_5X_PSK63R].name, 0, cb_init_mode, (void *)MODE_5X_PSK63R },
{ mode_info[MODE_10X_PSK63R].name, 0, cb_init_mode, (void *)MODE_10X_PSK63R },
@ -567,7 +536,7 @@ Fl_Menu_Item quick_change_psk_multiR[] = {
{ 0 }
};
Fl_Menu_Item quick_change_psk_multi[] = {
static const Fl_Menu_Item quick_change_psk_multi[] = {
{ mode_info[MODE_12X_PSK125].name, 0, cb_init_mode, (void *)MODE_12X_PSK125 },
{ mode_info[MODE_6X_PSK250].name, 0, cb_init_mode, (void *)MODE_6X_PSK250 },
{ mode_info[MODE_2X_PSK500].name, 0, cb_init_mode, (void *)MODE_2X_PSK500 },
@ -577,7 +546,7 @@ Fl_Menu_Item quick_change_psk_multi[] = {
{ 0 }
};
Fl_Menu_Item quick_change_mfsk[] = {
static const Fl_Menu_Item quick_change_mfsk[] = {
{ mode_info[MODE_MFSK4].name, 0, cb_init_mode, (void *)MODE_MFSK4 },
{ mode_info[MODE_MFSK8].name, 0, cb_init_mode, (void *)MODE_MFSK8 },
{ mode_info[MODE_MFSK16].name, 0, cb_init_mode, (void *)MODE_MFSK16 },
@ -590,19 +559,19 @@ Fl_Menu_Item quick_change_mfsk[] = {
{ 0 }
};
Fl_Menu_Item quick_change_wefax[] = {
static const Fl_Menu_Item quick_change_wefax[] = {
{ mode_info[MODE_WEFAX_576].name, 0, cb_init_mode, (void *)MODE_WEFAX_576 },
{ mode_info[MODE_WEFAX_288].name, 0, cb_init_mode, (void *)MODE_WEFAX_288 },
{ 0 }
};
Fl_Menu_Item quick_change_navtex[] = {
static const Fl_Menu_Item quick_change_navtex[] = {
{ mode_info[MODE_NAVTEX].name, 0, cb_init_mode, (void *)MODE_NAVTEX },
{ mode_info[MODE_SITORB].name, 0, cb_init_mode, (void *)MODE_SITORB },
{ 0 }
};
Fl_Menu_Item quick_change_mt63[] = {
static const Fl_Menu_Item quick_change_mt63[] = {
{ mode_info[MODE_MT63_500S].name, 0, cb_init_mode, (void *)MODE_MT63_500S },
{ mode_info[MODE_MT63_500L].name, 0, cb_init_mode, (void *)MODE_MT63_500L },
{ mode_info[MODE_MT63_1000S].name, 0, cb_init_mode, (void *)MODE_MT63_1000S },
@ -612,7 +581,7 @@ Fl_Menu_Item quick_change_mt63[] = {
{ 0 }
};
Fl_Menu_Item quick_change_thor[] = {
static const Fl_Menu_Item quick_change_thor[] = {
{ mode_info[MODE_THOR4].name, 0, cb_init_mode, (void *)MODE_THOR4 },
{ mode_info[MODE_THOR5].name, 0, cb_init_mode, (void *)MODE_THOR5 },
{ mode_info[MODE_THOR8].name, 0, cb_init_mode, (void *)MODE_THOR8 },
@ -626,7 +595,7 @@ Fl_Menu_Item quick_change_thor[] = {
{ 0 }
};
Fl_Menu_Item quick_change_domino[] = {
static const Fl_Menu_Item quick_change_domino[] = {
{ mode_info[MODE_DOMINOEX4].name, 0, cb_init_mode, (void *)MODE_DOMINOEX4 },
{ mode_info[MODE_DOMINOEX5].name, 0, cb_init_mode, (void *)MODE_DOMINOEX5 },
{ mode_info[MODE_DOMINOEX8].name, 0, cb_init_mode, (void *)MODE_DOMINOEX8 },
@ -638,7 +607,7 @@ Fl_Menu_Item quick_change_domino[] = {
{ 0 }
};
Fl_Menu_Item quick_change_feld[] = {
static const Fl_Menu_Item quick_change_feld[] = {
{ mode_info[MODE_FELDHELL].name, 0, cb_init_mode, (void *)MODE_FELDHELL },
{ mode_info[MODE_SLOWHELL].name, 0, cb_init_mode, (void *)MODE_SLOWHELL },
{ mode_info[MODE_HELLX5].name, 0, cb_init_mode, (void *)MODE_HELLX5 },
@ -649,7 +618,7 @@ Fl_Menu_Item quick_change_feld[] = {
{ 0 }
};
Fl_Menu_Item quick_change_throb[] = {
static const Fl_Menu_Item quick_change_throb[] = {
{ mode_info[MODE_THROB1].name, 0, cb_init_mode, (void *)MODE_THROB1 },
{ mode_info[MODE_THROB2].name, 0, cb_init_mode, (void *)MODE_THROB2 },
{ mode_info[MODE_THROB4].name, 0, cb_init_mode, (void *)MODE_THROB4 },
@ -659,7 +628,7 @@ Fl_Menu_Item quick_change_throb[] = {
{ 0 }
};
Fl_Menu_Item quick_change_olivia[] = {
static const Fl_Menu_Item quick_change_olivia[] = {
{ mode_info[MODE_OLIVIA_4_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_250 },
{ mode_info[MODE_OLIVIA_8_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_250 },
{ mode_info[MODE_OLIVIA_4_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_500 },
@ -673,7 +642,7 @@ Fl_Menu_Item quick_change_olivia[] = {
{ 0 }
};
Fl_Menu_Item quick_change_contestia[] = {
static const Fl_Menu_Item quick_change_contestia[] = {
{ "4/125", 0, cb_contestiaI, (void *)MODE_CONTESTIA },
{ "4/250", 0, cb_contestiaA, (void *)MODE_CONTESTIA },
{ "8/250", 0, cb_contestiaB, (void *)MODE_CONTESTIA },
@ -688,7 +657,7 @@ Fl_Menu_Item quick_change_contestia[] = {
{ 0 }
};
Fl_Menu_Item quick_change_rtty[] = {
static const Fl_Menu_Item quick_change_rtty[] = {
{ "RTTY-45", 0, cb_rtty45, (void *)MODE_RTTY },
{ "RTTY-50", 0, cb_rtty50, (void *)MODE_RTTY },
{ "RTTY-75N", 0, cb_rtty75N, (void *)MODE_RTTY },
@ -929,15 +898,6 @@ void set_dominoex_tab_widgets()
chkDominoEX_FEC->value(progdefaults.DOMINOEX_FEC);
}
static void busy_cursor(void*)
{
Fl::first_window()->cursor(FL_CURSOR_WAIT);
}
static void default_cursor(void*)
{
Fl::first_window()->cursor(FL_CURSOR_DEFAULT);
}
void startup_modem(modem* m, int f)
{
trx_start_modem(m, f);
@ -1144,7 +1104,7 @@ void cb_E(Fl_Menu_*, void*) {
fl_digi_main->hide();
}
int squelch_val;
static int squelch_val;
void rsid_squelch_timer(void*)
{
progStatus.sqlonoff = squelch_val;
@ -1165,6 +1125,8 @@ void init_modem(trx_mode mode, int freq)
{
ENSURE_THREAD(FLMAIN_TID);
LOG_INFO("mode: %d, freq: %d", (int)mode, freq);
#if !BENCHMARK_MODE
quick_change = 0;
modem_config_tab = tabsModems->child(0);
@ -1406,10 +1368,30 @@ void init_modem_sync(trx_mode m, int f)
{
ENSURE_THREAD(FLMAIN_TID);
if (trx_state != STATE_RX)
TRX_WAIT(STATE_RX, abort_tx());
int count = 500;
if (trx_state != STATE_RX) {
LOG_INFO("%s", "Waiting for STATE_RX");
abort_tx();
while (trx_state != STATE_RX && count) {
LOG_VERBOSE("%d msecs remaining", count * 10);
MilliSleep(10);
count--;
}
if (!count) LOG_ERROR("%s", "trx wait for RX timeout");
}
LOG_INFO("Call init_modem %d, %d", m, f);
init_modem(m, f);
count = 500;
if (trx_state != STATE_RX) {
while (trx_state != STATE_RX && count) {
MilliSleep(10);
count--;
}
LOG_INFO("Waited %.2f sec for RX state", (500 - count) * 0.01);
}
TRX_WAIT(STATE_RX, init_modem(m, f));
REQ_FLUSH(TRX_TID);
}
@ -1447,10 +1429,9 @@ void populate_charset_menu(void)
CHARSETstatus->add(charset_list[i].name, 0, cb_charset_menu, (void *)charset_list[i].tiniconv_id);
}
// find the position of the default charset in charset_list[] and trigger the callback
void set_default_charset(void)
{
// find the position of the default charset in charset_list[] and
// trigger the callback
for (unsigned int i = 0; i < number_of_charsets; i++) {
if (strcmp(charset_list[i].name, progdefaults.charset_name.c_str()) == 0) {
cb_charset_menu(0, (void *)charset_list[i].tiniconv_id);
@ -1459,10 +1440,9 @@ void set_default_charset(void)
}
}
// if w is not NULL, give focus to TransmitText only if the last event was an Enter keypress
void restoreFocus(Fl_Widget* w)
{
// if w is not NULL, give focus to TransmitText only if the last event
// was an Enter keypress
if (!w)
TransmitText->take_focus();
else if (Fl::event() == FL_KEYBOARD) {
@ -1796,9 +1776,9 @@ void cb_view_hide_channels(Fl_Menu_ *w, void *d)
}
#if USE_SNDFILE
bool capval = false;
bool genval = false;
bool playval = false;
static bool capval = false;
static bool genval = false;
static bool playval = false;
void cb_mnuCapture(Fl_Widget *w, void *d)
{
if (!scard) return;
@ -2096,29 +2076,35 @@ void cb_ShowConfig(Fl_Widget*, void*)
cb_mnuVisitURL(0, (void*)HomeDir.c_str());
}
static void cb_ShowDATA(Fl_Widget*, void*)
{
/// Must be already created by createRecordLoader()
dlgRecordLoader->show();
}
bool ask_dir_creation( const std::string & dir )
{
if ( 0 == directory_is_created(dir.c_str())) {
int ans = fl_choice2(_("%s: Do not exist, create?"), _("No"), _("Yes"), 0, dir.c_str() );
if (!ans) return false ;
return true ;
}
return false ;
}
void cb_ShowNBEMS(Fl_Widget*, void*)
{
DIR *nbems_dir;
nbems_dir = opendir(NBEMS_dir.c_str());
if (!nbems_dir) {
int ans = fl_choice2(_("Do not exist, create?"), _("No"), _("Yes"), 0);
if (!ans) return;
if ( ask_dir_creation(NBEMS_dir)) {
check_nbems_dirs();
}
closedir(nbems_dir);
cb_mnuVisitURL(0, (void*)NBEMS_dir.c_str());
}
void cb_ShowFLMSG(Fl_Widget*, void*)
{
DIR *flmsg_dir;
flmsg_dir = opendir(FLMSG_dir.c_str());
if (!flmsg_dir) {
int ans = fl_choice2(_("Do not exist, create?"), _("No"), _("Yes"), 0);
if (!ans) return;
if ( ask_dir_creation(FLMSG_dir)) {
check_nbems_dirs();
}
closedir(flmsg_dir);
cb_mnuVisitURL(0, (void*)FLMSG_dir.c_str());
}
@ -2285,8 +2271,8 @@ void updateOutSerNo()
}
}
string old_call;
string new_call;
static string old_call;
static string new_call;
void clearQSO()
{
@ -2720,36 +2706,37 @@ int default_handler(int event)
if ((key == FL_F + 4) && Fl::event_alt()) clean_exit(true);
if (w == fl_digi_main || w->window() == fl_digi_main) {
if (fl_digi_main->contains(w)) {
if (key == FL_Escape || (key >= FL_F && key <= FL_F_Last) ||
((key == '1' || key == '2' || key == '3' || key == '4') && Fl::event_alt())) {
TransmitText->take_focus();
TransmitText->handle(FL_KEYBOARD);
// w->take_focus(); // remove this to leave tx text focused
return 1;
}
#ifdef __APPLE__
if ((key == '=') && (Fl::event_state() == FL_COMMAND)) {
if ((key == '=') && (Fl::event_state() == FL_COMMAND))
#else
if (key == '=' && Fl::event_alt()) {
if (key == '=' && Fl::event_alt())
#endif
{
progdefaults.txlevel += 0.1;
if (progdefaults.txlevel > 0) progdefaults.txlevel = 0;
cntTxLevel->value(progdefaults.txlevel);
return 1;
}
#ifdef __APPLE__
if ((key == '-') && (Fl::event_state() == FL_COMMAND)) {
if ((key == '-') && (Fl::event_state() == FL_COMMAND))
#else
if (key == '-' && Fl::event_alt()) {
if (key == '-' && Fl::event_alt())
#endif
{
progdefaults.txlevel -= 0.1;
if (progdefaults.txlevel < -30) progdefaults.txlevel = -30;
cntTxLevel->value(progdefaults.txlevel);
return 1;
}
}
else if (w == dlgLogbook || w->window() == dlgLogbook)
else if (dlgLogbook->contains(w))
return log_search_handler(event);
else if ((Fl::event_key() == FL_Escape) ||
@ -2757,7 +2744,9 @@ int default_handler(int event)
TransmitText->visible_focus()))
return 1;
else if (Fl::event_ctrl()) return w->handle(FL_KEYBOARD);
else if ( (fl_digi_main->contains(w) || dlgLogbook->contains(w)) &&
Fl::event_ctrl() )
return w->handle(FL_KEYBOARD);
return 0;
}
@ -2778,19 +2767,17 @@ int wo_default_handler(int event)
if ((key == FL_F + 4) && Fl::event_alt()) clean_exit(true);
if (w == fl_digi_main || w->window() == fl_digi_main) {
if (fl_digi_main->contains(w)) {
if (key == FL_Escape || (key >= FL_F && key <= FL_F_Last) ||
((key == '1' || key == '2' || key == '3' || key == '4') && Fl::event_alt())) {
// TransmitText->take_focus();
// TransmitText->handle(FL_KEYBOARD);
// w->take_focus(); // remove this to leave tx text focused
return 1;
}
#ifdef __APPLE__
if ((key == '=') && (Fl::event_state() == FL_COMMAND)) {
if ((key == '=') && (Fl::event_state() == FL_COMMAND))
#else
if (key == '=' && Fl::event_alt()) {
if (key == '=' && Fl::event_alt())
#endif
{
progdefaults.txlevel += 0.1;
if (progdefaults.txlevel > 0) progdefaults.txlevel = 0;
cntTxLevel->value(progdefaults.txlevel);
@ -2807,13 +2794,6 @@ int wo_default_handler(int event)
return 1;
}
}
// else if (w == dlgLogbook || w->window() == dlgLogbook)
// return log_search_handler(event);
// else if ((Fl::event_key() == FL_Escape) ||
// (Fl::event_ctrl() && ((key == 'z' || key == 'Z')) &&
// TransmitText->visible_focus()))
// return 1;
else if (Fl::event_ctrl()) return w->handle(FL_KEYBOARD);
@ -2926,6 +2906,8 @@ bool clean_exit(bool ask) {
#endif
rigCAT_close();
ADIF_RW_close();
if (mixer)
mixer->closeMixer();
@ -2952,7 +2934,7 @@ bool clean_exit(bool ask) {
return true;
}
bool restore_minimize = false;
static bool restore_minimize = false;
void UI_select()
{
@ -3407,13 +3389,14 @@ void WF_UI()
static void cb_opmode_show(Fl_Widget* w, void*);
Fl_Menu_Item menu_[] = {
static Fl_Menu_Item menu_[] = {
{_("&File"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
{ make_icon_label(_("Folders")), 0, 0, 0, FL_SUBMENU, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Fldigi config..."), folder_open_icon), 0, cb_ShowConfig, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("FLMSG files..."), folder_open_icon), 0, cb_ShowFLMSG, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("NBEMS files..."), folder_open_icon), 0, cb_ShowNBEMS, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Data files..."), folder_open_icon), 0, cb_ShowDATA, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
{ make_icon_label(_("Macros")), 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU, _FL_MULTI_LABEL, 0, 14, 0},
@ -4026,7 +4009,7 @@ void cb_qso_inpAct(Fl_Widget*, void*)
url.append("?grid=").append(progdefaults.myLocator, 0, 2);
string::size_type i;
if (!fetch_http_gui(url, data, 10.0, busy_cursor, 0, default_cursor, 0) ||
if (!fetch_http_gui(url, data, 10.0) ||
(i = data.find("\r\n\r\n")) == string::npos) {
LOG_ERROR("Error while fetching \"%s\": %s", url.c_str(), data.c_str());
return;
@ -4092,21 +4075,26 @@ void cb_qso_opBrowser(Fl_Browser*, void*)
}
}
void show_frequency(long long freq)
void _show_frequency(long long freq)
{
qsoFreqDisp1->value(freq);
qsoFreqDisp2->value(freq);
qsoFreqDisp3->value(freq);
}
void show_frequency(long long freq)
{
REQ(_show_frequency, freq);
}
void show_mode(const string& sMode)
{
REQ_SYNC(&Fl_ComboBox::put_value, qso_opMODE, sMode.c_str());
REQ(&Fl_ComboBox::put_value, qso_opMODE, sMode.c_str());
}
void show_bw(const string& sWidth)
{
REQ_SYNC(&Fl_ComboBox::put_value, qso_opBW, sWidth.c_str());
REQ(&Fl_ComboBox::put_value, qso_opBW, sWidth.c_str());
}
@ -4185,7 +4173,7 @@ void cb_btnCW_Default(Fl_Widget *w, void *v)
static void cb_mainViewer_Seek(Fl_Input *, void *)
{
static Fl_Color seek_color[2] = { FL_FOREGROUND_COLOR,
static const Fl_Color seek_color[2] = { FL_FOREGROUND_COLOR,
adjust_color(FL_RED, FL_BACKGROUND2_COLOR) }; // invalid RE
seek_re.recompile(*txtInpSeek->value() ? txtInpSeek->value() : "[invalid");
if (txtInpSeek->textcolor() != seek_color[!seek_re]) {
@ -4448,7 +4436,8 @@ void LOGBOOK_colors_font()
ypos = inpNotes_log->y() + inpNotes_log->h() - wh;
Fl_Input2* row5[] = {
inpITUZ_log, inpCONT_log, inpDXCC_log };
inpITUZ_log, inpCONT_log, inpDXCC_log, inpQSL_VIA_log
};
for (size_t i = 0; i < sizeof(row5)/sizeof(*row5); i++) {
inp_font_pos(row5[i], row5[i]->x(), ypos, row5[i]->w(), wh);
}
@ -5512,9 +5501,8 @@ void create_fl_digi_main_primary() {
// ztimer must be run by FLTK's timeout handler
Fl::add_timeout(0.0, ztimer, (void*)true);
// Set the state of checked toggle menu items
struct {
// Set the state of checked toggle menu items. Never changes.
const struct {
bool var; const char* label;
} toggles[] = {
{ progStatus.LOGenabled, LOG_TO_FILE_MLABEL },
@ -5544,6 +5532,7 @@ void create_fl_digi_main_primary() {
clearQSO();
createConfig();
createRecordLoader();
if (withnoise)
grpNoise->show();
@ -5570,7 +5559,7 @@ void cb_mnuCaptureHAB(Fl_Widget *w, void *d);
void cb_mnuGenerateHAB(Fl_Widget *w, void *d);
void cb_mnuPlaybackHAB(Fl_Widget *w, void *d);
Fl_Menu_Item alt_menu_[] = {
static Fl_Menu_Item alt_menu_[] = {
{_("&File"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
#if USE_SNDFILE
@ -5967,7 +5956,7 @@ void altTabs()
tabsUI->remove(tabMBars);
}
int WF_only_height = 0;
static int WF_only_height = 0;
void create_fl_digi_main_WF_only() {
@ -6146,7 +6135,7 @@ void create_fl_digi_main_WF_only() {
fl_digi_main->callback(cb_wMain);
fl_digi_main->resizable(wf);
struct {
const struct {
bool var; const char* label;
} toggles[] = {
{ progStatus.DOCKEDSCOPE, DOCKEDSCOPE_MLABEL }
@ -6179,6 +6168,7 @@ void create_fl_digi_main_WF_only() {
wf->UI_select(true);
createConfig();
createRecordLoader();
if (withnoise)
grpNoise->show();
altTabs();
@ -7593,10 +7583,8 @@ void qsy(long long rfc, int fmid)
else if (progdefaults.chkUSEHAMLIBis)
REQ(hamlib_set_qsy, rfc);
#endif
#if USE_XMLRPC
else if (progdefaults.chkUSEXMLRPCis)
REQ(xmlrpc_set_qsy, rfc);
#endif
else
LOG_VERBOSE("Ignoring rfcarrier change request (no rig control)");
}
@ -7763,7 +7751,8 @@ void set_rtty_shift(int shift)
if (shift < selCustomShift->minimum() || shift > selCustomShift->maximum())
return;
const int shifts[] = { 23, 85, 160, 170, 182, 200, 240, 350, 425, 850 };
// Static const array otherwise will be built at each call.
static const int shifts[] = { 23, 85, 160, 170, 182, 200, 240, 350, 425, 850 };
size_t i;
for (i = 0; i < sizeof(shifts)/sizeof(*shifts); i++)
if (shifts[i] == shift)
@ -7778,7 +7767,8 @@ void set_rtty_shift(int shift)
void set_rtty_baud(float baud)
{
const float bauds[] = {
// Static const array otherwise will be rebuilt at each call.
static const float bauds[] = {
45.0f, 45.45f, 50.0f, 56.0f, 75.0f,
100.0f, 110.0f, 150.0f, 200.0f, 300.0f
};
@ -7793,7 +7783,8 @@ void set_rtty_baud(float baud)
void set_rtty_bits(int bits)
{
const int bits_[] = { 5, 7, 8 };
// Static const array otherwise will be built at each call.
static const int bits_[] = { 5, 7, 8 };
for (size_t i = 0; i < sizeof(bits_)/sizeof(*bits_); i++) {
if (bits_[i] == bits) {
selBits->value(i);

Wyświetl plik

@ -0,0 +1,60 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0302
#include "record_browse.h"
#include <config.h>
Fl_Group *tabDataFiles=(Fl_Group *)0;
Fl_Input_Choice *inpDataSources=(Fl_Input_Choice *)0;
Fl_Light_Button *btnDataSourceUpdate=(Fl_Light_Button *)0;
static void cb_btnDataSourceUpdate(Fl_Light_Button*, void*) {
DerivedRecordLst::cbGuiUpdate();
}
Fl_Button *btnDataSourceReset=(Fl_Button *)0;
static void cb_btnDataSourceReset(Fl_Button*, void*) {
DerivedRecordLst::cbGuiReset();
}
Fl_Double_Window* make_record_loader_window() {
Fl_Double_Window* w;
{ Fl_Double_Window* o = new Fl_Double_Window(540, 280, "Data files sources");
w = o;
o->tooltip("Data files update");
{ tabDataFiles = new Fl_Group(5, 25, 570, 275);
tabDataFiles->tooltip("Tabular data sources");
{ DerivedRecordLst* o = new DerivedRecordLst(6, 25, 529, 217, "Data files sources");
o->box(FL_THIN_DOWN_FRAME);
o->color(FL_BACKGROUND_COLOR);
o->selection_color(FL_BACKGROUND_COLOR);
o->labeltype(FL_NO_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->align(Fl_Align(FL_ALIGN_TOP));
o->when(FL_WHEN_RELEASE);
o->end();
Fl_Group::current()->resizable(o);
} // DerivedRecordLst* o
{ inpDataSources = new Fl_Input_Choice(6, 254, 284, 21, "Data source");
inpDataSources->tooltip("Data files repository");
inpDataSources->align(Fl_Align(FL_ALIGN_RIGHT));
} // Fl_Input_Choice* inpDataSources
{ btnDataSourceUpdate = new Fl_Light_Button(387, 254, 74, 20, "Update");
btnDataSourceUpdate->tooltip("Update selected local data files with repository content");
btnDataSourceUpdate->callback((Fl_Callback*)cb_btnDataSourceUpdate);
} // Fl_Light_Button* btnDataSourceUpdate
{ btnDataSourceReset = new Fl_Button(465, 254, 70, 20, "Reset");
btnDataSourceReset->tooltip("Delete local data files if selected.");
btnDataSourceReset->callback((Fl_Callback*)cb_btnDataSourceReset);
} // Fl_Button* btnDataSourceReset
tabDataFiles->end();
Fl_Group::current()->resizable(tabDataFiles);
} // Fl_Group* tabDataFiles
o->end();
} // Fl_Double_Window* o
return w;
}

Wyświetl plik

@ -0,0 +1,44 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0302
header_name {.h}
code_name {.cxx}
decl {\#include <config.h>} {private local
}
decl {\#include "record_loader_gui.h"} {public global
}
decl {\#include <FL/Fl_Double_Window.H>} {public local
}
Function {make_record_loader_window()} {open
} {
Fl_Window {} {
label {Data files sources} open
tooltip {Data files update} xywh {614 112 540 280} type Double resizable visible
} {
Fl_Group tabDataFiles {open
tooltip {Tabular data sources} xywh {5 25 570 275} resizable
} {
Fl_Table {} {
label {Data files sources} open
xywh {6 25 529 217} labeltype NO_LABEL resizable
class DerivedRecordLst
} {}
Fl_Input_Choice inpDataSources {
label {Data source} open
tooltip {Data files repository} xywh {6 254 284 21} align 8
} {}
Fl_Light_Button btnDataSourceUpdate {
label Update
callback {DerivedRecordLst::cbGuiUpdate();}
tooltip {Update selected local data files with repository content} xywh {387 254 74 20}
}
Fl_Button btnDataSourceReset {
label Reset
callback {DerivedRecordLst::cbGuiReset();}
tooltip {Delete local data files if selected.} xywh {465 254 70 20}
}
}
}
}

Wyświetl plik

@ -436,7 +436,7 @@ int MAC_chooser::options() const {
int MAC_chooser::show() {
// Make sure fltk interface updates before posting our dialog
Fl::flush();
Fl::awake();
// BROWSER TITLE
CFStringRef cfs_title;

Wyświetl plik

@ -449,4 +449,43 @@ void fftfilt::rtty_order(double f, int N, double twarp, double alpha)
pass = 2;
// delete tmpfft;
// Stefan's latest
f*=1.275; // This factor is ominous to me. I can't explain it. It shouldn't
// be there. But if I leave it out ht(f) differs inbetween the
// raised cosine from above and this one. And if left out the error
// rate increases... So, this is an unsolved mystery for now.
for( int i = 0; i < filterlen/2; ++i ) {
double a = 1.0;
double x = (double)i/(double)(filterlen/2);
// raised cosine response (changed for -1.0...+1.0 times Nyquist-f
// instead of books versions ranging from -1..+1 times samplerate)
double ht =
fabs(x) <= (1.0 - a)/(1.0/f) ? 1.0:
fabs(x) > (1.0 + a)/(1.0/f) ? 0.0:
cos(M_PI/(f*4.0*a)*(fabs(x)-(1.0-a)/(1.0/f)));
ht *= ht; // cos^2
// equalized nyquist-channel response
double eq = 1.0/sinc((double)i*f*2);
// compensate for "awkward" FFT-implementation. For every other imple-
// mentation of a FFT this would have been just...
filter[i].re = eq*ht*sin((double)i* - 0.5*M_PI);
filter[i].im = eq*ht*cos((double)i* - 0.5*M_PI);
filter[(filterlen-i)%filterlen].re = eq*ht*sin((double)i*+0.5*M_PI);
filter[(filterlen-i)%filterlen].im = eq*ht*cos((double)i*+0.5*M_PI);
// ... this (caused most headache):
//filter[i].re = eq*ht*0.7071;
//filter[i].im = eq*ht*0.7071;
//filter[(filterlen-i)%filterlen].re = eq*ht*0.7071;
//filter[(filterlen-i)%filterlen].im = eq*ht*0.7071;
}
}

10
src/flsynop.rc 100644
Wyświetl plik

@ -0,0 +1,10 @@
#define BUILD_FLDIGI 1
#include "config.h"
#define IDI_ICON 101
IDI_ICON ICON DISCARDABLE "fldigi.ico"
#define RC_FILE_VERSION_QUAD FLDIGI_VERSION_MAJOR,FLDIGI_VERSION_MINOR,0,0
#define RC_FILE_DESCRIPTION "Fast Light Digital Modem Application"
#include "common.rc"

Wyświetl plik

@ -340,6 +340,9 @@ extern Fl_Counter2 *cntrAUTOCRLF;
extern Fl_Check_Button *btnCRCRLF;
extern Fl_Check_Button *chkUOStx;
extern Fl_Check_Button *chkPseudoFSK;
extern Fl_Check_Button *btnSynopAdifDecoding;
extern Fl_Check_Button *btnSynopKmlDecoding;
extern Fl_Check_Button *btnSynopInterleaved;
extern Fl_Group *tabTHOR;
extern Fl_Input2 *txtTHORSecondary;
extern Fl_Check_Button *valTHOR_FILTER;
@ -351,8 +354,7 @@ extern Fl_Check_Button *valTHOR_SOFTBITS;
extern Fl_Counter2 *valTHOR_PATHS;
extern Fl_Group *tabNavtex;
extern Fl_Check_Button *btnNvtxAdifLog;
extern Fl_Output *txtNvtxCatalog;
extern Fl_Button *btnSelectNvtxCatalog;
extern Fl_Check_Button *btnNvtxKmlLog;
extern Fl_Group *tabWefax;
extern Fl_Check_Button *btnWefaxAdifLog;
extern Fl_Check_Button *btnWefaxEmbeddedGui;
@ -550,6 +552,18 @@ extern Fl_Check_Button *btn_wx_inches;
extern Fl_Check_Button *btn_wx_mbars;
#include "weather.h"
extern Fl_Button *btn_metar_search;
extern Fl_Group *tabKML;
extern Fl_Input *btnKmlSaveDir;
extern Fl_Input *inputKmlRootFile;
extern Fl_Counter *cntKmlMergeDistance;
extern Fl_Counter *cntKmlRetentionTime;
extern Fl_Spinner2 *cntKmlRefreshInterval;
extern Fl_Choice *selKmlBalloonStyle;
extern Fl_Input *btnKmlCommand;
extern Fl_Button *btlTestKmlCommand;
extern Fl_Button *btnSelectKmlDestDir;
extern Fl_Button *btlPurge;
extern Fl_Check_Button *btnKmlPurgeOnStartup;
extern Fl_Group *tabQRZ;
extern Fl_Tabs *tabsQRZ;
extern Fl_Round_Button *btnQRZWEBnotavailable;
@ -621,6 +635,6 @@ void closeDialog();
void createConfig();
class Fl_File_Chooser ;
void WefaxDestDirSet(Fl_File_Chooser *w, void *userdata);
void NvtxCatalogSet(Fl_File_Chooser *w, void *userdata);
void KmlDestDirSet(Fl_File_Chooser *w, void *userdata);
void make_window();
#endif

Wyświetl plik

@ -26,6 +26,7 @@
#define _CONFIGURATION_H
#include <string>
#include <math.h>
#include "rtty.h"
#include "waterfall.h"
@ -340,6 +341,15 @@
ELEM_(bool, PseudoFSK, "PSEUDOFSK", \
"Generate Pseudo-FSK signal on right audio channel", \
false) \
ELEM_(bool, SynopAdifDecoding, "SYNOPADIFDECODING", \
"Decoding of Synop weather information on RTTY to ADIF log", \
false) \
ELEM_(bool, SynopKmlDecoding, "SYNOPKMLDECODING", \
"Decoding of Synop weather information on RTTY to KML file", \
false) \
ELEM_(bool, SynopInterleaved, "SYNOPINTERLEAVED", \
"Decoding of Synop interleaved with coded text, or replaces it", \
false) \
ELEM_(bool, UOSrx, "UOSRX", \
"Revert to unshifted chars on a space (RX)", \
true) \
@ -1168,7 +1178,7 @@
"This setting is currently unused", \
true) \
ELEM_(double, TxMonitorLevel, "TXMONITORLEVEL", \
"Level for monitored (on watrerfall) transmit signal", \
"Level for monitored (on waterfall) transmit signal", \
0.5) \
/* Waterfall palette */ \
ELEM_(std::string, PaletteName, "PALETTENAME", \
@ -1550,43 +1560,69 @@
ELEM_(bool, NVTX_AdifLog, "NAVTEXADIFLOG", \
"Logs Navtex messages in Adig log file", \
false) \
ELEM_(std::string, NVTX_Catalog, "NAVTEXCATALOG", \
"Catalog pathname of Navtex stations", \
PKGDATADIR "/NAVTEX_Stations.csv") \
ELEM_(bool, NVTX_KmlLog, "NAVTEXKMLLOG", \
"Logs Navtex messages to KML document", \
false) \
ELEM_(int, NVTX_MinSizLoggedMsg, "NAVTEXMINSIZLOGGEDMSG", \
"Minimum length of logged messages", \
0 ) \
/* WX fetch from NOAA */ \
ELEM_(std::string, wx_eoh, "WX_EOH", \
"Text at end of METAR report header\n" \
"default = Connection: close", \
"Connection: close") \
ELEM_(std::string, wx_sta, "WX_STA", \
"4 letter specifier for wx station", \
"KMDQ") \
ELEM_(bool, wx_condx, "WX_CONDX", \
"weather conditions", \
"Weather conditions", \
true) \
ELEM_(bool, wx_fahrenheit, "WX_FAHRENHEIT", \
"report in Fahrenheit", \
"Report in Fahrenheit", \
true) \
ELEM_(bool, wx_celsius, "WX_CELSIUS", \
"report in Celsius", \
"Report in Celsius", \
true) \
ELEM_(bool, wx_mph, "WX_MPH", \
"report speed in miles per hour", \
"Report speed in miles per hour", \
true) \
ELEM_(bool, wx_kph, "WX_KPH", \
"report speed in kilometers per hour", \
"Report speed in kilometers per hour", \
true) \
ELEM_(bool, wx_inches, "WX_INCHES", \
"report pressure in inches of mercury", \
"Report pressure in inches of mercury", \
true) \
ELEM_(bool, wx_mbars, "WX_MBARS", \
"report pressure in millibars", \
"Report pressure in millibars", \
true) \
ELEM_(bool, wx_full, "WX_FULL", \
"use complete METAR report", \
"Use complete METAR report", \
true) \
ELEM_(bool, wx_station_name, "WX_STATION_NAME", \
"report station noun name", \
"Report station noun name", \
true) \
/* KML Keyhole Markup Language */ \
ELEM_(bool, kml_purge_on_startup, "KML_PURGE_ON_STARTUP", \
"Purge KML data at startup", \
false) \
ELEM_(std::string, kml_save_dir, "KML_SAVE_DIR", \
"Destination directory for generated KML documents", \
"") \
ELEM_(std::string, kml_command, "KML_COMMAND", \
"Command executed when creating KML files", \
"") \
ELEM_(int, kml_merge_distance, "KML_MERGE_DISTANCE", \
"Minimum distance for splitting alias nodes", \
10000) \
ELEM_(int, kml_retention_time, "KML_RETENTION_TIME", \
"Number of hours for keeping data in each node", \
0) \
ELEM_(int, kml_refresh_interval, "KML_REFRESH_INTERVAL", \
"Refresh interval written in KML files (In seconds)", \
120) \
ELEM_(int, kml_balloon_style, "KML_BALLOON_STYLE", \
"KML balloons data displayed as text, HTML tables, HTML single matrix", \
2) \
// declare the struct

Wyświetl plik

@ -0,0 +1,93 @@
// ----------------------------------------------------------------------------
// coordinate.h -- Handling of longitude and latitude.
//
// Copyright (C) 2012
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef _COORDINATE_H
#define _COORDINATE_H
#include <iostream>
// Models a longitude or latitude.
class CoordinateT
{
// Precision is: 360 * 3600 = 1296000, 21 bits. A float might be enough.
double m_angle ; // In decimal degrees, between -180.0 and 180.0.
bool m_is_lon ; // Longitude or latitude.
// TODO: Consider adding a big offset to m_angle, instead of an extra flag.
void Check(void) const ;
void Init( char direction, double degrees );
public:
CoordinateT(bool ll=true)
: m_angle(0.0), m_is_lon(ll) {};
CoordinateT( double degrees, bool is_lon );
CoordinateT( char direction, double degrees );
CoordinateT( char direction, int degree, int minute, int second );
double angle(void) const { return m_angle ; }
bool is_lon(void) const { return m_is_lon; }
// Specific for reading from the file of navtex or wmo stations.
// Navtex: "57 06 N"
// Wmo : "69-36N", "013-27E", "009-25E"
friend std::istream & operator>>( std::istream & istrm, CoordinateT & ref );
friend std::ostream & operator<<( std::ostream & ostrm, const CoordinateT & ref );
class Pair ;
}; // CoordinateT
// Longitude , latitude.
class CoordinateT::Pair
{
CoordinateT m_lon, m_lat ;
public:
Pair() {}
Pair( const CoordinateT & coo1, const CoordinateT & coo2 );
Pair( double lon, double lat );
Pair( const std::string & locator );
CoordinateT longitude() const { return m_lon ; }
CoordinateT latitude() const { return m_lat ; }
CoordinateT & longitude() { return m_lon ; }
CoordinateT & latitude() { return m_lat ; }
double distance( const Pair & a ) const;
std::string locator() const ;
friend std::istream & operator>>( std::istream & istrm, Pair & ref );
friend std::ostream & operator<<( std::ostream & ostrm, const Pair & ref );
}; // CoordinateT::Pair
#endif // _COORDINATE_H

Wyświetl plik

@ -23,6 +23,8 @@
#ifndef _DEBUG_H_
#define _DEBUG_H_
#define DEBUG_PSKMAIL 1
#include "util.h"
class debug
@ -84,6 +86,9 @@ unused__ static uint32_t log_source_ = debug::LOG_OTHER;
#define LOG_SET_SOURCE(source__) log_source_ = source__
extern bool debug_pskmail;
extern bool debug_audio;
#endif // _DEBUG_H_
// Local Variables:

Wyświetl plik

@ -0,0 +1,107 @@
// ----------------------------------------------------------------------------
// doxygen.h
//
// Copyright (C) 2013
// John Phelps, KL4YFD
//
// This file is part of fldigi.
//
// fldigi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
/*
This include file is not indended to be included by any source file in Fldigi,
but is used only for DOXYGEN automatic-documentation generation.
Please put only comments & Doxygen info in this file.
*/
/** \mainpage Fldigi 3.21 doxygen documentation
<div align="center"><img src="../../../data/fldigi-psk.png" ></div>
\section intro Introduction
Welcome to the Fldigi doxygen documentation.
Here you'll find information useful for developing and debugging fldigi and flarq.
fldigi - Digital modem program for Linux, Free-BSD, OS X, Windows XP, NT, W2K, Vista and Win7.
flarq - Automatic Repeat reQuest program.
Fldigi and Flarq are separate programs that are packaged together as source, binary, and installation files.
Build updated to fltk-1.3.0 library standards. Can also be built using fltk-1.1.10
\section download To Download Fldigi :
<UL>
<LI> latest release version at: <A HREF="http://www.w1hkj.com/download.html">http://www.w1hkj.com/download.html</A></LI>
<LI> beta versions at: <A HREF="http://www.w1hkj.com/beta">http://www.w1hkj.com/beta</A></LI>
<LI> alpha versions at: <A HREF="http://www.w1hkj.com/alpha">http://www.w1hkj.com/alpha</A></LI>
<LI> pre-alpha & test versions at: <A HREF="http://www.w1hkj.com/temp">http://www.w1hkj.com/temp</A></LI>
<LI> To pull latest source from main repository: <B>git clone git://git.berlios.de/fldigi</B></LI>
</UL>
\section entry Good Entry-Points for Navigating the Doxygen Documentation :
<UL>
<LI><A HREF="annotated.html">List of all Classes and Data Structures</A></LI>
<LI><A HREF="classmodem.html">The modem:: class documentation</A></LI>
<LI><A HREF="classmodem__inherit__graph.png">The modem:: class inheritange graph</A></LI>
<LI><A HREF="globals.html">list of all functions, variables, defines, enums, and typedefs with links to the files they belong to</A></LI>
</UL>
\section cppcheck_results Results from the cppcheck static program analysis tool:
Analysis was ran during doxygen documentation generation.
<UL>
<LI><A HREF="../../tests/cppcheck/results/error.txt">Errors</A></LI>
<LI><A HREF="../../tests/cppcheck/results/warning.txt">Warnings</A></LI>
<LI><A HREF="../../tests/cppcheck/results/style.txt">Code-Style Issues</A></LI>
<LI><A HREF="../../tests/cppcheck/results/performance.txt">Performance Issues</A></LI>
<LI><A HREF="../../tests/cppcheck/results/portability.txt">Portability Issues</A></LI>
<LI><A HREF="../../tests/cppcheck/results/information.txt">Information</A></LI>
<LI><B>Inconclusive tests did not FAIL, but also did not PASS</B></LI>
<LI><A HREF="../../tests/cppcheck/results/error_inconclusive.txt"><I>Inconclusive Errors</I></A></LI>
<LI><A HREF="../../tests/cppcheck/results/warning_inconclusive.txt"><I>Inconclusive Warnings</I></A></LI>
<LI><A HREF="../../tests/cppcheck/results/style_inconclusive.txt"><I>Inconclusive Code-Style Issues</I></A></LI>
<LI><A HREF="../../tests/cppcheck/results/performance_inconclusive.txt"><I>Inconclusive Performance Issues</I></A></LI>
<LI><A HREF="../../tests/cppcheck/results/portability_inconclusive.txt"><I>Inconclusive Portability Issues</I></A></LI>
<LI><A HREF="../../tests/cppcheck/results/information_inconclusive.txt"><I>Inconclusive Information</I></A></LI>
</UL>
\section git Information from git :
<UL>
<LI><A HREF="__git/">Patches for the last 125 commits</A></LI>
<LI><A HREF="__git/gitlog.txt">git-log for the last 125 commits</A></LI>
</UL>
\section license License
fldigi is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
fldigi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses
*/

Wyświetl plik

@ -36,6 +36,29 @@ SRX,
STX,
TX_PWR,
EXPORT, // flag used internally in fldigi's logbook
QSL_VIA,
NUMFIELDS };
// ADIF multiline string is a sequence of Characters and line-breaks,
// where a line break is an ASCII CR (code 13) followed immediately by an ASCII LF (code 10)
// Not sure fldigi is completely conformant with this.
// #define ADIF_EOL "\r\n"
#define ADIF_EOL "\n"
// Forward declaration for QsoHelper.
class cQsoRec ;
// Helps for creating a new ADIF record.
class QsoHelper {
cQsoRec * qso_rec ;
QsoHelper();
QsoHelper(const QsoHelper &);
QsoHelper & operator=(const QsoHelper &);
public:
QsoHelper(int mode);
~QsoHelper();
// Inserts a key-value pair.
void Push( ADIF_FIELD_POS pos, const std::string & value );
};
#endif

Wyświetl plik

@ -52,6 +52,8 @@ extern Fl_Double_Window *fl_digi_main;
extern Fl_Double_Window *scopeview;
//extern Fl_Double_Window *opBrowserView;
extern Fl_Double_Window *dlgRecordLoader;
extern bool NBEMSapps_dir;
extern FTextRX *ReceiveText;
@ -59,28 +61,24 @@ extern FTextTX *TransmitText;
extern pskBrowser *mainViewer;
extern Fl_Input2 *txtInpSeek;
extern Fl_Box *hideViewer;
extern Raster *FHdisp;
extern Fl_Group *mvgroup;
extern Fl_Group *mvgroup;
extern Panel *text_panel;
extern Fl_Box *minbox;
extern Fl_Group *MixerFrame;
extern int oix;
extern Fl_Box *StatusBar;
extern Fl_Box *Status2;
extern Fl_Box *Status1;
extern Fl_Counter2 *cntCW_WPM;
extern Fl_Counter2 *cntTxLevel;
extern Fl_Box *WARNstatus;
extern Fl_Button *MODEstatus;
extern Fl_Slider2 *sldrSquelch;
extern Progress *pgrsSquelch;
extern Progress *pgrsSquelch;
extern Fl_Button *btnMacro[];
extern Fl_Button *btnAltMacros1;
extern Fl_Button *btnAltMacros2;
extern Fl_Group *macroFrame1;
extern Fl_Group *macroFrame2;
extern Fl_Group *macroFrame1;
extern Fl_Group *macroFrame2;
extern Fl_Input2 *inpFreq;
extern Fl_Input2 *inpTimeOff;
extern Fl_Input2 *inpTimeOn;
@ -98,53 +96,38 @@ extern Fl_Input2 *inpVEprov;
extern Fl_Input2 *inpLoc;
extern Fl_Input2 *inpNotes;
extern Fl_Input2 *inpAZ; // WA5ZNU
extern Fl_Button *qsoClear;
extern Fl_Button *qsoSave;
extern Fl_Box *txtRigName;
extern cFreqControl *qsoFreqDisp1;
extern cFreqControl *qsoFreqDisp1;
extern cFreqControl *qsoFreqDisp2;
extern cFreqControl *qsoFreqDisp3;
extern cFreqControl *qsoFreqDisp3;
extern Fl_Input2 *inpFreq2;
extern Fl_Input2 *inpTimeOff2;
extern Fl_Input2 *inpTimeOn2;
extern Fl_Button *btnTimeOn2;
extern Fl_Input2 *inpName2;
extern Fl_Input2 *inpRstIn2;
extern Fl_Input2 *inpRstOut2;
extern Fl_Button *qsoClear2;
extern Fl_Button *qsoSave2;
extern Fl_Input2 *inpCall1;
extern Fl_Input2 *inpCall2;
extern Fl_Input2 *inpCall3;
extern Fl_Input2 *inpCall4;
extern Fl_Input2 *inpName1;
extern Fl_Group *QsoInfoFrame1B;
extern Fl_Group *qsoFrameView;
extern Fl_Group *QsoButtonFrame;
extern Fl_Group *QsoInfoFrame;
extern cFreqControl *qsoFreqDisp;
extern Fl_Group *QsoInfoFrame1B;
extern Fl_Group *qsoFrameView;
extern Fl_Group *QsoInfoFrame;
extern cFreqControl *qsoFreqDisp;
extern Fl_ComboBox *qso_opMODE;
extern Fl_ComboBox *qso_opBW;
extern Fl_Button *qso_opPICK;
extern Fl_Browser *qso_opBrowser;
extern Fl_Button *qso_btnAddFreq;
extern Fl_Button *qso_btnSelFreq;
extern Fl_Button *qso_btnDelFreq;
extern Fl_Button *qso_btnClearList;
extern Fl_Value_Slider2 *mvsquelch;
extern Fl_Value_Slider2 *valRcvMixer;
extern Fl_Value_Slider2 *valXmtMixer;
extern Fl_Value_Slider2 *mvsquelch;
extern Fl_Value_Slider2 *valRcvMixer;
extern Fl_Value_Slider2 *valXmtMixer;
extern Fl_Button *btnAFC;
extern Fl_Button *btnSQL;
extern Fl_Light_Button *btnRSID;
extern Fl_Light_Button *btnTxRSID;
extern Fl_Light_Button *btnTune;
extern Fl_Button *btnMacroTimer;
extern bool bWF_only;
extern bool bHAB;
@ -168,7 +151,7 @@ extern Fl_Output *habTimeSinceLastRx;
extern Fl_Output *habString;
extern bool withnoise;
extern int altMacros;
extern int altMacros;
extern int HAB_height;
extern int HAB_width;
@ -386,5 +369,6 @@ extern void cb_mnuCheckUpdate(Fl_Widget *, void *);
// dl-fldigi
void set_menu_dl_online(bool val);
void set_menu_dl_refresh_active(bool active);
bool ask_dir_creation( const std::string & dir );
#endif

Wyświetl plik

@ -0,0 +1,111 @@
// ----------------------------------------------------------------------------
// kmlserver.h -- KML Server
//
// Copyright (C) 2012
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef _KMLSERVER_H
#define _KMLSERVER_H
#include <limits.h>
#include <string>
#include <vector>
#include <sstream>
#include <coordinate.h>
/// Keyhole Markup Language: This publishes a complete message, localisation+time+weather etc...
class KmlServer {
protected:
/// Counts the number of complete messages written.
int m_nb_broadcasts ;
int exit_kml_server;
int request_broadcast;
public:
/// List of key-value pairs displayed for example in Google Earth balloons.
struct CustomDataT : public std::vector< std::pair< std::string, std::string > > {
/// Also used when reloading a KML file.
void Push( const char * k, const std::string & v );
/// TODO: Most of keys are duplicated. Should store them in a hash to reduce memory footprint.
void Push( const char * k, const char * v ) {
Push( k, std::string(v) );
}
/// This helper makes insertions simpler.
template< class Type >
void Push( const char * k, const Type & v ) {
std::stringstream strm ;
strm << v ;
Push( k, strm.str() );
}
};
KmlServer() : m_nb_broadcasts(0), exit_kml_server(0), request_broadcast(0) {}
virtual ~KmlServer() {}
/// BEWARE: Will work until 2038.
static const time_t UniqueEvent = INT_MAX ;
/// This can for example go to a NMEA client.
virtual void Broadcast(
const std::string & category,
time_t evtTim,
const CoordinateT::Pair & refCoo,
double altitude,
const std::string & kml_name,
const std::string & styleNam,
const std::string & descrTxt,
const CustomDataT & custDat ) = 0;
/// Singleton.
static KmlServer * GetInstance(void);
/// Number of calls to Broadcast(). Debugging purpose only.
int NbBroadcasts(void) const { return m_nb_broadcasts; }
/// Debugging only, just to check what happens inside.
void ResetCounter() { m_nb_broadcasts = 0;}
virtual void Reset() = 0;
/// TODO: Maybe have one display style per category, instead of the same for all.
virtual void InitParams(
const std::string & kml_command,
const std::string & kml_dir,
double kml_merge = 10000,
int kml_retention = 0, // Keep all data.
int kml_refresh = 120,
int kml_balloon_style = 0) = 0;
virtual void ReloadKmlFiles() = 0;
/// Creates the process for the command to be run when KML data is saved.
static void SpawnProcess();
/// Stops the sub-thread, flush KML data to the files.
static void Exit();
static std::string Tm2Time( time_t tim );
/// No value means, now.
static std::string Tm2Time(void);
};
#endif // _KMLSERVER_H

Wyświetl plik

@ -37,6 +37,7 @@ extern Fl_Check_Button *btnSelectRSTrcvd;
extern Fl_Check_Button *btnSelectQth;
extern Fl_Check_Button *btnSelectLOC;
extern Fl_Check_Button *btnSelectState;
extern Fl_Check_Button *btnSelectQSL_VIA;
extern Fl_Check_Button *btnSelectProvince;
extern Fl_Check_Button *btnSelectCountry;
extern Fl_Check_Button *btnSelectNotes;
@ -79,6 +80,7 @@ extern Fl_Input2 *inpCQZ_log;
extern Fl_Input2 *inpITUZ_log;
extern Fl_Input2 *inpCONT_log;
extern Fl_Input2 *inpDXCC_log;
extern Fl_Input2 *inpQSL_VIA_log;
extern Fl_Input2 *inpSerNoOut_log;
extern Fl_Input2 *inpMyXchg_log;
extern Fl_Input2 *inpSerNoIn_log;

Wyświetl plik

@ -25,7 +25,9 @@ extern std::string MacrosDir;
extern std::string WrapDir;
extern std::string TalkDir;
extern std::string TempDir;
extern std::string KmlDir;
extern std::string PskMailDir;
extern std::string DATA_dir;
extern std::string NBEMS_dir;
extern std::string ARQ_dir;
extern std::string ARQ_files_dir;
@ -78,24 +80,15 @@ extern void arq_close();
extern void WriteARQ(unsigned char);
extern void checkTLF();
#define ARQBUFSIZ 8192
struct RXMSGSTRUC {
long int msg_type;
char c;
};
struct TXMSGSTRUC {
long int msg_type;
char buffer[ARQBUFSIZ];
};
extern RXMSGSTRUC rxmsgst;
extern int rxmsgid;
extern TXMSGSTRUC txmsgst;
extern int txmsgid;
void check_nbems_dirs(void);
extern bool nbems_dirs_checked;
// This inits or reinits everything related to KML: Reloads params etc...
void kml_init(bool load_files = false);
// close down remaining threads just before exiting UI
extern void exit_process();
int directory_is_created( const char * strdir );
#endif

Wyświetl plik

@ -18,8 +18,9 @@
#define TWOPI (2.0 * M_PI)
class modem : public morse {
class modem {
protected:
cMorse morse;
trx_mode mode;
SoundBase *scard;

Wyświetl plik

@ -47,16 +47,16 @@ struct CW_XMT_TABLE {
const char *prt;
};
class morse {
class cMorse {
private:
CW_TABLE *cw_rx_lookup[256];
CW_XMT_TABLE cw_tx_lookup[256];
unsigned int tokenize_representation(const char *representation);
public:
morse() {
cMorse() {
init();
}
~morse() {
~cMorse() {
}
void init();
const char *rx_lookup(char *r);

Wyświetl plik

@ -6,6 +6,7 @@
bool request_reply(const std::string& node, const std::string& service,
const std::string& request, std::string& reply, double timeout = 0.0);
bool fetch_http(const std::string& url, std::string& reply, double timeout = 0.0);
bool fetch_http_gui(const std::string& url, std::string& reply, double timeout = 0.0);
bool fetch_http_gui(const std::string& url, std::string& reply, double timeout,
void(*busy)(void*), void* arg1, void(*done)(void*), void* arg2);

Wyświetl plik

@ -131,8 +131,8 @@ public:
break;
sched_yield();
}
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
fsignal s(&m, &c);
pthread_mutex_lock(&m);
for (;;) {

Wyświetl plik

@ -0,0 +1,18 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0302
#ifndef record_browse_h
#define record_browse_h
#include <FL/Fl.H>
#include "record_loader_gui.h"
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Group.H>
extern Fl_Group *tabDataFiles;
#include <FL/Fl_Input_Choice.H>
extern Fl_Input_Choice *inpDataSources;
#include <FL/Fl_Light_Button.H>
extern Fl_Light_Button *btnDataSourceUpdate;
#include <FL/Fl_Button.H>
extern Fl_Button *btnDataSourceReset;
Fl_Double_Window* make_record_loader_window();
#endif

Wyświetl plik

@ -0,0 +1,83 @@
// ----------------------------------------------------------------------------
// record_loader.h
//
// Copyright (C) 2013
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef RECORD_LOADER_H
#define RECORD_LOADER_H
#include <iosfwd>
#include <string>
class RecordLoaderInterface
{
RecordLoaderInterface & operator=( const RecordLoaderInterface & );
public:
RecordLoaderInterface();
virtual void Clear() = 0 ;
/// Reads just one record.
virtual bool ReadRecord( std::istream & ) = 0 ;
/// Loads a file and stores it for later lookup. Returns the number of records, or -1.
int LoadAndRegister();
std::string ContentSize() const ;
virtual ~RecordLoaderInterface();
/// Base name. In case the URL is not nice enough to build a clean data filename.
virtual std::string base_filename() const ;
/// The place where we store the data locally.
std::pair< std::string, bool > storage_filename(bool create_dir = false) const ;
virtual const char * Url() const { return NULL; }
virtual const char * Description() const = 0 ;
std::string Timestamp() const;
static void SetDataDir( const std::string & data_dir );
}; // RecordLoaderInterface
/// Loads records from a file or an Url.
template< class Catalog >
class RecordLoaderSingleton
{
static Catalog s_cata_inst ;
public:
static Catalog & InstCatalog() {
return s_cata_inst ;
}
};
template<class Catalog> Catalog RecordLoaderSingleton< Catalog >::s_cata_inst = Catalog();
/// Loads tabular records from a file.
template< class Catalog >
struct RecordLoader : public RecordLoaderInterface, public RecordLoaderSingleton<Catalog>
{
}; // RecordLoader
void createRecordLoader();
#endif // RECORD_LOADER_H

Wyświetl plik

@ -0,0 +1,28 @@
#ifndef RECORD_LOADER_GUI_H
#define RECORD_LOADER_GUI_H
#include <FL/Fl_Table.H>
#include <FL/Fl_Double_Window.H>
class RecordLoaderInterface ;
class DerivedRecordLst : public Fl_Table
{
DerivedRecordLst();
DerivedRecordLst( const DerivedRecordLst & );
DerivedRecordLst & operator=( const DerivedRecordLst & );
public:
DerivedRecordLst(int, int, int, int, const char * title = 0);
virtual ~DerivedRecordLst();
static void cbGuiUpdate();
static void cbGuiReset();
void AddRow(int R);
void DrawRow(int R);
protected:
void draw_cell(TableContext context, // table cell drawing
int R=0, int C=0, int X=0, int Y=0, int W=0, int H=0);
};
#endif // RECORD_LOADER_GUI_H

Wyświetl plik

@ -9,6 +9,8 @@ extern Cserial rigio;
extern bool hexout(const std::string&);
extern bool sendCommand(std::string, int retnbr);
extern long long rigCAT_getfreq(int retries, bool &failed);
extern void rigCAT_setfreq(long long);

Wyświetl plik

@ -80,15 +80,18 @@ enum { INITIAL, EXTENDED, WAIT };
private:
// Table of precalculated Reed Solomon symbols
unsigned char *pCodes;
unsigned char *pCodes1;
unsigned char *pCodes2;
static const RSIDs rsid_ids[];
static const int rsid_ids_size;
bool found1;
bool found2;
static const RSIDs rsid_ids_1[];
static const int rsid_ids_size1;
static const int Squares[];
static const int indices[];
static const RSIDs rsid_ids2[];
static const RSIDs rsid_ids_2[];
static const int rsid_ids_size2;
int rsid_secondary_time_out;
@ -105,27 +108,24 @@ private:
Cfft *rsfft;
// Hashing tables
unsigned char aHashTable1[RSID_HASH_LEN];
unsigned char aHashTable2[RSID_HASH_LEN];
unsigned char hash_table_A[RSID_HASH_LEN];
unsigned char hash_table_B[RSID_HASH_LEN];
unsigned char aHashTable1_2[RSID_HASH_LEN];
unsigned char aHashTable2_2[RSID_HASH_LEN];
unsigned char hash_table_C[RSID_HASH_LEN];
unsigned char hash_table_D[RSID_HASH_LEN];
bool bPrevTimeSliceValid;
int iPrevDistance;
int iPrevBin;
int iPrevSymbol;
int iTime; // modulo RSID_NTIMES
int aBuckets[RSID_NTIMES][RSID_FFT_SIZE];
int i1, i2, i3;
int aBuckets[RSID_NTIMES][RSID_FFT_SIZE]; // history of detected rsid tones
bool bPrevTimeSliceValid2;
int iPrevDistance2;
int iPrevBin2;
int iPrevSymbol2;
int iTime2; // modulo RSID_NTIMES
int DistanceOut;
int MetricsOut;
// resample
SRC_STATE* src_state;
@ -141,11 +141,12 @@ private:
void Encode(int code, unsigned char *rsid);
int HammingDistance(int iBucket, unsigned char *p2);
void CalculateBuckets(const double *pSpectrum, int iBegin, int iEnd);
bool search_amp( int &pSymbolOut, int &pBinOut);
bool search_amp2( int &pSymbolOut, int &pBinOut);
bool search_amp1( int &pSymbolOut, int &pBinOut, unsigned char *table);
bool search_amp2( int &pSymbolOut, int &pBinOut, unsigned char *table);
void search(void);
void apply (int iSymbol, int iBin);
void apply1 (int iSymbol, int iBin);
void apply2 (int iSymbol, int iBin);
void setup_mode(int m);
public:
cRsId();
~cRsId();

Wyświetl plik

@ -133,7 +133,6 @@ private:
int symbollen;
int bytelen;
int nbits;
// RTTY_PARITY parity;
int stoplen;
int msb;
bool useFSK;
@ -146,7 +145,6 @@ private:
int rtty_bits;
RTTY_PARITY rtty_parity;
int rtty_stop;
bool rtty_reverse;
bool rtty_msbfirst;
double mark_noise;

Wyświetl plik

@ -133,8 +133,137 @@ std::basic_string<CharT> join(const std::basic_string<CharT>* begin, size_t len
std::vector<std::string> split(const char* re_str, const char* str, unsigned max_split = UINT_MAX);
// Fills a string with snpritnf format string.
std::string strformat( const char * fmt, ... );
// Eliminates spaces and tabs at the beginning and the end.
void strtrim( std::string & str );
// First letter of each word in uppercase, the rest in lowercase.
void strcapitalize( std::string & str );
// Returns the replacement of all occurences of a given string by another.
std::string strreplace( const std::string & inp, const std::string & from, const std::string & to );
/// Edit distance: Returns an integer which is the distance between the two strings.
size_t levenshtein(const std::string & source, const std::string & target);
// Conversion to uppercase.
std::string uppercase( const std::string & str );
// ----------------------------------------------------------------------------
/// This is a read-only replacement for std::stringstream.
struct imemstream : public std::streambuf, public std::istream {
/// Faster than stringstream because no copy.
imemstream(char* s, std::size_t n) : std::istream( this )
{
setg(s, s, s + n);
}
/// Faster than stringstream because no copy.
imemstream(const std::string & r) : std::istream( this )
{
char * s = const_cast< char * >( r.c_str() );
setg(s, s, s + r.size());
}
};
// ----------------------------------------------------------------------------
/// Tells if type is a char[]. Used for SFINAE.
template< class T >
struct DtTyp {
/// In the general case, data types are not char arrays.
struct Any {};
};
/// Matches if the type is a char[].
template< size_t N >
struct DtTyp< char[N] > {
struct Array {};
static const size_t Size = N ;
};
/// Reads all chars until after the delimiter.
bool read_until_delim( char delim, std::istream & istrm );
/// Reads a char followed by the delimiter.
bool read_until_delim( char delim, std::istream & istrm, char & ref, const char dflt );
/// Reads a double up to the given delimiter.
inline bool read_until_delim( char delim, std::istream & istrm, double & ref )
{
istrm >> ref ;
if( ! istrm ) return false ;
char tmp = istrm.get();
if( istrm.eof() ) {
/// Resets to good to mean that it worked fine.
istrm.clear();
return true ;
}
return tmp == delim ;
}
/// Reads a string up to the given delimiter.
inline bool read_until_delim( char delim, std::istream & istrm, std::string & ref )
{
return std::getline( istrm, ref, delim );
}
/// For reading from a string with tokens separated by a char. Used to load CSV files.
template< typename Tp >
bool read_until_delim( char delim, std::istream & istrm, Tp & ref, typename DtTyp< Tp >::Any = typename DtTyp< Tp >::Any() )
{
std::string parsed_str ;
if( ! std::getline( istrm, parsed_str, delim ) ) {
return false ;
}
imemstream sstrm( parsed_str );
sstrm >> ref ;
return sstrm ;
}
/// Same, with a default value if there is nothing to read.
template< typename Tp >
bool read_until_delim( char delim, std::istream & istrm, Tp & ref, const Tp dflt, typename DtTyp< Tp >::Any = typename DtTyp< Tp >::Any() )
{
std::string parsed_str ;
if( ! std::getline( istrm, parsed_str, delim ) ) {
return false ;
}
if( parsed_str.empty() ) {
ref = dflt ;
return true;
}
imemstream sstrm( parsed_str );
sstrm >> ref ;
return sstrm ;
}
/// For reading from a string with tokens separated by a char to a fixed-size array.
template< typename Tp >
bool read_until_delim( char delim, std::istream & istrm, Tp & ref, typename DtTyp< Tp >::Array = typename DtTyp< Tp >::Array() )
{
istrm.getline( ref, DtTyp< Tp >::Size, delim );
// Should we return an error if buffer is too small?
return istrm ;
}
/// Same, with a default value if there is nothing to read. Fixed-size array.
template< typename Tp >
bool read_until_delim( char delim, std::istream & istrm, Tp & ref, const Tp dflt, typename DtTyp< Tp >::Array = typename DtTyp< Tp >::Array() )
{
istrm.getline( ref, DtTyp< Tp >::Size, delim );
// If nothing to read, copy the default value.
if( ref[0] == '\0' ) {
strncpy( ref, dflt, DtTyp< Tp >::Size - 1 );
}
// Should we return an error if buffer is too small?
return istrm;
}
// ----------------------------------------------------------------------------
#endif // STRUTIL_H_
// Local Variables:

Wyświetl plik

@ -0,0 +1,96 @@
// ----------------------------------------------------------------------------
// synop.h -- SYNOP decoding
//
// Copyright (C) 2012
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#ifndef _SYNOP_H
#define _SYNOP_H
// This tells how Synop data are serialized.
class synop_callback {
public:
virtual ~synop_callback() {} ;
// These methods could as well be pure virtual.
virtual bool interleaved(void) const { return true; }
virtual void print( const char * str, size_t nb, bool ) const = 0;
virtual bool log_adif(void) const = 0;
virtual bool log_kml(void) const = 0 ;
};
// Implementation hidden in synop.cxx
class synop {
// When set, the output does not contain Synop sentences but only
// the name of the regular expression which matched. It helps
// for debugging because the output is independent of the locale.
static bool m_test_mode ;
public:
static const synop_callback * ptr_callback ;
template< class Callback >
static void setup()
{
static const Callback cstCall = Callback();
ptr_callback = &cstCall ;
};
static synop * instance();
static void regex_usage(void);
virtual ~synop() {};
// It is used as a global object, the constructor does not do anything.
virtual void init() = 0;
virtual void cleanup() = 0;
/// We should have a tempo as well.
virtual void add(char c) = 0;
// When Synop decoding is disabled.
virtual void flush(bool finish_decoding) = 0;
virtual bool enabled(void) const = 0;
static bool GetTestMode(void) { return m_test_mode ; };
static void SetTestMode(bool test_mode) { m_test_mode = test_mode ; };
};
// gathers the various data files used for Synop decoding.
struct SynopDB {
// Loads the files from s given directory.
static bool Init( const std::string & data_dir );
// For testing purpose.
static const std::string & IndicatorToName( int wmo_indicator );
static const std::string IndicatorToCoordinates( int wmo_indicator );
// To Test the reading of our weather stations data files.
static const std::string & BuoyToName( const char * buoy_id );
static const std::string & ShipToName( const char * ship_id );
static const std::string & JCommToName( const char * ship_id );
};
// ----------------------------------------------------------------------------
#endif // _SYNOP_H

Wyświetl plik

@ -62,6 +62,10 @@
#define THORSLOWPATHS 3
#define THORFASTPATHS 5
// the following constant changes if a mode with more tones than 25x4 is
// created
#define MAXPATHS (8 * THORFASTPATHS * THORNUMTONES )
struct THORrxpipe {
complex vector[THORMAXFFTS * THORNUMTONES * 6];
};

Wyświetl plik

@ -40,9 +40,7 @@ int pthread_cond_timedwait_rel(pthread_cond_t* cond, pthread_mutex_t* mutex, dou
enum {
INVALID_TID = -1,
TRX_TID, QRZ_TID, RIGCTL_TID, NORIGCTL_TID, EQSL_TID, ADIF_RW_TID,
#if USE_XMLRPC
XMLRPC_TID,
#endif
ARQ_TID, ARQSOCKET_TID,
FLMAIN_TID,
NUM_THREADS, NUM_QRUNNER_THREADS = NUM_THREADS - 1

Wyświetl plik

@ -25,4 +25,9 @@ struct timeval& operator-=(struct timeval &t0, const struct timeval &t1);
bool operator>(const struct timeval &t0, const struct timeval &t1);
bool operator==(const struct timeval &t0, const struct timeval &t1);
#ifndef GMTIME_R
extern struct tm *gmtime_r(const time_t *timer, struct tm *tmbuf);
extern struct tm *localtime_r(const time_t *_Time,struct tm *_Tm);
#endif
#endif // TIMEOPS_H_

Wyświetl plik

@ -201,14 +201,24 @@ deprecated__ typeof(strcat) strcat;
# define PATH_SEP "/"
// Unnamed sempahores are not supported on OS X
// (and named semaphores are broken on cygwin).
/// Unnamed sempahores are not supported on OS X (and named semaphores are broken on cygwin).
#ifdef __APPLE__
# define USE_NAMED_SEMAPHORES 1
#else
# define USE_NAMED_SEMAPHORES 0
#endif
/// Returns 0 if a process is running, 0 if not there and -1 if the test cannot be made.
int test_process(int pid);
/// Starts a process and returns its pid, and -1 if error. Returns 0 if this cannot be made.
int fork_process( const char * cmd );
/// Returns NULL if no error.
const char * create_directory( const char * dir );
int directory_is_created( const char * dir );
#endif /* UTIL_H */
/*

Wyświetl plik

@ -128,7 +128,6 @@ private:
int rtty_bits;
RTTY_PARITY rtty_parity;
int rtty_stop;
bool rtty_reverse;
bool rtty_msbfirst;
int bflen;

Wyświetl plik

@ -7,7 +7,7 @@
#include <stdio.h>
/** \mainpage irrXML 1.2 API documentation
/** irrXML 1.2 API documentation
<div align="center"><img src="logobig.png" ></div>
\section intro Introduction

97
src/kml/styles.kml 100644
Wyświetl plik

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<Style id="10-meter discus buoy">
<IconStyle><Icon><href></href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="2-meter discus buoy">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/grn-stars.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="2.4-meter discus buoy">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/wht-square.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="2.4-meter foam hull buoy">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/pause.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="2.5-meter ODAS buoy">
<IconStyle><Icon><href>http://google.com/mapfiles/ms/micons/ferry.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="3-meter discus buoy">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/red-stars.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="6-meter NOMAD buoy">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/ltblu-circle.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="automated">
<IconStyle><Icon><href>root://icons/palette-2.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="Buoy">
<IconStyle><Icon><href>http://google.com/mapfiles/ms/micons/marina.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="Canadian NOMAD buoy">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/N.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="Drifting Buoy">
<IconStyle><Icon><href>root://icons/palette-4.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="INMARSAT">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/S.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="METEOSAT">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/M.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="Lightship">
<IconStyle><Icon><href>root://icons/palette-5.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="Oil Platform">
<IconStyle><Icon><href>http://google.com/mapfiles/ms/micons/gas.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="ORBCOMM">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/O.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="OTHER">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/wht-blank.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="other buoy">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/pal3/icon20.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="ship">
<IconStyle><Icon><href>root://icons/palette-8.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="Weather Station">
<IconStyle><Icon><href>http://google.com/mapfiles/ms/micons/partly_cloudy.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="wmo">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/W.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="ARGOS">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/A.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<Style id="IRIDIUM">
<IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/I.png</href></Icon></IconStyle>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
</Document>
</kml>

Wyświetl plik

@ -57,6 +57,7 @@ FIELD fields[] = {
{COUNTRY, "COUNTRY", &btnSelectCountry}, // contacted stations DXCC entity name
{CQZ, "CQZ", &btnSelectCQZ}, // contacted stations CQ Zone
{DXCC, "DXCC", &btnSelectDXCC}, // contacted stations Country Code
{QSL_VIA, "QSL_VIA", &btnSelectQSL_VIA}, // contacted stations path
{IOTA, "IOTA", &btnSelectIOTA}, // Islands on the air
{ITUZ, "ITUZ", &btnSelectITUZ}, // ITU zone
{CONT, "CONT", &btnSelectCONT}, // contacted stations continent

Wyświetl plik

@ -156,6 +156,8 @@ Fl_Check_Button *btnSelectLOC=(Fl_Check_Button *)0;
Fl_Check_Button *btnSelectState=(Fl_Check_Button *)0;
Fl_Check_Button *btnSelectQSL_VIA=(Fl_Check_Button *)0;
Fl_Check_Button *btnSelectProvince=(Fl_Check_Button *)0;
Fl_Check_Button *btnSelectCountry=(Fl_Check_Button *)0;
@ -273,6 +275,8 @@ Fl_Input2 *inpCONT_log=(Fl_Input2 *)0;
Fl_Input2 *inpDXCC_log=(Fl_Input2 *)0;
Fl_Input2 *inpQSL_VIA_log=(Fl_Input2 *)0;
Fl_Input2 *inpSerNoOut_log=(Fl_Input2 *)0;
Fl_Input2 *inpMyXchg_log=(Fl_Input2 *)0;
@ -389,7 +393,7 @@ btnCabRSTrcvd->value(1);
}
void create_logbook_dialogs() {
{ wExport = new Fl_Double_Window(675, 439, _("Export Setup"));
{ wExport = new Fl_Double_Window(675, 435, _("Export Setup"));
{ Fl_Group* o = new Fl_Group(4, 4, 388, 400, _("Select Records to Export"));
o->box(FL_ENGRAVED_FRAME);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
@ -445,10 +449,10 @@ void create_logbook_dialogs() {
{ Fl_Group* o = new Fl_Group(392, 4, 280, 400, _("Select Fields to Export"));
o->box(FL_ENGRAVED_FRAME);
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
{ btnClearAllFields = new Fl_Button(395, 372, 90, 24, _("Clear All"));
{ btnClearAllFields = new Fl_Button(395, 375, 90, 24, _("Clear All"));
btnClearAllFields->callback((Fl_Callback*)cb_btnClearAllFields);
} // Fl_Button* btnClearAllFields
{ btnCheckAllFields = new Fl_Button(487, 372, 90, 24, _("Check All"));
{ btnCheckAllFields = new Fl_Button(487, 375, 90, 24, _("Check All"));
btnCheckAllFields->callback((Fl_Callback*)cb_btnCheckAllFields);
} // Fl_Button* btnCheckAllFields
{ btnSelectCall = new Fl_Check_Button(402, 31, 70, 15, _("Call"));
@ -459,107 +463,110 @@ void create_logbook_dialogs() {
btnSelectName->down_box(FL_DOWN_BOX);
btnSelectName->value(1);
} // Fl_Check_Button* btnSelectName
{ btnSelectFreq = new Fl_Check_Button(402, 74, 70, 15, _("Freq"));
{ btnSelectFreq = new Fl_Check_Button(402, 73, 70, 15, _("Freq"));
btnSelectFreq->down_box(FL_DOWN_BOX);
btnSelectFreq->value(1);
} // Fl_Check_Button* btnSelectFreq
{ btnSelectBand = new Fl_Check_Button(402, 96, 70, 15, _("Band"));
{ btnSelectBand = new Fl_Check_Button(402, 94, 70, 15, _("Band"));
btnSelectBand->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectBand
{ btnSelectMode = new Fl_Check_Button(402, 117, 70, 15, _("Mode"));
{ btnSelectMode = new Fl_Check_Button(402, 115, 70, 15, _("Mode"));
btnSelectMode->down_box(FL_DOWN_BOX);
btnSelectMode->value(1);
} // Fl_Check_Button* btnSelectMode
{ btnSelectQSOdateOn = new Fl_Check_Button(402, 139, 70, 15, _("QSO Date On"));
{ btnSelectQSOdateOn = new Fl_Check_Button(402, 136, 70, 15, _("QSO Date On"));
btnSelectQSOdateOn->down_box(FL_DOWN_BOX);
btnSelectQSOdateOn->value(1);
} // Fl_Check_Button* btnSelectQSOdateOn
{ btnSelectQSOdateOff = new Fl_Check_Button(402, 161, 70, 15, _("QSO Date Off"));
{ btnSelectQSOdateOff = new Fl_Check_Button(402, 157, 70, 15, _("QSO Date Off"));
btnSelectQSOdateOff->down_box(FL_DOWN_BOX);
btnSelectQSOdateOff->value(1);
} // Fl_Check_Button* btnSelectQSOdateOff
{ btnSelectTimeON = new Fl_Check_Button(402, 183, 70, 15, _("Time ON"));
{ btnSelectTimeON = new Fl_Check_Button(402, 178, 70, 15, _("Time ON"));
btnSelectTimeON->down_box(FL_DOWN_BOX);
btnSelectTimeON->value(1);
} // Fl_Check_Button* btnSelectTimeON
{ btnSelectTimeOFF = new Fl_Check_Button(402, 204, 70, 15, _("Time OFF"));
{ btnSelectTimeOFF = new Fl_Check_Button(402, 199, 70, 15, _("Time OFF"));
btnSelectTimeOFF->down_box(FL_DOWN_BOX);
btnSelectTimeOFF->value(1);
} // Fl_Check_Button* btnSelectTimeOFF
{ btnSelectTX_pwr = new Fl_Check_Button(402, 226, 70, 15, _("TX Power"));
{ btnSelectTX_pwr = new Fl_Check_Button(402, 220, 70, 15, _("TX Power"));
btnSelectTX_pwr->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectTX_pwr
{ btnSelectRSTsent = new Fl_Check_Button(402, 248, 70, 15, _("RST sent"));
{ btnSelectRSTsent = new Fl_Check_Button(402, 241, 70, 15, _("RST sent"));
btnSelectRSTsent->down_box(FL_DOWN_BOX);
btnSelectRSTsent->value(1);
} // Fl_Check_Button* btnSelectRSTsent
{ btnSelectRSTrcvd = new Fl_Check_Button(402, 269, 70, 15, _("RST rcvd"));
{ btnSelectRSTrcvd = new Fl_Check_Button(402, 262, 70, 15, _("RST rcvd"));
btnSelectRSTrcvd->down_box(FL_DOWN_BOX);
btnSelectRSTrcvd->value(1);
} // Fl_Check_Button* btnSelectRSTrcvd
{ btnSelectQth = new Fl_Check_Button(402, 291, 70, 15, _("Qth"));
{ btnSelectQth = new Fl_Check_Button(402, 283, 70, 15, _("Qth"));
btnSelectQth->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectQth
{ btnSelectLOC = new Fl_Check_Button(402, 313, 70, 15, _("LOC"));
{ btnSelectLOC = new Fl_Check_Button(402, 304, 70, 15, _("LOC"));
btnSelectLOC->down_box(FL_DOWN_BOX);
btnSelectLOC->value(1);
} // Fl_Check_Button* btnSelectLOC
{ btnSelectState = new Fl_Check_Button(400, 335, 70, 15, _("State"));
{ btnSelectState = new Fl_Check_Button(402, 325, 70, 15, _("State"));
btnSelectState->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectState
{ btnSelectQSL_VIA = new Fl_Check_Button(402, 346, 70, 15, _("QSL-VIA"));
btnSelectQSL_VIA->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectQSL_VIA
{ btnSelectProvince = new Fl_Check_Button(533, 31, 70, 15, _("Province"));
btnSelectProvince->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectProvince
{ btnSelectCountry = new Fl_Check_Button(533, 51, 70, 15, _("Country"));
{ btnSelectCountry = new Fl_Check_Button(533, 52, 70, 15, _("Country"));
btnSelectCountry->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectCountry
{ btnSelectNotes = new Fl_Check_Button(533, 73, 70, 15, _("Notes"));
btnSelectNotes->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectNotes
{ btnSelectQSLrcvd = new Fl_Check_Button(533, 95, 70, 15, _("QSL rcvd date"));
{ btnSelectQSLrcvd = new Fl_Check_Button(533, 94, 70, 15, _("QSL rcvd date"));
btnSelectQSLrcvd->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectQSLrcvd
{ btnSelectQSLsent = new Fl_Check_Button(533, 117, 70, 15, _("QSL sent date"));
{ btnSelectQSLsent = new Fl_Check_Button(533, 115, 70, 15, _("QSL sent date"));
btnSelectQSLsent->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectQSLsent
{ btnSelectSerialIN = new Fl_Check_Button(533, 138, 70, 15, _("Serial # in"));
{ btnSelectSerialIN = new Fl_Check_Button(533, 136, 70, 15, _("Serial # in"));
btnSelectSerialIN->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectSerialIN
{ btnSelectSerialOUT = new Fl_Check_Button(533, 160, 70, 15, _("Serial # out"));
{ btnSelectSerialOUT = new Fl_Check_Button(533, 157, 70, 15, _("Serial # out"));
btnSelectSerialOUT->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectSerialOUT
{ btnSelectXchgIn = new Fl_Check_Button(533, 182, 70, 15, _("Exchange In"));
{ btnSelectXchgIn = new Fl_Check_Button(533, 178, 70, 15, _("Exchange In"));
btnSelectXchgIn->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectXchgIn
{ btnSelectMyXchg = new Fl_Check_Button(533, 204, 70, 15, _("Exchange Out"));
{ btnSelectMyXchg = new Fl_Check_Button(533, 199, 70, 15, _("Exchange Out"));
btnSelectMyXchg->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectMyXchg
{ btnSelectCNTY = new Fl_Check_Button(533, 226, 70, 15, _("County"));
{ btnSelectCNTY = new Fl_Check_Button(533, 220, 70, 15, _("County"));
btnSelectCNTY->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectCNTY
{ btnSelectCONT = new Fl_Check_Button(534, 247, 70, 15, _("Continent"));
{ btnSelectCONT = new Fl_Check_Button(533, 241, 70, 15, _("Continent"));
btnSelectCONT->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectCONT
{ btnSelectCQZ = new Fl_Check_Button(534, 269, 70, 15, _("CQZ"));
{ btnSelectCQZ = new Fl_Check_Button(533, 262, 70, 15, _("CQZ"));
btnSelectCQZ->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectCQZ
{ btnSelectDXCC = new Fl_Check_Button(534, 291, 70, 15, _("DXCC"));
{ btnSelectDXCC = new Fl_Check_Button(533, 283, 70, 15, _("DXCC"));
btnSelectDXCC->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectDXCC
{ btnSelectIOTA = new Fl_Check_Button(534, 313, 70, 15, _("IOTA"));
{ btnSelectIOTA = new Fl_Check_Button(533, 304, 70, 15, _("IOTA"));
btnSelectIOTA->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectIOTA
{ btnSelectITUZ = new Fl_Check_Button(534, 335, 70, 15, _("ITUZ"));
{ btnSelectITUZ = new Fl_Check_Button(533, 325, 70, 15, _("ITUZ"));
btnSelectITUZ->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnSelectITUZ
{ btnSetFieldDefaults = new Fl_Button(578, 372, 90, 24, _("Defaults"));
{ btnSetFieldDefaults = new Fl_Button(578, 375, 90, 24, _("Defaults"));
btnSetFieldDefaults->callback((Fl_Callback*)cb_btnSetFieldDefaults);
} // Fl_Button* btnSetFieldDefaults
o->end();
} // Fl_Group* o
wExport->end();
} // Fl_Double_Window* wExport
{ dlgLogbook = new Fl_Double_Window(590, 514, _("Logbook"));
{ dlgLogbook = new Fl_Double_Window(590, 510, _("Logbook"));
{ inpDate_log = new Fl_DateInput(4, 24, 100, 24, _("Date On"));
inpDate_log->tooltip(_("Date QSO started"));
inpDate_log->box(FL_DOWN_BOX);
@ -829,44 +836,56 @@ void create_logbook_dialogs() {
inpCQZ_log->align(Fl_Align(FL_ALIGN_TOP_LEFT));
inpCQZ_log->when(FL_WHEN_RELEASE);
} // Fl_Input2* inpCQZ_log
{ inpITUZ_log = new Fl_Input2(311, 204, 80, 24, _("ITUZ"));
{ inpITUZ_log = new Fl_Input2(311, 204, 59, 24, _("ITUZ"));
inpITUZ_log->tooltip(_("ITU zone"));
inpITUZ_log->box(FL_DOWN_BOX);
inpITUZ_log->color(FL_BACKGROUND2_COLOR);
inpITUZ_log->selection_color(FL_SELECTION_COLOR);
inpITUZ_log->labeltype(FL_NORMAL_LABEL);
inpITUZ_log->labelfont(0);
inpITUZ_log->labelsize(12);
inpITUZ_log->labelsize(14);
inpITUZ_log->labelcolor(FL_FOREGROUND_COLOR);
inpITUZ_log->align(Fl_Align(FL_ALIGN_TOP_LEFT));
inpITUZ_log->when(FL_WHEN_RELEASE);
} // Fl_Input2* inpITUZ_log
{ inpCONT_log = new Fl_Input2(409, 204, 80, 24, _("CONT"));
{ inpCONT_log = new Fl_Input2(374, 204, 66, 24, _("CONT"));
inpCONT_log->tooltip(_("Continent"));
inpCONT_log->box(FL_DOWN_BOX);
inpCONT_log->color(FL_BACKGROUND2_COLOR);
inpCONT_log->selection_color(FL_SELECTION_COLOR);
inpCONT_log->labeltype(FL_NORMAL_LABEL);
inpCONT_log->labelfont(0);
inpCONT_log->labelsize(12);
inpCONT_log->labelsize(14);
inpCONT_log->labelcolor(FL_FOREGROUND_COLOR);
inpCONT_log->align(Fl_Align(FL_ALIGN_TOP_LEFT));
inpCONT_log->when(FL_WHEN_RELEASE);
} // Fl_Input2* inpCONT_log
{ inpDXCC_log = new Fl_Input2(506, 204, 80, 24, _("DXCC"));
{ inpDXCC_log = new Fl_Input2(445, 204, 70, 24, _("DXCC"));
inpDXCC_log->tooltip(_("DXCC designator"));
inpDXCC_log->box(FL_DOWN_BOX);
inpDXCC_log->color(FL_BACKGROUND2_COLOR);
inpDXCC_log->selection_color(FL_SELECTION_COLOR);
inpDXCC_log->labeltype(FL_NORMAL_LABEL);
inpDXCC_log->labelfont(0);
inpDXCC_log->labelsize(12);
inpDXCC_log->labelsize(14);
inpDXCC_log->labelcolor(FL_FOREGROUND_COLOR);
inpDXCC_log->align(Fl_Align(FL_ALIGN_TOP_LEFT));
inpDXCC_log->when(FL_WHEN_RELEASE);
} // Fl_Input2* inpDXCC_log
{ inpQSL_VIA_log = new Fl_Input2(518, 204, 70, 24, _("QSL-VIA"));
inpQSL_VIA_log->tooltip(_("QSL route of contacted station"));
inpQSL_VIA_log->box(FL_DOWN_BOX);
inpQSL_VIA_log->color(FL_BACKGROUND2_COLOR);
inpQSL_VIA_log->selection_color(FL_SELECTION_COLOR);
inpQSL_VIA_log->labeltype(FL_NORMAL_LABEL);
inpQSL_VIA_log->labelfont(0);
inpQSL_VIA_log->labelsize(14);
inpQSL_VIA_log->labelcolor(FL_FOREGROUND_COLOR);
inpQSL_VIA_log->align(Fl_Align(FL_ALIGN_TOP_LEFT));
inpQSL_VIA_log->when(FL_WHEN_RELEASE);
} // Fl_Input2* inpQSL_VIA_log
{ inpSerNoOut_log = new Fl_Input2(4, 252, 55, 24, _("Ser out"));
inpSerNoOut_log->tooltip(_("Contest seral # sent"));
inpSerNoOut_log->tooltip(_("Contest serial # sent"));
inpSerNoOut_log->box(FL_DOWN_BOX);
inpSerNoOut_log->color(FL_BACKGROUND2_COLOR);
inpSerNoOut_log->selection_color(FL_SELECTION_COLOR);

Wyświetl plik

@ -1,26 +1,30 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0110
version 1.0302
i18n_type 1
i18n_include "gettext.h"
i18n_function _
header_name {.h}
code_name {.cxx}
decl {\#include <config.h>} {}
decl {\#include <config.h>} {private local
}
decl {\#include <FL/Fl_Pixmap.H>} {}
decl {\#include <FL/Fl_Pixmap.H>} {private local
}
decl {\#include "logsupport.h"} {}
decl {\#include "logsupport.h"} {private local
}
decl {\#include "pixmaps.h"} {}
decl {\#include "pixmaps.h"} {private local
}
decl {\#include "flinput2.h"} {public
decl {\#include "flinput2.h"} {public local
}
Function {create_logbook_dialogs()} {open return_type void
} {
Fl_Window wExport {
label {Export Setup}
xywh {517 143 675 439} type Double visible
label {Export Setup} open
xywh {168 180 675 435} type Double hide
} {
Fl_Group {} {
label {Select Records to Export}
@ -110,7 +114,7 @@ btnSelectCQZ->value(0);
btnSelectITUZ->value(0);
btnSelectTX_pwr->value(0);
btnSelectNotes->value(0);}
xywh {395 372 90 24}
xywh {395 375 90 24}
}
Fl_Button btnCheckAllFields {
label {Check All}
@ -144,7 +148,7 @@ btnSelectCQZ->value(1);
btnSelectITUZ->value(1);
btnSelectTX_pwr->value(1);
btnSelectNotes->value(1);}
xywh {487 372 90 24}
xywh {487 375 90 24}
}
Fl_Check_Button btnSelectCall {
label Call
@ -156,55 +160,59 @@ btnSelectNotes->value(1);}
}
Fl_Check_Button btnSelectFreq {
label Freq
xywh {402 74 70 15} down_box DOWN_BOX value 1
xywh {402 73 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectBand {
label Band
xywh {402 96 70 15} down_box DOWN_BOX
xywh {402 94 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectMode {
label Mode
xywh {402 117 70 15} down_box DOWN_BOX value 1
xywh {402 115 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectQSOdateOn {
label {QSO Date On}
xywh {402 139 70 15} down_box DOWN_BOX value 1
xywh {402 136 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectQSOdateOff {
label {QSO Date Off}
xywh {402 161 70 15} down_box DOWN_BOX value 1
xywh {402 157 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectTimeON {
label {Time ON}
xywh {402 183 70 15} down_box DOWN_BOX value 1
xywh {402 178 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectTimeOFF {
label {Time OFF}
xywh {402 204 70 15} down_box DOWN_BOX value 1
xywh {402 199 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectTX_pwr {
label {TX Power}
xywh {402 226 70 15} down_box DOWN_BOX
xywh {402 220 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectRSTsent {
label {RST sent}
xywh {402 248 70 15} down_box DOWN_BOX value 1
xywh {402 241 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectRSTrcvd {
label {RST rcvd}
xywh {402 269 70 15} down_box DOWN_BOX value 1
xywh {402 262 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectQth {
label Qth
xywh {402 291 70 15} down_box DOWN_BOX
xywh {402 283 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectLOC {
label LOC
xywh {402 313 70 15} down_box DOWN_BOX value 1
xywh {402 304 70 15} down_box DOWN_BOX value 1
}
Fl_Check_Button btnSelectState {
label State
xywh {400 335 70 15} down_box DOWN_BOX
xywh {402 325 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectQSL_VIA {
label {QSL-VIA}
xywh {402 346 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectProvince {
label Province
@ -212,7 +220,7 @@ btnSelectNotes->value(1);}
}
Fl_Check_Button btnSelectCountry {
label Country
xywh {533 51 70 15} down_box DOWN_BOX
xywh {533 52 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectNotes {
label Notes
@ -220,51 +228,51 @@ btnSelectNotes->value(1);}
}
Fl_Check_Button btnSelectQSLrcvd {
label {QSL rcvd date}
xywh {533 95 70 15} down_box DOWN_BOX
xywh {533 94 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectQSLsent {
label {QSL sent date}
xywh {533 117 70 15} down_box DOWN_BOX
xywh {533 115 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectSerialIN {
label {Serial \# in}
xywh {533 138 70 15} down_box DOWN_BOX
xywh {533 136 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectSerialOUT {
label {Serial \# out}
xywh {533 160 70 15} down_box DOWN_BOX
xywh {533 157 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectXchgIn {
label {Exchange In}
xywh {533 182 70 15} down_box DOWN_BOX
xywh {533 178 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectMyXchg {
label {Exchange Out}
xywh {533 204 70 15} down_box DOWN_BOX
xywh {533 199 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectCNTY {
label County
xywh {533 226 70 15} down_box DOWN_BOX
xywh {533 220 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectCONT {
label Continent
xywh {534 247 70 15} down_box DOWN_BOX
xywh {533 241 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectCQZ {
label CQZ
xywh {534 269 70 15} down_box DOWN_BOX
xywh {533 262 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectDXCC {
label DXCC
xywh {534 291 70 15} down_box DOWN_BOX
xywh {533 283 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectIOTA {
label IOTA
xywh {534 313 70 15} down_box DOWN_BOX
xywh {533 304 70 15} down_box DOWN_BOX
}
Fl_Check_Button btnSelectITUZ {
label ITUZ
xywh {534 335 70 15} down_box DOWN_BOX
xywh {533 325 70 15} down_box DOWN_BOX
}
Fl_Button btnSetFieldDefaults {
label Defaults
@ -298,16 +306,16 @@ btnSelectCQZ->value(0);
btnSelectITUZ->value(0);
btnSelectTX_pwr->value(0);
btnSelectNotes->value(0);}
xywh {578 372 90 24}
xywh {578 375 90 24}
}
}
}
Fl_Window dlgLogbook {
label Logbook open
xywh {603 71 590 514} type Double resizable visible
xywh {522 70 590 510} type Double resizable visible
} {
Fl_Input inpDate_log {
label {Date On} selected
label {Date On}
tooltip {Date QSO started} xywh {4 24 100 24} align 5
code0 {\#include "calendar.h"}
code1 {inpDate_log->format(2);}
@ -424,22 +432,27 @@ btnSelectNotes->value(0);}
}
Fl_Input inpITUZ_log {
label ITUZ
tooltip {ITU zone} xywh {311 204 80 24} labelsize 12 align 5
tooltip {ITU zone} xywh {311 204 59 24} align 5
class Fl_Input2
}
Fl_Input inpCONT_log {
label CONT
tooltip Continent xywh {409 204 80 24} labelsize 12 align 5
tooltip Continent xywh {374 204 66 24} align 5
class Fl_Input2
}
Fl_Input inpDXCC_log {
label DXCC
tooltip {DXCC designator} xywh {506 204 80 24} labelsize 12 align 5
tooltip {DXCC designator} xywh {445 204 70 24} align 5
class Fl_Input2
}
Fl_Input inpQSL_VIA_log {
label {QSL-VIA}
tooltip {QSL route of contacted station} xywh {518 204 70 24} align 5
class Fl_Input2
}
Fl_Input inpSerNoOut_log {
label {Ser out}
tooltip {Contest seral \# sent} xywh {4 252 55 24} align 1
tooltip {Contest serial \# sent} xywh {4 252 55 24} align 1
class Fl_Input2
}
Fl_Input inpMyXchg_log {
@ -497,7 +510,7 @@ btnSelectNotes->value(0);}
tooltip {Find next} xywh {547 284 24 22} color 50 selection_color 48 align 16
code0 {bSearchNext->image(new Fl_Pixmap(right_arrow_icon));}
}
Fl_Group wBrowser {open
Fl_Group wBrowser {open selected
xywh {2 315 586 195} box DOWN_FRAME color 7 selection_color 15 resizable
code0 {\#include "table.h"}
class Table

Wyświetl plik

@ -496,7 +496,7 @@ void cb_mnuMergeADIF_log(Fl_Menu_* m, void* d) {
const char* p = FSEL::select(_("Merge ADIF file"), "ADIF\t*." ADIF_SUFFIX);
Fl::wait();
fl_digi_main->redraw();
Fl::flush();
Fl::awake();
if (p) {
cQsoDb *mrgdb = new cQsoDb;
adifFile.do_readfile (p, mrgdb);
@ -911,6 +911,7 @@ void clearRecord() {
inpNotes_log->value ("");
inpIOTA_log->value("");
inpDXCC_log->value("");
inpQSL_VIA_log->value("");
inpCONT_log->value("");
inpCNTY_log->value("");
inpCQZ_log->value("");
@ -964,6 +965,7 @@ void saveRecord() {
rec.putField(CNTY, inpCNTY_log->value());
rec.putField(IOTA, inpIOTA_log->value());
rec.putField(DXCC, inpDXCC_log->value());
rec.putField(DXCC, inpQSL_VIA_log->value());
rec.putField(CONT, inpCONT_log->value());
rec.putField(CQZ, inpCQZ_log->value());
rec.putField(ITUZ, inpITUZ_log->value());
@ -1018,6 +1020,7 @@ cQsoRec rec;
rec.putField(CNTY, inpCNTY_log->value());
rec.putField(IOTA, inpIOTA_log->value());
rec.putField(DXCC, inpDXCC_log->value());
rec.putField(QSL_VIA, inpQSL_VIA_log->value());
rec.putField(CONT, inpCONT_log->value());
rec.putField(CQZ, inpCQZ_log->value());
rec.putField(ITUZ, inpITUZ_log->value());
@ -1089,6 +1092,7 @@ void EditRecord( int i )
inpCNTY_log->value(editQSO->getField(CNTY));
inpIOTA_log->value(editQSO->getField(IOTA));
inpDXCC_log->value(editQSO->getField(DXCC));
inpQSL_VIA_log->value(editQSO->getField(QSL_VIA));
inpCONT_log->value(editQSO->getField(CONT));
inpCQZ_log->value(editQSO->getField(CQZ));
inpITUZ_log->value(editQSO->getField(ITUZ));
@ -1142,6 +1146,7 @@ void AddRecord ()
inpCNTY_log->value("");
inpIOTA_log->value("");
inpDXCC_log->value("");
inpQSL_VIA_log->value("");
inpCONT_log->value("");
inpCQZ_log->value("");
inpITUZ_log->value("");

Wyświetl plik

@ -1368,3 +1368,45 @@ void makeEQSL(const char *message)
}
/// With this constructor, no need to declare the array mode_info[] in the calling program.
QsoHelper::QsoHelper(int the_mode)
: qso_rec( new cQsoRec )
{
qso_rec->putField(MODE, mode_info[the_mode].adif_name );
}
/// This saves the new record to a file and must be run in the main thread.
static void QsoHelperSave(cQsoRec * qso_rec_ptr)
{
qsodb.qsoNewRec (qso_rec_ptr);
qsodb.isdirty(0);
qsodb.isdirty(0);
loadBrowser(true);
/// It is mandatory to do this in the main thread. TODO: Crash suspected.
adifFile.writeLog (logbook_filename.c_str(), &qsodb);
/// Beware that this object is created in a thread and deleted in the main one.
delete qso_rec_ptr ;
}
/// This must be called from the main thread, according to writeLog().
QsoHelper::~QsoHelper()
{
qso_rec->setDateTime(true);
qso_rec->setDateTime(false);
qso_rec->setFrequency( wf->rfcarrier() );
REQ( QsoHelperSave, qso_rec );
// It will be deleted in the main thread.
qso_rec = NULL ;
}
/// Adds one key-value pair to display in the ADIF file.
void QsoHelper::Push( ADIF_FIELD_POS pos, const std::string & value )
{
qso_rec->putField( pos, value.c_str() );
}

Wyświetl plik

@ -37,6 +37,7 @@
#include "qso_db.h"
#include "field_def.h"
#include "globals.h"
#include "timeops.h"
// following needed for localtime_r
#include <pthread.h>

Wyświetl plik

@ -191,6 +191,7 @@ void xml_add_record()
// need to add the remaining fields
adif_str(IOTA, "");
adif_str(DXCC, "");
adif_str(QSL_VIA, "");
adif_str(QSLRDATE, "");
adif_str(QSLSDATE, "");
adif.append("<eor>");

Wyświetl plik

@ -124,6 +124,7 @@ void submit_ADIF(cQsoRec &rec)
// QSO log area.
putadif(IOTA, rec.getField(IOTA));
putadif(DXCC, rec.getField(DXCC));
putadif(QSL_VIA, rec.getField(QSL_VIA));
putadif(QSLRDATE, rec.getField(QSLRDATE));
putadif(QSLSDATE, rec.getField(QSLSDATE));

Wyświetl plik

@ -39,6 +39,7 @@
#include "debug.h"
#include "icons.h"
#include "qrunner.h"
#include "timeops.h"
using namespace std;

Wyświetl plik

@ -95,6 +95,7 @@
#include "dxcc.h"
#include "newinstall.h"
#include "Viewer.h"
#include "kmlserver.h"
#if USE_HAMLIB
#include "rigclass.h"
@ -106,9 +107,7 @@
#include "qrunner.h"
#include "stacktrace.h"
#if USE_XMLRPC
#include "xmlrpc.h"
#endif
#include "xmlrpc.h"
#if BENCHMARK_MODE
#include "benchmark.h"
@ -137,9 +136,11 @@ string MacrosDir = "";
string WrapDir = "";
string TalkDir = "";
string TempDir = "";
string KmlDir = "";
string PskMailDir = "";
string NBEMS_dir = "";
string DATA_dir = "";
string ARQ_dir = "";
string ARQ_files_dir = "";
string ARQ_recv_dir = "";
@ -180,12 +181,6 @@ bool mailserver = false, mailclient = false, arqmode = false;
static bool show_cpucheck = false;
static bool iconified = false;
RXMSGSTRUC rxmsgst;
int rxmsgid = -1;
TXMSGSTRUC txmsgst;
int txmsgid = -1;
string option_help, version_text, build_text;
qrunner *cbq[NUM_QRUNNER_THREADS];
@ -224,9 +219,7 @@ void delayed_startup(void *)
grpTalker->hide();
#endif
#if USE_XMLRPC
XML_RPC_Server::start(progdefaults.xmlrpc_address.c_str(), progdefaults.xmlrpc_port.c_str());
#endif
notify_start();
@ -312,11 +305,13 @@ int main(int argc, char ** argv)
#ifdef __WOE32__
if (HomeDir.empty()) HomeDir.assign(BaseDir).append("dl-fldigi.files/");
if (PskMailDir.empty()) PskMailDir = BaseDir;
if (DATA_dir.empty()) DATA_dir.assign(BaseDir).append("DATA.files/");
if (NBEMS_dir.empty()) NBEMS_dir.assign(BaseDir).append("NBEMS.files/");
if (FLMSG_dir.empty()) FLMSG_dir_default = NBEMS_dir;
#else
if (HomeDir.empty()) HomeDir.assign(BaseDir).append(".dl-fldigi/");
if (PskMailDir.empty()) PskMailDir = BaseDir;
if (DATA_dir.empty()) DATA_dir.assign(HomeDir).append("data/");
if (NBEMS_dir.empty()) NBEMS_dir.assign(BaseDir).append(".nbems/");
if (FLMSG_dir.empty()) FLMSG_dir_default = NBEMS_dir;
#endif
@ -356,7 +351,6 @@ int main(int argc, char ** argv)
}
LOG_INFO("appname: %s", appname.c_str());
LOG_INFO("Test file %p", test_file);
if (NBEMSapps_dir)
LOG_INFO("%s present", test_file_name.c_str());
else
@ -372,8 +366,10 @@ int main(int argc, char ** argv)
LOG_INFO("WrapDir: %s", WrapDir.c_str());
LOG_INFO("TalkDir: %s", TalkDir.c_str());
LOG_INFO("TempDir: %s", TempDir.c_str());
LOG_INFO("KmlDir: %s", KmlDir.c_str());
LOG_INFO("PskMailDir: %s", PskMailDir.c_str());
LOG_INFO("DATA_dir: %s", DATA_dir.c_str());
LOG_INFO("NBEMS_dir: %s", NBEMS_dir.c_str());
LOG_INFO("ARQ_dir: %s", ARQ_dir.c_str());
LOG_INFO("ARQ_files_dir: %s", ARQ_files_dir.c_str());
@ -402,15 +398,8 @@ int main(int argc, char ** argv)
xmlfname = HomeDir;
xmlfname.append("rig.xml");
#if !defined(__WOE32__) && !defined(__APPLE__)
txmsgid = msgget( (key_t) progdefaults.tx_msgid, 0666 );
#else
txmsgid = -1;
#endif
checkTLF();
Fl::lock(); // start the gui thread!!
Fl::visual(FL_RGB); // insure 24 bit color operation
@ -504,6 +493,11 @@ int main(int argc, char ** argv)
create_logbook_dialogs();
LOGBOOK_colors_font();
if( progdefaults.kml_save_dir.empty() ) {
progdefaults.kml_save_dir = KmlDir ;
}
kml_init(true);
// OS X will prevent the main window from being resized if we change its
// size *after* it has been shown. With some X11 window managers, OTOH,
// the main window will not be restored at its exact saved position if
@ -534,11 +528,14 @@ int main(int argc, char ** argv)
int ret = Fl::run();
arq_close();
return ret;
}
#if USE_XMLRPC
void exit_process() {
KmlServer::Exit();
arq_close();
XML_RPC_Server::stop();
#endif
if (progdefaults.usepskrep)
pskrep_stop();
@ -550,7 +547,6 @@ int main(int argc, char ** argv)
FSEL::destroy();
return ret;
}
void generate_option_help(void) {
@ -617,7 +613,6 @@ void generate_option_help(void) {
<< " Look for wrap_auto_file files in DIRECTORY\n"
<< " The default is " << FLMSG_dir_default << "WRAP/auto/" << "\n\n"
#if USE_XMLRPC
<< " --xmlrpc-server-address HOSTNAME\n"
<< " Set the XML-RPC server address\n"
<< " The default is: " << progdefaults.xmlrpc_address << "\n\n"
@ -630,7 +625,6 @@ void generate_option_help(void) {
<< " Allow only the methods whose names don't match REGEX\n\n"
<< " --xmlrpc-list\n"
<< " List all available methods\n\n"
#endif
#if BENCHMARK_MODE
<< " --benchmark-modem ID\n"
@ -693,6 +687,12 @@ void generate_option_help(void) {
<< " --debug-level LEVEL\n"
<< " Set the event log verbosity\n\n"
<< " --debug-pskmail\n"
<< " Enable logging for pskmail / arq events\n\n"
<< " --debug-audio\n"
<< " Enable logging for sound-card events\n\n"
<< " --version\n"
<< " Print version information\n\n"
@ -778,10 +778,8 @@ int parse_args(int argc, char **argv, int& idx)
OPT_FLMSG_DIR,
OPT_AUTOSEND_DIR,
#if USE_XMLRPC
OPT_CONFIG_XMLRPC_ADDRESS, OPT_CONFIG_XMLRPC_PORT,
OPT_CONFIG_XMLRPC_ALLOW, OPT_CONFIG_XMLRPC_DENY, OPT_CONFIG_XMLRPC_LIST,
#endif
#if BENCHMARK_MODE
OPT_BENCHMARK_MODEM, OPT_BENCHMARK_AFC, OPT_BENCHMARK_SQL, OPT_BENCHMARK_SQLEVEL,
@ -795,12 +793,12 @@ int parse_args(int argc, char **argv, int& idx)
#if USE_PORTAUDIO
OPT_FRAMES_PER_BUFFER,
#endif
OPT_NOISE, OPT_DEBUG_LEVEL,
OPT_NOISE, OPT_DEBUG_LEVEL, OPT_DEBUG_PSKMAIL, OPT_DEBUG_AUDIO,
OPT_EXIT_AFTER,
OPT_DEPRECATED, OPT_HELP, OPT_VERSION, OPT_BUILD_INFO };
const char shortopts[] = ":";
static struct option longopts[] = {
static const char shortopts[] = ":";
static const struct option longopts[] = {
#ifndef __WOE32__
{ "rx-ipc-key", 1, 0, OPT_RX_IPC_KEY },
{ "tx-ipc-key", 1, 0, OPT_TX_IPC_KEY },
@ -815,13 +813,11 @@ int parse_args(int argc, char **argv, int& idx)
{ "cpu-speed-test", 0, 0, OPT_SHOW_CPU_CHECK },
#if USE_XMLRPC
{ "xmlrpc-server-address", 1, 0, OPT_CONFIG_XMLRPC_ADDRESS },
{ "xmlrpc-server-port", 1, 0, OPT_CONFIG_XMLRPC_PORT },
{ "xmlrpc-allow", 1, 0, OPT_CONFIG_XMLRPC_ALLOW },
{ "xmlrpc-deny", 1, 0, OPT_CONFIG_XMLRPC_DENY },
{ "xmlrpc-list", 0, 0, OPT_CONFIG_XMLRPC_LIST },
#endif
#if BENCHMARK_MODE
{ "benchmark-modem", 1, 0, OPT_BENCHMARK_MODEM },
@ -851,6 +847,8 @@ int parse_args(int argc, char **argv, int& idx)
{ "noise", 0, 0, OPT_NOISE },
{ "debug-level", 1, 0, OPT_DEBUG_LEVEL },
{ "debug-pskmail", 0, 0, OPT_DEBUG_PSKMAIL },
{ "debug-audio", 0, 0, OPT_DEBUG_AUDIO },
{ "help", 0, 0, OPT_HELP },
{ "version", 0, 0, OPT_VERSION },
@ -930,7 +928,6 @@ int parse_args(int argc, char **argv, int& idx)
}
break;
#if USE_XMLRPC
case OPT_CONFIG_XMLRPC_ADDRESS:
progdefaults.xmlrpc_address = optarg;
break;
@ -952,7 +949,6 @@ int parse_args(int argc, char **argv, int& idx)
case OPT_CONFIG_XMLRPC_LIST:
XML_RPC_Server::list_methods(cout);
exit(EXIT_SUCCESS);
#endif
#if BENCHMARK_MODE
case OPT_BENCHMARK_MODEM:
@ -1057,6 +1053,14 @@ int parse_args(int argc, char **argv, int& idx)
}
break;
case OPT_DEBUG_PSKMAIL:
debug_pskmail = true;
break;
case OPT_DEBUG_AUDIO:
debug_audio = true;
break;
case OPT_DEPRECATED:
cerr << "W: the --" << longopts[longindex].name
<< " option has been deprecated and will be removed in a future version\n";
@ -1124,9 +1128,6 @@ void generate_version_text(void)
#if USE_HAMLIB
s << " " "Hamlib " << HAMLIB_BUILD_VERSION "\n";
#endif
#if USE_XMLRPC
s << " " "XMLRPC-C " << XMLRPC_BUILD_VERSION "\n\n";
#endif
s << "\nRuntime information:\n";
struct utsname u;
@ -1298,6 +1299,7 @@ static void checkdirectories(void)
{ WrapDir, "wrap", 0 },
{ TalkDir, "talk", 0 },
{ TempDir, "temp", 0 },
{ KmlDir, "kml", 0 },
};
int r;
@ -1419,3 +1421,57 @@ static void arg_error(const char* name, const char* arg, bool missing)
exit(EXIT_FAILURE);
}
/// Sets or resets the KML parameters, and loads existing files.
void kml_init(bool load_files)
{
KmlServer::GetInstance()->InitParams(
progdefaults.kml_command,
progdefaults.kml_save_dir,
(double)progdefaults.kml_merge_distance,
progdefaults.kml_retention_time,
progdefaults.kml_refresh_interval,
progdefaults.kml_balloon_style);
if(load_files) {
KmlServer::GetInstance()->ReloadKmlFiles();
}
/// TODO: Should do this only when the locator has changed.
try {
/// One special KML object for the user.
CoordinateT::Pair myCoo( progdefaults.myLocator );
/// TODO: Fix this: It does not seem to create a polyline when changing the locator.
KmlServer::CustomDataT custData ;
custData.Push( "QTH", progdefaults.myQth );
custData.Push( "Locator", progdefaults.myLocator );
custData.Push( "Antenna", progdefaults.myAntenna );
custData.Push( "Name", progdefaults.myName );
KmlServer::GetInstance()->Broadcast(
"User",
KmlServer::UniqueEvent,
myCoo,
0.0, // Altitude.
progdefaults.myCall,
progdefaults.myLocator,
progdefaults.myQth,
custData );
}
catch( const std::exception & exc ) {
LOG_WARN("Cannot publish user position:%s", exc.what() );
}
}
/// Tests if a directory exists.
int directory_is_created( const char * strdir )
{
DIR *dir = opendir(strdir);
if (dir) {
closedir(dir);
return true;
}
return false;
}

Wyświetl plik

@ -106,6 +106,8 @@ void mfsk::shutdown()
mfsk::~mfsk()
{
stopflag = true;
int msecs = 200;
while(--msecs && txstate != TX_STATE_PREAMBLE) MilliSleep(1);
if (picTxWin)
picTxWin->hide();
if (picRxWin)
@ -710,7 +712,7 @@ void mfsk::eval_s2n()
int mfsk::rx_process(const double *buf, int len)
{
complex z;
complex* bins;
complex* bins = 0;
while (len-- > 0) {
// create analytic signal...

Wyświetl plik

@ -3,12 +3,14 @@
//
// support for ARQ server/client system such as pskmail and fl_arq
//
// Copyright (C) 2006-2010
// Copyright (C) 2006-2013
// Dave Freese, W1HKJ
// Copyright (C) 2008-2010
// Copyright (C) 2008-2013
// Stelios Bounanos, M0GLD
// Copyright (C) 2009-2010
// Copyright (C) 2009-2013
// John Douyere, VK2ETA
// Copyright (c) 2013
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
@ -66,9 +68,7 @@ LOG_FILE_SOURCE(debug::LOG_ARQCONTROL);
using namespace std;
// ============================================================================
// Implementation using thread vice the fldigi timeout facility
// ============================================================================
// =====================================================================
static pthread_t arq_thread;
static pthread_mutex_t arq_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t arq_rx_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -78,17 +78,27 @@ static void *arq_loop(void *args);
static bool arq_exit = false;
static bool arq_enabled;
static bool abort_flag = false;
static string tosend = "";
static string enroute = "";
//======================================================================
// test code for pskmail eol issues
/// Any access to shared variables must be protected.
static string tosend = ""; // Protected by tosend_mutex
static string enroute = ""; // Protected by tosend_mutex
static string arqtext = ""; // Protected by arq_rx_mutex
static string txstring = ""; // Protected by arq_rx_mutex
static size_t pText; // Protected by arq_rx_mutex
bool arq_text_available = false; // Protected by arq_rx_mutex
// Beware 'arq_text_available' is accessed by other modules.
static bool bSend0x06 = false; // Protected by arq_rx_mutex
// =====================================================================
static const char *asc[128] = {
"<NUL>", "<SOH>", "<STX>", "<ETX>",
"<EOT>", "<ENQ>", "<ACK>", "<BEL>",
"<BS>", "<TAB>", "<LF>", "<VT>",
"<FF>", "<CR>", "<SO>", "<SI>",
"<BS>", "<TAB>", "\n", "<VT>",
"<FF>", "", "<SO>", "<SI>",
"<DLE>", "<DC1>", "<DC2>", "<DC3>",
"<DC4>", "<NAK>", "<SYN>", "<ETB>",
"<CAN>", "<EM>", "<SUB>", "<ESC>",
@ -123,18 +133,22 @@ string noctrl(string src)
{
static string retstr;
retstr.clear();
for (size_t i = 0; i < src.length(); i++) retstr.append(asc[(int)src[i] & 0x7F]);
char hexstr[10];
int c;
for (size_t i = 0; i < src.length(); i++) {
c = src[i];
if ( c > 0 && c < 128)
retstr.append(asc[c]);
else {
snprintf(hexstr, sizeof(hexstr), "<%0X>", c & 0xFF);
retstr.append(hexstr);
}
}
return retstr;
}
//======================================================================
static string arqtext;
size_t pText;
bool arq_text_available = false;
string txstring;
extern void parse_arqtext(string &toparse);
static void set_button(Fl_Button* button, bool value)
@ -151,10 +165,12 @@ void ParseMode(string src)
int ret = sscanf( src.substr(7, src.length() - 7).c_str(), "%d", &msecs);
if (ret != 1 || msecs < 10 || msecs > 20000) msecs = 100;
}
LOG_INFO("%s %5.2f sec", "ARQ tune on", msecs/1000.0);
if (debug_pskmail)
LOG_INFO("%s %5.2f sec", "ARQ tune on", msecs/1000.0);
trx_tune();
MilliSleep(msecs);
LOG_INFO("%s", "ARQ tune off");
if (debug_pskmail)
LOG_INFO("%s", "ARQ tune off");
trx_receive();
return;
}
@ -164,11 +180,13 @@ LOG_INFO("%s", "ARQ tune off");
int ret = sscanf( src.substr(7, src.length() - 7).c_str(), "%d", &msecs);
if (ret != 1 || msecs < 10 || msecs > 20000) msecs = 100;
}
LOG_INFO("%s %5.2f sec", "ARQ set ptt on", msecs/1000.0);
if (debug_pskmail)
LOG_INFO("%s %5.2f sec", "ARQ set ptt on", msecs/1000.0);
push2talk->set(true);
REQ(&waterfall::set_XmtRcvBtn, wf, true);
MilliSleep(msecs);
LOG_INFO("%s", "ARQ set ptt off");
if (debug_pskmail)
LOG_INFO("%s", "ARQ set ptt off");
push2talk->set(false);
REQ(&waterfall::set_XmtRcvBtn, wf, false);
return;
@ -176,10 +194,11 @@ LOG_INFO("%s", "ARQ set ptt off");
for (size_t i = 0; i < NUM_MODES; ++i) {
if (strlen(mode_info[i].pskmail_name) > 0) {
if (src == mode_info[i].pskmail_name) {
while (trx_state != STATE_RX) {
MilliSleep(10);
}
LOG_INFO("Setting modem to %s", mode_info[i].pskmail_name);
// while (trx_state != STATE_RX) {
// MilliSleep(10);
// }
if (debug_pskmail)
LOG_INFO("Setting modem to %s", mode_info[i].pskmail_name);
REQ_SYNC(init_modem_sync, mode_info[i].mode, 0);
break;
}
@ -190,11 +209,13 @@ LOG_INFO("Setting modem to %s", mode_info[i].pskmail_name);
void ParseRSID(string src)
{
if (src == "ON") {
LOG_VERBOSE("%s", "RsID turned ON");
if (debug_pskmail)
LOG_INFO("%s", "RsID turned ON");
REQ(set_button, btnRSID, 1);
}
if (src == "OFF") {
LOG_VERBOSE("%s", "RsID turned OFF");
if (debug_pskmail)
LOG_INFO("%s", "RsID turned OFF");
REQ(set_button, btnRSID, 0);
}
}
@ -203,11 +224,13 @@ void ParseRSID(string src)
void ParseTxRSID(string src)
{
if (src == "ON") {
LOG_VERBOSE("%s", "TxRsID turned ON");
if (debug_pskmail)
LOG_INFO("%s", "TxRsID turned ON");
REQ(set_button, btnTxRSID, 1);
}
if (src == "OFF") {
LOG_VERBOSE("%s", "TxRsID turned OFF");
if (debug_pskmail)
LOG_INFO("%s", "TxRsID turned OFF");
REQ(set_button, btnTxRSID, 0);
}
}
@ -218,14 +241,16 @@ static string strCmdText;
static string strSubCmd;
unsigned long int idxCmd, idxCmdEnd, idxSubCmd, idxSubCmdEnd;
LOG_DEBUG("Arq text: %s", noctrl(toparse).c_str());
if (toparse.empty()) return;
idxCmd = toparse.find("<cmd>");
idxCmdEnd = toparse.find("</cmd>");
if (idxCmd != string::npos && debug_pskmail)
LOG_INFO("Parsing: %s", noctrl(toparse).c_str());
while ( idxCmd != string::npos && idxCmdEnd != string::npos && idxCmdEnd > idxCmd ) {
LOG_DEBUG("Cmd text: %s", toparse.substr(idxCmd, idxCmdEnd + 6).c_str());
strCmdText = toparse.substr(idxCmd + 5, idxCmdEnd - idxCmd - 5);
if (strCmdText == "server" && mailserver == false && mailclient == false) {
mailserver = true;
@ -239,7 +264,7 @@ static string strSubCmd;
if (progdefaults.PSKmailSweetSpot)
active_modem->set_freq(progdefaults.PSKsweetspot);
active_modem->set_freqlock(true);
LOG_VERBOSE("%s", "ARQ is set to pskmail server");
LOG_INFO("%s", "ARQ is set to pskmail server");
} else if (strCmdText == "client" && mailclient == false && mailserver == false) {
mailclient = true;
mailserver = false;
@ -250,7 +275,7 @@ static string strSubCmd;
Maillogfile->log_to_file_start();
REQ(set_button, wf->xmtlock, 0);
active_modem->set_freqlock(false);
LOG_VERBOSE("%s", "ARQ is set to pskmail client");
LOG_INFO("%s", "ARQ is set to pskmail client");
} else if (strCmdText == "normal") {
mailserver = false;
mailclient = false;
@ -260,14 +285,14 @@ static string strSubCmd;
}
REQ(set_button, wf->xmtlock, 0);
active_modem->set_freqlock(false);
LOG_VERBOSE("%s", "ARQ is reset to normal ops");
LOG_INFO("%s", "ARQ is reset to normal ops");
} else if ((idxSubCmd = strCmdText.find("<mode>")) != string::npos) {
idxSubCmdEnd = strCmdText.find("</mode>");
if ( idxSubCmdEnd != string::npos &&
idxSubCmdEnd > idxSubCmd ) {
strSubCmd = strCmdText.substr(idxSubCmd + 6, idxSubCmdEnd - idxSubCmd - 6);
ParseMode(strSubCmd);
LOG_VERBOSE("%s %s", "ARQ mode ", strSubCmd.c_str());
LOG_INFO("%s %s", "ARQ mode ", strSubCmd.c_str());
}
} else if ((idxSubCmd = strCmdText.find("<rsid>")) != string::npos) {
idxSubCmdEnd = strCmdText.find("</rsid>");
@ -275,7 +300,7 @@ static string strSubCmd;
idxSubCmdEnd > idxSubCmd ) {
strSubCmd = strCmdText.substr(idxSubCmd + 6, idxSubCmdEnd - idxSubCmd - 6);
ParseRSID(strSubCmd);
LOG_VERBOSE("%s %s", "ARQ rsid ", strSubCmd.c_str());
LOG_INFO("%s %s", "ARQ rsid ", strSubCmd.c_str());
}
} else if ((idxSubCmd = strCmdText.find("<txrsid>")) != string::npos) {
idxSubCmdEnd = strCmdText.find("</txrsid>");
@ -283,8 +308,11 @@ static string strSubCmd;
idxSubCmdEnd > idxSubCmd ) {
strSubCmd = strCmdText.substr(idxSubCmd + 8, idxSubCmdEnd - idxSubCmd - 8);
ParseTxRSID(strSubCmd);
LOG_VERBOSE("%s %s", "ARQ txrsid ", strSubCmd.c_str());
LOG_INFO("%s %s", "ARQ txrsid ", strSubCmd.c_str());
}
} else if (strCmdText == "abort") {
LOG_INFO("%s", "Abort current ARQ ops");
abort_flag = true;
}
toparse.erase(idxCmd, idxCmdEnd - idxCmd + 6);
@ -297,49 +325,9 @@ static string strSubCmd;
#define TIMEOUT 180 // 3 minutes
bool bSend0x06 = false;
//-----------------------------------------------------------------------------
// SysV ARQ used only on Linux / Free-BSD or Unix type OS
//-----------------------------------------------------------------------------
#if !defined(__WOE32__) && !defined(__APPLE__)
void process_msgque()
{
memset(txmsgst.buffer, 0, ARQBUFSIZ);
int nbytes = msgrcv (txmsgid, (void *)&txmsgst, ARQBUFSIZ, 0, IPC_NOWAIT);
if (nbytes > 0) {
txstring.append(txmsgst.buffer);
parse_arqtext(txstring);
if (!bSend0x06 && arqtext.empty() && !txstring.empty()) {
arqtext = txstring;
if (mailserver && progdefaults.PSKmailSweetSpot)
active_modem->set_freq(progdefaults.PSKsweetspot);
pText = 0;
arq_text_available = true;
active_modem->set_stopflag(false);
LOG_DEBUG("SYSV ARQ string: %s", arqtext.c_str());
start_tx();
txstring.clear();
}
}
}
bool SysV_arqRx()
{
txmsgid = msgget( (key_t) progdefaults.tx_msgid, 0666 );
if (txmsgid != -1) {
process_msgque();
return true;
}
return false;
}
#endif
//-----------------------------------------------------------------------------
//======================================================================
// Gmfsk ARQ file i/o used only on Linux
//-----------------------------------------------------------------------------
//======================================================================
// checkTLF
// look for files named
// TLFfldigi ==> tlfio is true and
@ -368,17 +356,21 @@ static string TLFlogname;
}
}
bool TLF_arqRx()
static bool TLF_arqRx()
{
/// The mutex is automatically unlocked when returning.
guard_lock arq_rx_lock(&arq_rx_mutex);
#if defined(__WOE32__) || defined(__APPLE__)
return false;
#else
time_t start_time, prog_time;
static char mailline[1000];
static string sAutoFile;
static string sAutoFile("");
sAutoFile.assign(PskMailDir);
sAutoFile.append("gmfsk_autofile");
ifstream autofile(sAutoFile.c_str());
if(autofile) {
arqtext = "";
time(&start_time);
while (!autofile.eof()) {
memset(mailline, 0, sizeof(mailline));
@ -397,6 +389,13 @@ bool TLF_arqRx()
std::remove (sAutoFile.c_str());
parse_arqtext(txstring);
if (abort_flag) {
AbortARQ();
abort_flag = false;
return true;
}
if (arqtext.empty() && !txstring.empty()) {
arqtext = txstring;
if (mailserver && progdefaults.PSKmailSweetSpot)
@ -404,23 +403,22 @@ bool TLF_arqRx()
pText = 0;
arq_text_available = true;
active_modem->set_stopflag(false);
LOG_INFO("%s", arqtext.c_str());
start_tx();
txstring.clear();
}
}
return true;
#endif
}
//-----------------------------------------------------------------------------
//======================================================================
// Auto transmit of file contained in WRAP_auto_dir
//-----------------------------------------------------------------------------
//======================================================================
bool WRAP_auto_arqRx()
{
time_t start_time, prog_time;
static char mailline[1000];
static string sAutoFile;
static string sAutoFile("");
sAutoFile.assign(FLMSG_WRAP_auto_dir);
sAutoFile.append("wrap_auto_file");
@ -432,6 +430,8 @@ bool WRAP_auto_arqRx()
autofile.open(sAutoFile.c_str());
}
if(autofile) {
/// Mutex is unlocked when leaving the block.
guard_lock arq_rx_lock(&arq_rx_mutex);
txstring.clear();
time(&start_time);
while (!autofile.eof()) {
@ -465,9 +465,9 @@ bool WRAP_auto_arqRx()
return false;
}
//-----------------------------------------------------------------------------
//======================================================================
// Socket ARQ i/o used on all platforms
//-----------------------------------------------------------------------------
//======================================================================
#define ARQLOOP_TIMING 100 // msec
#define CLIENT_TIMEOUT 5 // timeout after N secs
@ -477,7 +477,7 @@ static string errstring;
static pthread_t* arq_socket_thread = 0;
ARQ_SOCKET_Server* ARQ_SOCKET_Server::inst = 0;
static std::vector<ARQCLIENT> arqclient;
static std::vector<ARQCLIENT> arqclient; // Protected by arq_mutex
void arq_run(Socket);
@ -570,24 +570,43 @@ void* ARQ_SOCKET_Server::thread_func(void*)
break;
}
}
if (!arqclient.empty()) {
vector<ARQCLIENT>::iterator p = arqclient.begin();
while (p != arqclient.end()) {
try {
(*p).sock.close();
arqclient.erase(p);
{
/// Mutex is unlocked when leaving the block.
guard_lock arq_lock(&arq_mutex);
if (!arqclient.empty()) {
vector<ARQCLIENT>::iterator p = arqclient.begin();
while (p != arqclient.end()) {
try {
(*p).sock.close();
arqclient.erase(p);
}
catch (...) {;}
p++;
}
catch (...) {;}
p++;
}
}
inst->server_socket->close();
return NULL;
}
void arq_reset()
{
/// Mutex is unlocked when returning from function
guard_lock arq_rx_lock(&arq_rx_mutex);
arqmode = mailserver = mailclient = false;
txstring.clear();
arqtext.clear();
bSend0x06 = false;
pText = 0;
}
void arq_run(Socket s)
{
pthread_mutex_lock (&arq_mutex);
/// Mutex is unlocked when returning from function
guard_lock arq_lock(&arq_mutex);
struct timeval t = { 0, 20000 };
s.set_timeout(t);
s.set_nonblocking();
@ -604,11 +623,12 @@ void arq_run(Socket s)
p++;
}
LOG_INFO("%s", outs.str().c_str());
pthread_mutex_unlock (&arq_mutex);
}
void WriteARQsocket(unsigned char* data, size_t len)
{
/// Mutex is unlocked when returning from function
guard_lock arq_lock(&arq_mutex);
if (arqclient.empty()) return;
static string instr;
instr.clear();
@ -631,17 +651,24 @@ void WriteARQsocket(unsigned char* data, size_t len)
arqclient.erase(p);
}
}
if (arqclient.empty()) arqmode = false;
string outs = "";
for (unsigned int i = 0; i < len; i++)
outs += asc[data[i] & 0x7F];
LOG_INFO("%s", outs.c_str());
if (arqclient.empty()) arq_reset();
}
void test_arq_clients()
{
/// Mutex is unlocked when returning from function
guard_lock arq_lock(&arq_mutex);
if (arqclient.empty()) return;
static string instr;
instr.clear();
vector<ARQCLIENT>::iterator p;
p = arqclient.begin();
pthread_mutex_lock (&arq_mutex);
time_t now;
while (p != arqclient.end()) {
if (difftime(now = time(0), (*p).keep_alive) > CLIENT_TIMEOUT) {
@ -664,105 +691,106 @@ void test_arq_clients()
p++;
}
}
pthread_mutex_unlock (&arq_mutex);
if (arqclient.empty()) arqmode = false;
if (arqclient.empty()) arq_reset();
}
bool Socket_arqRx()
{
if (arqclient.empty()) return false;
{
/// Mutex is unlocked when leaving block
guard_lock arq_lock(&arq_mutex);
if (arqclient.empty()) return false;
static string instr;
vector<ARQCLIENT>::iterator p = arqclient.begin();
size_t n = 0;
instr.clear();
static string instr;
vector<ARQCLIENT>::iterator p = arqclient.begin();
size_t n = 0;
instr.clear();
pthread_mutex_lock (&arq_mutex);
while (p != arqclient.end()) {
try {
(*p).sock.wait(0);
n = (*p).sock.recv(instr);
if ( n > 0) {
txstring.append(instr);
(*p).keep_alive = time(0);
}
p++;
}
catch (const SocketException& e) {
txstring.clear();
LOG_INFO("closing socket fd %d, %d: %s", (*p).sock.fd(), e.error(), e.what());
while (p != arqclient.end()) {
try {
(*p).sock.close();
} catch (const SocketException& e) {
LOG_ERROR("socket error on # %d, %d: %s", (*p).sock.fd(), e.error(), e.what());
(*p).sock.wait(0);
n = (*p).sock.recv(instr);
if ( n > 0) {
txstring.append(instr);
(*p).keep_alive = time(0);
}
p++;
}
catch (const SocketException& e) {
txstring.clear();
LOG_INFO("closing socket fd %d, %d: %s", (*p).sock.fd(), e.error(), e.what());
try {
(*p).sock.close();
} catch (const SocketException& e) {
LOG_ERROR("socket error on # %d, %d: %s", (*p).sock.fd(), e.error(), e.what());
}
arqclient.erase(p);
}
arqclient.erase(p);
}
if (arqclient.empty()) arq_reset();
}
pthread_mutex_unlock (&arq_mutex);
if (!bSend0x06 && arqtext.empty() && !txstring.empty()) {
{
/// Mutex is unlocked when leaving block
guard_lock arq_rx_lock(&arq_rx_mutex);
if (!txstring.empty()) parse_arqtext(txstring);
pthread_mutex_lock (&arq_rx_mutex);
arqtext.assign(txstring);
parse_arqtext(arqtext);
txstring.clear();
LOG_VERBOSE("arqtext\n%s\n", arqtext.c_str());
if (abort_flag) {
AbortARQ();
abort_flag = false;
return true;
}
if (!arqtext.empty()) {
{
if (bSend0x06 || txstring.empty()) return false;
if (arqtext.empty()) {
arqtext.assign(txstring);
// if (debug_pskmail)
// LOG_INFO("Assigned tx text: %s", noctrl(txstring).c_str());
pText = 0;
if (mailserver && progdefaults.PSKmailSweetSpot)
active_modem->set_freq(progdefaults.PSKsweetspot);
pText = 0;
arq_text_available = true;
active_modem->set_stopflag(false);
start_tx();
} else {
arqtext.append(txstring);
// if (debug_pskmail)
// LOG_INFO("Appended tx text: %s", noctrl(txstring).c_str());
if (trx_state != STATE_TX) {
if (debug_pskmail)
LOG_INFO("%s","Restarting TX");
start_tx();
}
}
pthread_mutex_unlock (&arq_rx_mutex);
return true;
}
txstring.clear();
return false;
arq_text_available = true;
active_modem->set_stopflag(false);
}
}
return true;
}
//-----------------------------------------------------------------------------
// Send ARQ characters to ARQ client
//-----------------------------------------------------------------------------
#if !defined(__WOE32__) && !defined(__APPLE__)
void WriteARQSysV(unsigned char data)
{
rxmsgid = msgget( (key_t) progdefaults.rx_msgid, 0666);
if ( rxmsgid != -1) {
rxmsgst.msg_type = 1;
rxmsgst.c = data;
msgsnd (rxmsgid, (void *)&rxmsgst, 1, IPC_NOWAIT);
}
}
#endif
// ============================================================================
//======================================================================
// Implementation using thread vice the fldigi timeout facility
// ============================================================================
//======================================================================
void WriteARQ(unsigned char data)
{
pthread_mutex_lock (&tosend_mutex);
guard_lock tosend_lock(&tosend_mutex);
tosend += data;
pthread_mutex_unlock (&tosend_mutex);
return;
}
void WriteARQ(const char *data)
{
pthread_mutex_lock (&tosend_mutex);
guard_lock tosend_lock(&tosend_mutex);
tosend.append(data);
pthread_mutex_unlock (&tosend_mutex);
return;
}
static void *arq_loop(void *args)
{
static unsigned char szACK = 0x06;
SET_THREAD_ID(ARQ_TID);
for (;;) {
@ -772,44 +800,31 @@ static void *arq_loop(void *args)
test_arq_clients();
enroute.clear();
pthread_mutex_lock(&tosend_mutex);
if (!tosend.empty()) {
enroute = tosend;
tosend.clear();
}
pthread_mutex_unlock(&tosend_mutex);
{
/// Mutex is unlocked when exiting block
guard_lock tosend_lock(&tosend_mutex);
enroute.clear();
if (!tosend.empty()) {
enroute = tosend;
tosend.clear();
}
if (!enroute.empty()) {
pthread_mutex_lock (&arq_mutex);
WriteARQsocket((unsigned char*)enroute.c_str(), enroute.length());
#if !defined(__WOE32__) && !defined(__APPLE__)
for (size_t i = 0; i < enroute.length(); i++)
WriteARQSysV((unsigned char)enroute[i]);
#endif
pthread_mutex_unlock (&arq_mutex);
if (!enroute.empty()) {
WriteARQsocket((unsigned char*)enroute.c_str(), enroute.length());
}
}
if (bSend0x06) {
pthread_mutex_lock (&arq_mutex);
string xmtdone;
xmtdone += 0x06;
WriteARQsocket((unsigned char*)xmtdone.c_str(), xmtdone.length());
WriteARQsocket(&szACK, 1);
bSend0x06 = false;
pthread_mutex_unlock (&arq_mutex);
}
#if !defined(__WOE32__) && !defined(__APPLE__)
// order of precedence; Socket, Wrap autofile, TLF autofile
// order of precedence; Socket, Wrap autofile, TLF autofile
if (!Socket_arqRx())
if (!SysV_arqRx())
WRAP_auto_arqRx();
if (!WRAP_auto_arqRx())
TLF_arqRx();
#else
if (!Socket_arqRx())
WRAP_auto_arqRx();
#endif
if (!WRAP_auto_arqRx())
TLF_arqRx();
MilliSleep(ARQLOOP_TIMING);
}
@ -852,9 +867,10 @@ void arq_close(void)
int arq_get_char()
{
/// Mutex is unlocked when returning from function
guard_lock arq_rx_lock(&arq_rx_mutex);
int c = 0;
if (arq_text_available) {
pthread_mutex_lock (&arq_rx_mutex);
if (pText != arqtext.length()) {
c = arqtext[pText++] & 0xFF;
} else {
@ -864,52 +880,59 @@ int arq_get_char()
arq_text_available = false;
c = GET_TX_CHAR_ETX;
}
pthread_mutex_unlock (&arq_rx_mutex);
}
return c;
}
//======================================================================
// following function used if the T/R button is pressed to stop a transmission
// that is servicing the ARQ text buffer. It allows the ARQ client to reset
// itself properly
//======================================================================
void AbortARQ() {
pthread_mutex_lock (&arq_mutex);
/// Mutex is unlocked when returning from function
guard_lock arq_lock(&arq_rx_mutex);
arqtext.clear();
txstring.clear();
pText = 0;
arq_text_available = false;
bSend0x06 = true;
pthread_mutex_unlock (&arq_mutex);
}
//======================================================================
// Special notification for PSKMAIL: new mode marked only, in following
// format: "<DC2><Mode:newmode>", with <DC2> = '0x12'.
//======================================================================
void pskmail_notify_rsid(trx_mode mode)
{
char buf[64];
static char buf[64];
memset(buf, 0, sizeof(buf));
int n = snprintf(buf, sizeof(buf),
"\x12<Mode:%s>\n",
mode_info[mode].name);
if (n > 0 && n < (int)sizeof(buf)) {
WriteARQ((const char *)buf);
REQ(&FTextBase::addstr, ReceiveText, buf, FTextBase::CTRL);
LOG_VERBOSE("%s", buf);
LOG_INFO("%s", buf);
}
}
//======================================================================
// Special notification for PSKMAIL: signal to noise measured by decoder
// format "<DC2><s2n: CC, A.a, D.d>"
// where CC = count, A.a = average s/n, D.d = Std dev of s/n
//======================================================================
void pskmail_notify_s2n(double s2n_ncount, double s2n_avg, double s2n_stddev)
{
char buf[64];
static char buf[64];
memset(buf, 0, sizeof(buf));
int n = snprintf(buf, sizeof(buf),
"\x12<s2n: %1.0f, %1.1f, %1.1f>\n",
s2n_ncount, s2n_avg, s2n_stddev);
if (n > 0 && n < (int)sizeof(buf)) {
WriteARQ((const char *)buf);
REQ(&FTextBase::addstr, ReceiveText, buf, FTextBase::CTRL);
LOG_VERBOSE("%s", buf);
LOG_INFO("%s", buf);
}
}

Wyświetl plik

@ -7,6 +7,8 @@
// Leigh L. Klotz, Jr., WA5ZNU
// Copyright (C) 2007-2010
// Stelios Bounanos, M0GLD
// Copyright (C) 2013
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
@ -230,8 +232,6 @@ public:
string& str;
};
#include "re.h"
// Special handling for mode bitsets
template <>
class tag_elem<mode_set_t> : public tag_base
@ -248,20 +248,19 @@ public:
}
void read(const char* data)
{
re_t mode_name_re("([^,]+)", REG_EXTENDED);
int end;
modes.set();
while (mode_name_re.match(data)) {
const char* name = mode_name_re.submatch(1).c_str();
for( ; data ; )
{
const char * comma = strchr( data, ',' );
size_t tok_len = comma ? comma - data : strlen(data);
for (size_t i = 0; i < modes.size(); i++) {
if (!strcmp(mode_info[i].name, name)) {
if (!strncmp(mode_info[i].name, data, tok_len )) {
modes.set(i, 0);
break;
}
}
mode_name_re.suboff(0, NULL, &end);
data += end;
data = comma ? comma + 1 : NULL ;
}
}
mode_set_t& modes;
@ -389,7 +388,7 @@ bool configuration::readDefaultsXML()
tag_map[tag_list[i]->tag] = tag_list[i];
// parse the xml buffer
tag_map_t::const_iterator i;
tag_map_t::const_iterator i = tag_map.end();
while(xml->read()) {
switch(xml->getNodeType()) {
case EXN_TEXT:
@ -583,10 +582,6 @@ int configuration::setDefaults()
inpRIGdev->value(HamRigDevice.c_str());
mnuBaudRate->value(HamRigBaudrate);
#if !USE_XMLRPC
tabXMLRPC->parent()->remove(*tabXMLRPC);
#endif
inpXmlRigDevice->value(XmlRigDevice.c_str());
mnuXmlRigBaudrate->value(XmlRigBaudrate);

Wyświetl plik

@ -0,0 +1,255 @@
// ----------------------------------------------------------------------------
// coordinate.cxx -- Handling of longitude and latitude.
//
// Copyright (C) 2012
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdexcept>
#include <iomanip>
#include <sstream>
#include "config.h"
#include "coordinate.h"
#include "locator.h"
void CoordinateT::Check(void) const
{
if( m_is_lon ) {
if( ( m_angle >= -180.0 ) && ( m_angle <= 180.0 ) ) return ;
} else {
if( ( m_angle >= -90.0 ) && ( m_angle <= 90.0 ) ) return ;
}
std::stringstream strm ;
strm << "Invalid m_angle=" << m_angle << " m_is_lon=" << m_is_lon ;
throw std::runtime_error(strm.str());
}
CoordinateT::CoordinateT( double degrees, bool is_lon )
: m_angle( fmod(degrees, 360.0 ) ), m_is_lon(is_lon)
{
if( m_angle > 180.0 ) m_angle -= 360.0 ;
Check();
};
// Longitude East and Latitude North are positive.
void CoordinateT::Init( char direction, double angle_degrees )
{
m_angle = angle_degrees ;
switch( direction )
{
case 'W':
case 'w':
m_angle = -m_angle ;
case 'E':
case 'e':
if( ( angle_degrees < -180 ) || ( angle_degrees > 180 ) )
throw std::runtime_error("Invalid longitude degree");
m_is_lon = true ;
break ;
case 'S':
case 's':
m_angle = -m_angle ;
case 'N':
case 'n':
if( ( angle_degrees < -90 ) || ( angle_degrees > 90 ) )
throw std::runtime_error("Invalid latitude degree");
m_is_lon = false ;
break ;
default:
throw std::runtime_error("Invalid direction");
}
Check();
}
CoordinateT::CoordinateT( char direction, double angle_degrees ) {
Init( direction, angle_degrees );
}
CoordinateT::CoordinateT( char direction, int degree, int minute, int second )
{
// std::cout << "ctor d=" << direction << " " << degree << " " << minute << " " << second << "\n";
if( ( degree < 0 ) || ( degree > 180 ) )
throw std::runtime_error("Invalid degree");
if( ( minute < 0 ) || ( minute >= 60 ) )
throw std::runtime_error("Invalid minute");
if( ( second < 0 ) || ( second >= 60 ) )
throw std::runtime_error("Invalid second");
double angle_degrees = (double)degree + (double)minute / 60.0 + (double)second / 3600.0 ;
Init( direction, angle_degrees );
}
// Specific for reading from the file of navtex or wmo stations.
// Navtex: "57 06 N"
// Wmo : "69-36N", "013-27E", "009-25E" ou floating-point degrees: "12.34 E".
// Station Latitude or Latitude :DD-MM-SSH where DD is degrees, MM is minutes, SS is seconds
// and H is N for northern hemisphere or S for southern hemisphere or
// E for eastern hemisphere or W for western hemisphere.
// The seconds value is omitted for those stations where the seconds value is unknown.
std::istream & operator>>( std::istream & istrm, CoordinateT & ref )
{
if( ! istrm ) return istrm ;
std::stringstream sstrm ;
char direction ;
while( true ) {
// istrm >> direction ;
direction = (char)istrm.get();
if( ! istrm ) return istrm ;
switch( direction ) {
case 'e':
case 'E':
case 'w':
case 'W':
case 's':
case 'S':
case 'n':
case 'N':
break;
case '0' ... '9' :
case '.' :
case '-' :
case '+' :
case ' ' :
case '\t' :
sstrm << direction ;
continue;
default:
istrm.setstate(std::ios::eofbit);
return istrm ;
}
break;
}
// TODO: Check that the direction is what we expect.
std::string tmpstr = sstrm.str();
// std::cout << "READ:" << tmpstr << ":" << direction << "\n";
const char * tmpPtr = tmpstr.c_str();
int i_degree, i_minute, i_second ;
if( ( 3 == sscanf( tmpPtr, "%d-%d-%d", &i_degree, &i_minute, &i_second ) )
|| ( 3 == sscanf( tmpPtr, "%d %d %d", &i_degree, &i_minute, &i_second ) ) ) {
ref = CoordinateT( direction, i_degree, i_minute, i_second );
return istrm;
}
if( ( 2 == sscanf( tmpPtr, "%d-%d", &i_degree, &i_minute ) )
|| ( 2 == sscanf( tmpPtr, "%d %d", &i_degree, &i_minute ) ) ) {
ref = CoordinateT( direction, i_degree, i_minute, 0 );
return istrm;
}
double d_degree ;
if( 1 == sscanf( tmpPtr, "%lf", &d_degree ) ) {
ref = CoordinateT( direction, d_degree );
return istrm;
}
istrm.setstate(std::ios::eofbit);
return istrm ;
}
std::ostream & operator<<( std::ostream & ostrm, const CoordinateT & ref )
{
bool sign = ref.m_angle > 0 ;
double ang = sign ? ref.m_angle : -ref.m_angle;
ostrm << std::setfill('0') << std::setw( ref.m_is_lon ? 3 : 2 ) << (int)ang << "°"
<< std::setfill('0') << std::setw(2) << ( (int)( 0.5 + ang * 60.0 ) % 60 ) << "'"
<< std::setfill('0') << std::setw(2) << (int)fmod( ang * 3600.0, 60 ) << "''"
<< " ";
ostrm << ( ref.m_is_lon ? sign ? 'E' : 'W' : sign ? 'N' : 'S' );
return ostrm;
}
CoordinateT::Pair::Pair( const CoordinateT & coo1, const CoordinateT & coo2 )
: m_lon( coo1.is_lon() ? coo1 : coo2 )
, m_lat( coo2.is_lon() ? coo1 : coo2 )
{
if( ! ( coo1.is_lon() ^ coo2.is_lon() ) )
{
throw std::runtime_error("Internal inconsistency");
}
}
CoordinateT::Pair::Pair( double lon, double lat )
: m_lon( CoordinateT( lon, true ) )
, m_lat( CoordinateT( lat, false ) ) {}
CoordinateT::Pair::Pair( const std::string & locator )
{
double lon, lat ;
int res = locator2longlat( &lon, &lat, locator.c_str() );
if( res != RIG_OK ) {
throw std::runtime_error("Cannot decode Maidenhead locator:" + locator );
};
m_lon = CoordinateT( lon, true );
m_lat = CoordinateT( lat, false );
}
double CoordinateT::Pair::distance( const Pair & a ) const
{
double dist, azimuth ;
int res = qrb(
longitude().angle(), latitude().angle(),
a.longitude().angle(), a.latitude().angle(),
&dist, &azimuth );
if( res != RIG_OK) {
std::stringstream sstrm ;
sstrm << "Bad qrb result:" << *this << " <-> " << a ;
throw std::runtime_error(sstrm.str());
}
return dist ;
}
std::string CoordinateT::Pair::locator(void) const
{
char buf[64];
int ret = longlat2locator(
longitude().angle(),
latitude().angle(),
buf,
3 );
if( ret == RIG_OK ) {
return buf ;
}
return std::string();
}
std::ostream & operator<<( std::ostream & ostrm, const CoordinateT::Pair & ref )
{
ostrm << ref.latitude() << "/" << ref.longitude();
return ostrm;
}
std::istream & operator>>( std::istream & istrm, CoordinateT::Pair & ref )
{
istrm >> ref.latitude() >> ref.longitude();
return istrm;
}

Wyświetl plik

@ -48,9 +48,18 @@
#include <FL/Fl_Browser.H>
#include "debug.h"
#include "timeops.h"
#include "icons.h"
#include "gettext.h"
#include "threads.h"
#ifndef FLARQ_VERSION
# include "fl_digi.h"
#endif
static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
extern Fl_Double_Window *fl_digi_main;
extern void update_main_title();
@ -75,6 +84,9 @@ debug* debug::inst = 0;
debug::level_e debug::level = debug::INFO_LEVEL;
uint32_t debug::mask = ~0u;
bool debug_pskmail = false;
bool debug_audio = false;
static const char* prefix[] = {
_("Quiet"), _("Error"), _("Warning"), _("Info"), _("Verbose"), _("Debug")
};
@ -153,6 +165,7 @@ void debug::start(const char* filename)
void debug::stop(void)
{
guard_lock debug_lock(&debug_mutex);
if (window) {
window->hide();
delete window;
@ -167,10 +180,11 @@ static char fmt[1024];
void debug::log(level_e level, const char* func, const char* srcf, int line, const char* format, ...)
{
guard_lock debug_lock(&debug_mutex);
if (!inst)
return;
if (unlikely(debug::level == DEBUG_LEVEL)) {
if (unlikely(debug::level == DEBUG_LEVEL) || debug_pskmail || debug_audio) {
time_t t = time(NULL);
struct tm stm;
(void)localtime_r(&t, &stm);

Plik diff jest za duży Load Diff

Wyświetl plik

@ -38,6 +38,7 @@
#include "log.h"
#include "trx.h"
#include "fl_digi.h"
#include "timeops.h"
using namespace std;
@ -74,7 +75,7 @@ void cLogfile::log_to_file(log_t type, const string& s)
gmtime_r(&t, &tm);
strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%MZ", &tm);
char freq[20];
snprintf(freq, sizeof(freq), "%lld", wf->rfcarrier() + (wf->USB()
snprintf(freq, sizeof(freq), "%" PRId64, wf->rfcarrier() + (wf->USB()
? active_modem->get_freq()
: -active_modem->get_freq()));
const char *logmode = mode_info[active_modem->get_mode()].adif_name;

Wyświetl plik

@ -186,6 +186,9 @@ void loadBrowser(Fl_Widget *widget) {
w->add(_("<RISE:nn.n>\tCW rise time"));
w->add(_("<WPM:NN:FF>\tCW WPM:Farnsworth"));
w->add(LINE_SEP);
w->add(_("<RIGCAT:[\"text\"][hex ...]:ret>\tsend CAT cmd"));
w->add(LINE_SEP);
w->add(_("<AFC:on|off|t>\tAFC on,off,toggle"));
w->add(_("<LOCK:on|off|t>\tLOCK on,off,toggle"));

Wyświetl plik

@ -33,6 +33,7 @@
#include "misc.h"
#include "fl_digi.h"
#include "timeops.h"
#include "configuration.h"
#include "confdialog.h"
#include "logger.h"
@ -894,6 +895,75 @@ static void pTXRX(std::string &s, size_t &i, size_t endbracket)
ToggleTXRX = true;
}
static std::string hexstr(std::string &s)
{
static std::string hex;
static char val[3];
hex.clear();
for (size_t i = 0; i < s.length(); i++) {
snprintf(val, sizeof(val), "%02x", s[i] & 0xFF);
hex.append("<").append(val).append(">");
}
return hex;
}
static void pRIGCAT(std::string &s, size_t &i, size_t endbracket)
{
if (within_exec) {
s.replace(i, endbracket - i + 1, "");
return;
}
LOG_INFO("cat cmd:retnbr %s", s.c_str());
size_t start = s.find(':', i);
std::basic_string<char> buff;
size_t val = 0;
int retnbr = 0;
char c, ch;
bool asciisw = false;
bool valsw = false;
for (size_t j = start+1 ; j <= endbracket ; j++) {
ch = s[j];
if (ch == '\"') {
asciisw = !asciisw;
continue;
}
// accumulate ascii string
if (asciisw) {
if (isprint(ch)) buff += ch;
continue;
}
// following digits is expected size of CAT response from xcvr
if (ch == ':' && s[j+1] != '>') {
sscanf(&s[j+1], "%d", &retnbr);
}
// accumulate hex string values
if ((ch == ' ' || ch == '>' || ch == ':') && valsw) {
c = char(val);
// LOG_INFO("c=%02x, val=%d", c, val);
buff += c;
val = 0;
valsw = false;
} else {
val *= 16;
ch = toupper(ch);
if (isdigit(ch)) val += ch - '0';
else if (ch >= 'A' && ch <= 'F') val += ch - 'A' + 10;
valsw = true;
}
if (ch == ':') break;
}
LOG_INFO("cat %s", hexstr(buff).c_str());
sendCommand(buff, retnbr);
s.replace(i, endbracket - i + 1, "");
}
static void pVER(std::string &s, size_t &i, size_t endbracket)
{
@ -1788,15 +1858,15 @@ void set_macro_env(void)
// frequencies
char dial_freq[20];
snprintf(dial_freq, sizeof(dial_freq), "%lld", wf->rfcarrier());
snprintf(dial_freq, sizeof(dial_freq), "%ld", (long)wf->rfcarrier());
env[FLDIGI_DIAL_FREQUENCY].val = dial_freq;
char audio_freq[6];
snprintf(audio_freq, sizeof(audio_freq), "%d", active_modem->get_freq());
env[FLDIGI_AUDIO_FREQUENCY].val = audio_freq;
char freq[20];
snprintf(freq, sizeof(freq), "%lld", wf->rfcarrier() + (wf->USB()
snprintf(freq, sizeof(freq), "%ld", (long)(wf->rfcarrier() + (wf->USB()
? active_modem->get_freq()
: -active_modem->get_freq()));
: -active_modem->get_freq())));
env[FLDIGI_FREQUENCY].val = freq;
// debugging vars
@ -2153,6 +2223,7 @@ static const MTAGS mtags[] = {
{"<TX>", pTX},
{"<TX/RX>", pTXRX},
{"<VER>", pVER},
{"<RIGCAT:", pRIGCAT},
{"<CNTR>", pCNTR},
{"<DECR>", pDECR},
{"<INCR>", pINCR},

Wyświetl plik

@ -31,10 +31,10 @@
#include <time.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include "network.h"
#include "socket.h"
#include "re.h"
#include "timeops.h"
#include "gettext.h"
@ -63,16 +63,24 @@ bool request_reply(const string& node, const string& service, const string& requ
bool fetch_http(const string& url, string& reply, double timeout)
{
re_t http_re("http://([^/]+)(.+)", REG_EXTENDED | REG_ICASE);
static const size_t http_len = 7;
static const char http_str[http_len+1] = "http://";
if (!http_re.match(url.c_str()) || http_re.nsub() != 3)
return false;
const char * url_str = url.c_str();
if( strncmp( url_str, http_str, http_len ) ) return false;
const char * http_host_begin = url_str + http_len ;
const char * http_host_end = strchr( http_host_begin, '/' );
const char * http_page = http_host_end == NULL ? "" : http_host_end ;
std::string http_host = ( http_host_end == NULL )
? http_host_begin
: std::string( http_host_begin, http_host_end );
string request;
request.append("GET ").append(http_re.submatch(2)).append(" HTTP/1.0\n")
.append("Host: ").append(http_re.submatch(1)).append("\nConnection: close\n\n");
request.append("GET ").append(http_page).append(" HTTP/1.0\n")
.append("Host: ").append(http_host).append("\nConnection: close\n\n");
return request_reply(http_re.submatch(1), "http", request, reply, timeout);
return request_reply( http_host, "http", request, reply, timeout);
}
struct fetch_data_t {
@ -102,6 +110,24 @@ static void fetch_url_cleanup(void* data)
Fl::repeat_timeout(1.0, fetch_url_cleanup, data);
}
/// This callback changes the cursor when waiting for loading from the network.
static void busy_cursor(void*)
{
Fl::first_window()->cursor(FL_CURSOR_WAIT);
}
/// This restores the cursor after loading.
static void default_cursor(void*)
{
Fl::first_window()->cursor(FL_CURSOR_DEFAULT);
}
/// Loads a HTTP page to a string with standard cursor display.
bool fetch_http_gui(const string& url, string& reply, double timeout)
{
return fetch_http_gui(url, reply, timeout, busy_cursor, NULL, default_cursor, NULL);
}
// Like fetch_http, but calls Fl::wait and busy() until the time out has elapsed,
// done() before returning
bool fetch_http_gui(const string& url, string& reply, double timeout,

Wyświetl plik

@ -30,6 +30,7 @@
#include "fl_digi.h"
#include "configuration.h"
#include "confdialog.h"
#include "record_browse.h"
#include "logger.h"
#include <string>
@ -411,6 +412,7 @@ void Wizard::create_wizard(void)
{ tabOperator },
{ tabSoundCard },
{ tabRig },
{ tabDataFiles },
};
tabs.resize(sizeof(tabs_)/sizeof(*tabs_));

Wyświetl plik

@ -76,7 +76,7 @@ int get_ui_lang(const char* homedir)
string::size_type u = string::npos;
while (in >> lang) {
if (lang[0] != '\n' & lang[0] != '#' && (u = lang.find('_')) != string::npos)
if ( (lang[0] != '\n') & (lang[0] != '#') && ( (u = lang.find('_')) != string::npos) )
break;
}
in.close();

Wyświetl plik

@ -0,0 +1,567 @@
// ----------------------------------------------------------------------------
// record_loader.cxx
//
// Copyright (C) 2013
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
// Fldigi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Fldigi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include <config.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#ifdef __MINGW32__
# include "compat.h"
#endif
#include "record_loader.h"
#include "record_browse.h"
#include "debug.h"
#include "main.h"
#include "icons.h"
#include "fl_digi.h"
#include "strutil.h"
#include "gettext.h"
#include "network.h"
#include <stdexcept>
#include <fstream>
#include <iostream>
#include <sys/stat.h>
#include "FL/Fl_Double_Window.H"
#include "FL/Fl_Output.H"
#include "FL/fl_ask.H"
#include "FL/Fl_Check_Button.H"
Fl_Double_Window *dlgRecordLoader = (Fl_Double_Window *)0;
/// Loads a file and stores it for later lookup.
int RecordLoaderInterface::LoadAndRegister()
{
Clear();
std::string filnam = storage_filename().first;
time_t cntTim = time(NULL);
LOG_INFO("Opening:%s", filnam.c_str());
std::ifstream ifs( filnam.c_str() );
/// Reuse the same string for each new record.
std::string input_str ;
size_t nbRec = 0 ;
while( ! ifs.eof() )
{
if( ! std::getline( ifs, input_str ) ) break;
/// Comments are legal with # as first character.
if( input_str[0] == '#' ) continue;
imemstream str_strm( input_str );
try
{
if( ReadRecord( str_strm ) ) {
++nbRec;
} else {
LOG_WARN( "Cannot process '%s'", input_str.c_str() );
}
}
catch(const std::exception & exc)
{
LOG_WARN( "%s: Caught <%s> when reading '%s'",
base_filename().c_str(),
exc.what(),
input_str.c_str() );
return -1 ;
}
}
ifs.close();
LOG_INFO( "Read:%s with %d records in %d seconds",
filnam.c_str(), nbRec, (int)( time(NULL) - cntTim ) );
return nbRec ;
}
// ----------------------------------------------------------------------------
struct Row
{
Fl_Output * m_timestamp ;
Fl_Check_Button * m_select ;
Fl_Output * m_content_size ;
Fl_Output * m_nb_rows ;
Fl_Button * m_url ;
RecordLoaderInterface * m_itf ;
bool UpdateRow()
{
const std::string str = m_itf->Timestamp();
m_timestamp->value(str.c_str());
const std::string & strSz = m_itf->ContentSize();
m_content_size->value(strSz.c_str());
int nb_recs = m_itf->LoadAndRegister();
char nb_recs_str[64];
bool isGood = ( nb_recs >= 0 );
if( isGood )
sprintf( nb_recs_str, "%6d", nb_recs );
else
strcpy( nb_recs_str, " N/A" );
m_nb_rows->value(nb_recs_str);
const char * strurl = m_itf->Url();
if( strurl != NULL ) {
const std::string strnam = m_itf->base_filename();
m_url->tooltip( strurl );
}
if (dlgRecordLoader)
dlgRecordLoader->damage();
return isGood ;
}
};
/// Array all data loaders. It is setup at start time.
static Row * all_recs = NULL ;
/// Number of data loaders, it is a very small integer.
static int dataloader_nb = 0 ;
static const int nb_cols = 5 ;
// ----------------------------------------------------------------------------
/// This is a virtual class, therefore it must have a default constructor.
RecordLoaderInterface::RecordLoaderInterface()
{
++dataloader_nb ;
/// We prefer tp use realloc because it is ready before main() is called.
all_recs = (Row *)realloc( all_recs, dataloader_nb * sizeof( Row ) );
all_recs[ dataloader_nb - 1 ].m_itf = this ;
}
/// This happens very rarely, so performance is not an issue.
RecordLoaderInterface::~RecordLoaderInterface()
{
for( int i = 0; i < dataloader_nb; ++i )
{
if( all_recs[i].m_itf == this ) {
memmove( all_recs + i, all_recs + i + 1, sizeof( Row ) * ( dataloader_nb - i - 1 ) );
--dataloader_nb ;
return ;
}
}
LOG_ERROR("Inconsistent %d", dataloader_nb );
}
/// This takes only the filename from the complete HTTP or FTP URL, or file path.
std::string RecordLoaderInterface::base_filename() const
{
const char * pFil = strrchr( Url(), '/' );
if( pFil == NULL )
pFil = Url();
else
++pFil ;
/// This might be an URL so we take only the beginning.
const char * quest = strchr( pFil, '?' );
if( quest == NULL ) quest = pFil + strlen(pFil);
return std::string( pFil, quest );
}
std::pair< std::string, bool > RecordLoaderInterface::storage_filename(bool create_dir) const
{
/// We check if it is changed, it is not performance-critical.
if( create_dir ) {
if( ask_dir_creation( DATA_dir ) ) {
const char * err = create_directory( DATA_dir.c_str() );
if( err ) {
fl_alert("Error:%s",err);
}
}
}
std::string filnam_data = DATA_dir + "/" + base_filename();
if( create_dir ) {
return std::make_pair( filnam_data, false );
}
/// This is for a read access.
std::ifstream ifs( filnam_data.c_str() );
if( ifs )
{
ifs.close();
return std::make_pair( filnam_data, false );
}
if( errno != ENOENT ) {
LOG_WARN( "Cannot read '%s': %s", filnam_data.c_str(), strerror(errno) );
}
// Second try with a file maybe installed by "make install".
std::string filnam_inst = PKGDATADIR "/" + base_filename();
LOG_INFO("Errno=%s with %s. Trying %s", strerror(errno), filnam_data.c_str(), filnam_inst.c_str() );
ifs.open( filnam_inst.c_str() );
if( ifs )
{
ifs.close();
return std::make_pair( filnam_inst, true );
}
/// But the file is not there.
return std::make_pair( filnam_data, false );
}
std::string RecordLoaderInterface::Timestamp() const
{
std::string filnam = storage_filename().first;
struct stat st;
if (stat(filnam.c_str(), &st) == -1 ) return "N/A";
struct tm tmLastMod = *localtime( & st.st_mtime );
char buf[64];
sprintf(buf, "%d/%d/%d %02d:%02d",
tmLastMod.tm_year + 1900,
tmLastMod.tm_mon + 1,
tmLastMod.tm_mday,
tmLastMod.tm_hour,
tmLastMod.tm_min );
return buf ;
}
std::string RecordLoaderInterface::ContentSize() const
{
/// It would be faster to cache this result in the object.
std::string filnam = storage_filename().first;
struct stat st;
if (stat(filnam.c_str(), &st) == -1 ) return " N/A";
char buf[64];
sprintf(buf, "%9" PRIuSZ, (size_t)st.st_size );
return buf ;
}
// ----------------------------------------------------------------------------
static void cb_record_url(Fl_Widget *w, void* ptr)
{
const RecordLoaderInterface * it = static_cast< const RecordLoaderInterface * >(ptr);
cb_mnuVisitURL( NULL, const_cast< char * >( it->Url() ) );
}
void DerivedRecordLst::AddRow( int row )
{
Row * ptRow = all_recs + row ;
int X,Y,W,H;
int col=0;
{
col_width( col, 110 );
find_cell(CONTEXT_TABLE, row, col, X, Y, W, H);
ptRow->m_timestamp = new Fl_Output(X,Y,W,H);
ptRow->m_timestamp->tooltip( _("Data file creation date") );
}
++col;
{
col_width( col, 16 );
find_cell(CONTEXT_TABLE, row, col, X, Y, W, H);
ptRow->m_select = new Fl_Check_Button(X,Y,W,H);
ptRow->m_select->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
ptRow->m_select->value(1);
}
++col;
{
col_width( col, 80 );
find_cell(CONTEXT_TABLE, row, col, X, Y, W, H);
ptRow->m_content_size = new Fl_Output(X,Y,W,H);
ptRow->m_content_size->tooltip( _("Size in bytes") );
}
++col;
{
col_width( col, 50 );
find_cell(CONTEXT_TABLE, row, col, X, Y, W, H);
ptRow->m_nb_rows = new Fl_Output(X,Y,W,H);
ptRow->m_nb_rows->tooltip( _("Number of lines in data file") );
}
++col;
{
col_width( col, 166 );
find_cell(CONTEXT_TABLE, row, col, X, Y, W, H);
const char * strurl = ptRow->m_itf->Url();
ptRow->m_url = NULL ;
if( strurl != NULL ) {
const std::string strnam = ptRow->m_itf->base_filename();
ptRow->m_url = new Fl_Button(X,Y,W,H, strdup(strnam.c_str()) );
ptRow->m_url->tooltip( strurl );
ptRow->m_url->callback(cb_record_url, ptRow->m_itf);
}
}
ptRow->UpdateRow();
}
DerivedRecordLst::DerivedRecordLst(int x, int y, int w, int h, const char *title)
: Fl_Table(x,y,w,h,title)
{
col_header(1);
col_resize(1);
col_header_height(25);
row_header(1);
row_resize(0);
row_header_width(105);
rows(dataloader_nb);
cols(nb_cols);
begin(); // start adding widgets to group
{
for( int row = 0; row < dataloader_nb; ++row )
{
AddRow( row );
}
}
end();
}
DerivedRecordLst::~DerivedRecordLst()
{
}
// Handle drawing all cells in table
void DerivedRecordLst::draw_cell(TableContext context,
int R, int C, int X, int Y, int W, int H)
{
switch ( context )
{
case CONTEXT_STARTPAGE:
fl_font(FL_HELVETICA, 12); // font used by all headers
break;
case CONTEXT_RC_RESIZE:
{
int X, Y, W, H;
int index = 0;
for ( int r = 0; r<rows(); r++ )
{
for ( int c = 0; c<cols(); c++ )
{
if ( index >= children() ) break;
find_cell(CONTEXT_TABLE, r, c, X, Y, W, H);
child(index++)->resize(X,Y,W,H);
}
}
init_sizes(); // tell group children resized
return;
}
case CONTEXT_ROW_HEADER:
fl_push_clip(X, Y, W, H);
{
RecordLoaderInterface * it = ( (R >= 0) && ( R < dataloader_nb ) ) ? all_recs[ R ].m_itf : NULL;
if( it == NULL ) {
LOG_ERROR("R=%d",R);
return;
}
const char * str = it ? it->Description() : "Unknown" ;
fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, row_header_color());
fl_color(FL_BLACK);
fl_draw(str, X, Y, W, H, FL_ALIGN_CENTER);
}
fl_pop_clip();
return;
case CONTEXT_COL_HEADER:
fl_push_clip(X, Y, W, H);
{
static const char * col_names[nb_cols] = {
_("Timestamp"),
_(" "),
_("Size"),
_("# recs"),
_("WWW"),
};
const char * title = ( ( C >= 0 ) && ( C < nb_cols ) ) ? col_names[C] : "?" ;
fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
fl_color(FL_BLACK);
fl_draw(title, X, Y, W, H, FL_ALIGN_CENTER);
}
fl_pop_clip();
return;
case CONTEXT_CELL:
// fl_push_clip(X, Y, W, H);
return; // fltk handles drawing the widgets
default:
return;
}
}
void DerivedRecordLst::cbGuiUpdate()
{
std::string server = inpDataSources->value();
if( server.empty() ) {
fl_alert(_("No server selected"));
return ;
}
if( server[server.size()-1] != '/' ) server += '/' ;
for( int row = 0; row < dataloader_nb; ++row )
{
Row * ptrRow = all_recs + row;
if( ! ptrRow->m_select->value() ) continue ;
RecordLoaderInterface * it = ptrRow->m_itf;
std::string url = server + it->base_filename();
std::string reply ;
double timeout=600.0;
// Consider truncating the HTTP header.
int res = fetch_http_gui(url, reply, timeout );
LOG_INFO("Loaded %s : %d chars. res=%d", url.c_str(), (int)reply.size(), res );
if( ! res )
{
int ok = fl_choice2(
_("Could not download %s"),
_("Continue"),
_("Stop"),
NULL,
url.c_str() );
if( ok == 1 ) break ;
continue ;
}
static const char *notFound404 = "HTTP/1.1 404 Not Found";
if( 0 == strncmp( reply.c_str(), notFound404, strlen(notFound404) ) )
{
int ok = fl_choice2(
_("Non-existent URL: %s"),
_("Continue"),
_("Stop"),
NULL,
url.c_str() );
if( ok == 1 ) break ;
continue ;
}
/// This creates the directory if necessary;
std::string filnam = it->storage_filename(true).first;
std::ofstream ofstrm( filnam.c_str() );
if( ofstrm )
ofstrm.write( &reply[0], reply.size() );
if( ! ofstrm ) {
int ok = fl_choice2(
_("Error saving %s to %s:%s"),
_("Continue"),
_("Stop"),
NULL,
url.c_str(), filnam.c_str(), strerror(errno) );
if( ok == 1 ) break ;
continue ;
}
ofstrm.close();
bool isGood = all_recs[row].UpdateRow();
if( ! isGood ) {
int ok = fl_choice2(
_("Error loading %s to %s: %s."),
_("Continue"),
_("Stop"),
NULL,
url.c_str(), filnam.c_str(), strerror(errno) );
if( ok == 0 ) break ;
continue ;
}
}
btnDataSourceUpdate->value(0);
}
void DerivedRecordLst::cbGuiReset()
{
fprintf(stderr, "%s\n", __FUNCTION__ );
for( int row = 0; row < dataloader_nb; ++row )
{
Row * ptrRow = all_recs + row;
if( ! ptrRow->m_select->value() ) continue ;
RecordLoaderInterface * it = ptrRow->m_itf;
std::pair< std::string, bool > stofil_pair = it->storage_filename(true);
it->Clear();
const char * stofil = stofil_pair.first.c_str() ;
if( stofil_pair.second ) {
fl_alert("Cannot erase installed data file %s", stofil );
continue ;
} else {
LOG_INFO("Erasing %s", stofil );
int res = ::remove( stofil );
if( ( res != 0 ) && ( res != ENOENT ) ) {
fl_alert("Error erasing data file %s:%s", stofil, strerror(errno) );
continue ;
}
all_recs[row].UpdateRow();
}
}
}
// ----------------------------------------------------------------------------
/// Necessary because in a Fl_Menu, a slash has a special meaning.
static std::string fl_escape( const char * str )
{
std::string res ;
for( char ch ; ( ch = *str ) != '\0' ; ++str )
{
if( ch == '/' ) res += '\\';
res += ch ;
}
return res ;
}
static void fl_input_add( const char * str )
{
inpDataSources->add( fl_escape( str ).c_str() );
}
void createRecordLoader()
{
if (dlgRecordLoader) return;
dlgRecordLoader = make_record_loader_window();
fl_input_add("http://www.w1hkj.com/support_files/");
fl_input_add("http://primhillcomputers.com/fldigi/data");
inpDataSources->value(0);
}
// ----------------------------------------------------------------------------

Wyświetl plik

@ -31,6 +31,11 @@
#include <cstring>
#include <climits>
#include <stdexcept>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <limits>
#include "re.h"
#include "strutil.h"
@ -88,3 +93,156 @@ string strformat( const char * fmt, ... )
return str ;
}
/// Removes leading spaces and tabs.
static std::string & strtriml(std::string &str) {
str.erase(str.begin(), std::find_if(str.begin(), str.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return str;
}
/// Removes trailing spaces and tabs.
static std::string & strtrimr(std::string &str) {
str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), str.end());
return str;
}
/// Removes leading trailing spaces and tabs.
void strtrim(std::string &str) {
strtriml(strtrimr(str));
}
void strcapitalize(std::string &str) {
bool isStart = true ;
for( size_t i = 0; i < str.size(); ++i ) {
const char tmpC = str[i];
if( isalpha( tmpC ) ) {
if( isStart ) {
str[ i ] = toupper( tmpC );
isStart = false ;
} else {
str[ i ] = tolower( tmpC );
}
} else {
isStart = true ;
}
}
}
std::string strreplace( const std::string & inp, const std::string & from, const std::string & to )
{
size_t from_sz=from.size();
std::string tmp ;
for( size_t old_curr = 0 ; ; ) {
size_t new_curr = inp.find( from, old_curr );
if( new_curr == std::string::npos ) {
tmp.append( inp, old_curr, std::string::npos );
break ;
}
else
{
tmp.append( inp, old_curr, new_curr - old_curr );
tmp.append( to );
old_curr = new_curr + from_sz ;
}
}
return tmp ;
}
/// Edit distance. Not the fastest implementation.
size_t levenshtein(const string & source, const string & target) {
const size_t n = source.size();
const size_t m = target.size();
if (n == 0) return m;
if (m == 0) return n;
typedef std::vector< std::vector<size_t> > Tmatrix;
Tmatrix matrix(n+1);
for (size_t i = 0; i <= n; i++) {
matrix[i].resize(m+1);
}
for (size_t i = 0; i <= n; i++) {
matrix[i][0]=i;
}
for (size_t j = 0; j <= m; j++) {
matrix[0][j]=j;
}
for (size_t i = 1; i <= n; i++) {
char s_i = source[i-1];
for (size_t j = 1; j <= m; j++) {
char t_j = target[j-1];
size_t cost = (s_i == t_j) ? 0 : 1 ;
size_t above = matrix[i-1][j];
size_t left = matrix[i][j-1];
size_t diag = matrix[i-1][j-1];
size_t cell = std::min( above + 1, std::min(left + 1, diag + cost));
// Step 6A: Cover transposition, in addition to deletion,
// insertion and substitution. This step is taken from:
// Berghel, Hal ; Roach, David : "An Extension of Ukkonen's
// Enhanced Dynamic Programming ASM Algorithm"
// (http://www.acm.org/~hlb/publications/asm/asm.html)
if (i>2 && j>2) {
size_t trans=matrix[i-2][j-2]+1;
if (source[i-2]!=t_j) trans++;
if (s_i!=target[j-2]) trans++;
if (cell>trans) cell=trans;
}
matrix[i][j]=cell;
}
}
return matrix[n][m];
}
/// Converts a string to uppercase.
string uppercase( const string & str )
{
string resu ;
for( size_t i = 0 ; i < str.size(); ++i )
{
resu += static_cast<char>( toupper( str[i] ) );
}
return resu ;
}
// ----------------------------------------------------------------------------
/// Just reads all chars until the delimiter.
bool read_until_delim( char delim, std::istream & istrm )
{
istrm.ignore ( std::numeric_limits<std::streamsize>::max(), delim );
if(istrm.eof()) return true ;
return istrm.bad() ? false : true ;
}
/// Reads a char up to the given delimiter, or returns the default value if there is none.
bool read_until_delim( char delim, std::istream & istrm, char & ref, const char dflt )
{
if(istrm.eof()) {
ref = dflt ;
return true ;
}
ref = istrm.get();
if( istrm.bad() ) return false;
if( ref == delim ) {
ref = dflt ;
return true ;
}
char tmpc = istrm.get();
if( istrm.eof() ) return true;
if( tmpc == delim ) return true ;
if( tmpc == '\n' ) return true ;
if( tmpc == '\r' ) return true ;
return false;
}

Wyświetl plik

@ -173,3 +173,31 @@ bool operator==(const struct timeval &t0, const struct timeval &t1)
{
return t0.tv_sec == t1.tv_sec && t0.tv_usec == t1.tv_usec;
}
#ifndef HAVE_GMTIME_R
#include "threads.h"
static pthread_mutex_t gmtime_r_mutex = PTHREAD_MUTEX_INITIALIZER;
struct tm *gmtime_r(const time_t *_Time, struct tm *_Tm)
{
pthread_mutex_lock (&gmtime_r_mutex);
struct tm *p = gmtime(_Time);
if (p && _Tm) memcpy (_Tm, p, sizeof (struct tm));
pthread_mutex_unlock (&gmtime_r_mutex);
return p;
}
static pthread_mutex_t gmtime_local_mutex = PTHREAD_MUTEX_INITIALIZER;
struct tm *localtime_r(const time_t *_Time,struct tm *_Tm)
{
pthread_mutex_lock (&gmtime_local_mutex);
struct tm *p = localtime(_Time);
if (p && _Tm) memcpy (_Tm, p, sizeof (struct tm));
pthread_mutex_unlock (&gmtime_local_mutex);
return p;
}
#endif

Wyświetl plik

@ -5,6 +5,8 @@
// Stelios Bounanos, M0GLD
// Copyright (C) 2009
// Dave Freese, W1HKJ
// Copyright (C) 2013
// Remi Chateauneu, F4ECW
//
// This file is part of fldigi.
//
@ -22,16 +24,21 @@
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include <config.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/stat.h>
#include <cstdlib>
#include "config.h"
#include "util.h"
#ifdef __MINGW32__
# include "compat.h"
#endif
/* Return the smallest power of 2 not less than n */
/// Return the smallest power of 2 not less than n
uint32_t ceil2(uint32_t n)
{
--n;
@ -44,7 +51,7 @@ uint32_t ceil2(uint32_t n)
return n + 1;
}
/* Return the largest power of 2 not greater than n */
/// Return the largest power of 2 not greater than n
uint32_t floor2(uint32_t n)
{
n |= n >> 1;
@ -57,6 +64,8 @@ uint32_t floor2(uint32_t n)
}
#include <stdlib.h>
/// Transforms the version, as a string, into an integer, so comparisons are possible.
unsigned long ver2int(const char* version)
{
unsigned long v = 0L;
@ -285,6 +294,7 @@ uint32_t simple_hash_str(const unsigned char* str, uint32_t code)
#include <climits>
static const char hexsym[] = "0123456789ABCDEF";
static std::vector<char>* hexbuf;
const char* str2hex(const unsigned char* str, size_t len)
{
@ -344,3 +354,112 @@ void MilliSleep(long msecs)
Sleep(msecs);
#endif
}
/// Returns 0 if a process is running, 0 if not there and -1 if the test cannot be made.
int test_process(int pid)
{
#ifdef __MINGW32__
HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
DWORD ret = WaitForSingleObject(process, 0);
CloseHandle(process);
return ret == WAIT_TIMEOUT;
#elif defined(__linux__)
/// This is dependent on procfs.
char buf[32];
sprintf(buf,"/proc/%d/cmdline",pid);
FILE * tmpF = fopen( buf, "r" );
if( tmpF != NULL ) {
fclose(tmpF);
return 1 ;
}
return 0 ;
#else
int ret = kill(pid,0);
switch( ret ) {
case EINVAL: return -1 ;
case EPERM : return -1 ;
case ESRCH : return 0 ; // Process is not there.
case 0 : return 1 ; // Process is found.
}
fprintf(stderr,"kill failed with %s", strerror(ret) );
return -1 ;
#endif
}
#ifdef __MINGW32__
/// This includes Windows.h
#include <winbase.h>
/// Retrieve the system error message for the last-error code
static const char * WindowsError(DWORD dw)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
/// BEWARE, this is NOT reentrant !
static char buffer[2048];
strcpy( buffer, (const char *)lpMsgBuf );
LocalFree(lpMsgBuf);
return buffer ;
}
#endif
/// Starts a process and returns its pid, and -1 if error. Returns 0 if this cannot be made.
int fork_process( const char * cmd )
{
#ifdef __MINGW32__
char* cmd_local = strdup(cmd);
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
if (!CreateProcess(NULL, cmd_local, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
fprintf(stderr,"CreateProcess failed: %s", WindowsError(GetLastError()) );
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
free(cmd_local);
return pi.dwProcessId ;
#else
pid_t newpid = fork();
switch(newpid) {
case -1:
return -1 ;
case 0:
execl("/bin/sh", "sh", "-c", cmd, NULL );
fprintf(stderr,"execl failed with %s", strerror(errno) );
/// Ideally we should warn the main process.
exit(EXIT_FAILURE);
}
return newpid ;
#endif
}
/// Returns true if OK. Beware, the error case is not reentrant.
const char * create_directory( const char * dir )
{
#ifdef __WIN32__
if( !CreateDirectory( dir, NULL ) ) {
DWORD err = GetLastError();
if( err == ERROR_ALREADY_EXISTS ) return NULL ;
return WindowsError(err);
}
#else
if ( mkdir(dir, 0777) == -1 ) {
if( errno == EEXIST ) return NULL ;
return strerror(errno);
}
#endif
return NULL ;
}

Wyświetl plik

@ -189,16 +189,6 @@ static wxpairs cloud_type[] = {
{"CI", "cirrus"},
{NULL, NULL} };
static void wx_busy_cursor(void*)
{
Fl::first_window()->cursor(FL_CURSOR_WAIT);
}
static void wx_default_cursor(void*)
{
Fl::first_window()->cursor(FL_CURSOR_DEFAULT);
}
void getwx(string& wx, const char *metar)
{
string url;
@ -226,7 +216,7 @@ void getwx(string& wx, const char *metar)
url.assign("http://weather.noaa.gov/pub/data/observations/metar/decoded/")
.append(wxsta).append(".TXT");
if (!fetch_http_gui(url, text, 5.0, wx_busy_cursor, 0, wx_default_cursor, 0)) {
if (!fetch_http_gui(url, text, 5.0)) {
LOG_WARN("%s", "url not available\n");
return;
}
@ -238,7 +228,10 @@ void getwx(string& wx, const char *metar)
LOG_WARN("%s", "station not found\n");
return;
}
const char *eoh = "Content-Type:";
string eoh = progdefaults.wx_eoh;
if (eoh.empty()) eoh = "Connection: close";
p1 = text.find(eoh);
if (p1 != string::npos) {
p1 = text.find("\n",p1);

Wyświetl plik

@ -78,6 +78,7 @@
#include "rigsupport.h"
#include "confdialog.h"
#include "arq_io.h"
LOG_FILE_SOURCE(debug::LOG_RPC);
@ -586,7 +587,8 @@ public:
return;
}
}
throw xmlrpc_c::fault("No such modem");
*retval = "No such modem";
return;
}
};
@ -673,9 +675,10 @@ public:
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
{
if (!(active_modem->get_cap() & modem::CAP_AFC_SR))
throw xmlrpc_c::fault("Operation not supported by modem");
*retval = xmlrpc_c::value_int((int)cntSearchRange->value());
*retval = "Operation not supported by modem";
// throw xmlrpc_c::fault("Operation not supported by modem");
else
*retval = xmlrpc_c::value_int((int)cntSearchRange->value());
}
};
@ -690,8 +693,11 @@ public:
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
{
XMLRPC_LOCK;
if (!(active_modem->get_cap() & modem::CAP_AFC_SR))
throw xmlrpc_c::fault("Operation not supported by modem");
if (!(active_modem->get_cap() & modem::CAP_AFC_SR)) {
*retval = "Operation not supported by modem";
return;
// throw xmlrpc_c::fault("Operation not supported by modem");
}
int v = (int)(cntSearchRange->value());
REQ(set_valuator, cntSearchRange, params.getInt(0, (int)cntSearchRange->minimum(), (int)cntSearchRange->maximum()));
@ -710,8 +716,11 @@ public:
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
{
XMLRPC_LOCK;
if (!(active_modem->get_cap() & modem::CAP_AFC_SR))
throw xmlrpc_c::fault("Operation not supported by modem");
if (!(active_modem->get_cap() & modem::CAP_AFC_SR)) {
*retval = "Operation not supported by modem";
return;
// throw xmlrpc_c::fault("Operation not supported by modem");
}
int v = (int)(cntSearchRange->value() + params.getInt(0));
REQ(set_valuator, cntSearchRange, v);
@ -724,15 +733,16 @@ public:
static Fl_Valuator* get_bw_val(void)
{
if (!(active_modem->get_cap() & modem::CAP_BW))
throw xmlrpc_c::fault("Operation not supported by modem");
return 0;
// throw xmlrpc_c::fault("Operation not supported by modem");
trx_mode m = active_modem->get_mode();
if (m >= MODE_HELL_FIRST && m <= MODE_HELL_LAST)
return sldrHellBW;
else if (m == MODE_CW)
return sldrCWbandwidth;
throw xmlrpc_c::fault("Unknown CAP_BW modem");
return 0;
// throw xmlrpc_c::fault("Unknown CAP_BW modem");
}
class Modem_get_bw : public xmlrpc_c::method
@ -853,7 +863,8 @@ public:
}
break;
default:
throw xmlrpc_c::fault("Invalid Olivia bandwidth");
*retval = "Invalid Olivia bandwidth";
// throw xmlrpc_c::fault("Invalid Olivia bandwidth");
}
}
};
@ -902,7 +913,8 @@ public:
*retval = xmlrpc_c::value_nil();
}
else
throw xmlrpc_c::fault("Invalid Olivia tones");
*retval = "Invalid Olivia tones";
// throw xmlrpc_c::fault("Invalid Olivia tones");
}
};
@ -976,8 +988,11 @@ public:
{
XMLRPC_LOCK;
string s = params.getString(0);
if (s != "LSB" && s != "USB")
throw xmlrpc_c::fault("Invalid argument");
if (s != "LSB" && s != "USB") {
*retval = "Invalid argument";
return;
// throw xmlrpc_c::fault("Invalid argument");
}
if (progdefaults.chkUSERIGCATis)
rigCAT_setmode(s);
@ -1019,7 +1034,9 @@ public:
XMLRPC_LOCK;
string s = params.getString(0);
if (s != "USB" && s != "LSB")
throw xmlrpc_c::fault("Invalid argument");
*retval = "Invalid argument";
// throw xmlrpc_c::fault("Invalid argument");
else
REQ(static_cast<void (waterfall::*)(bool)>(&waterfall::USB), wf, s == "USB");
*retval = xmlrpc_c::value_nil();
@ -1466,8 +1483,10 @@ public:
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
{
XMLRPC_LOCK;
if (trx_state == STATE_TX || trx_state == STATE_TUNE)
if (trx_state == STATE_TX || trx_state == STATE_TUNE) {
REQ(abort_tx);
REQ(AbortARQ);
}
*retval = xmlrpc_c::value_nil();
}
};
@ -1535,11 +1554,13 @@ public:
}
void execute(const xmlrpc_c::paramList& params, xmlrpc_c::value* retval)
{
// if (trx_state == STATE_TX || trx_state == STATE_TUNE)
if (btnTune->value() || wf->xmtrcv->value())
if (trx_state == STATE_TX || trx_state == STATE_TUNE)
// if (btnTune->value() || wf->xmtrcv->value())
*retval = xmlrpc_c::value_string("TX");
else
else if (trx_state == STATE_RX)
*retval = xmlrpc_c::value_string("RX");
else
*retval = xmlrpc_c::value_string("OTHER");
}
};
@ -2980,7 +3001,7 @@ struct Navtex_send_message : public xmlrpc_c::method
ELEM_(Spot_get_auto, "spot.get_auto") \
ELEM_(Spot_set_auto, "spot.set_auto") \
ELEM_(Spot_toggle_auto, "spot.toggle_auto") \
ELEM_(Spot_pskrep_get_count, "spot.pskrep.get_count") \
ELEM_(Spot_pskrep_get_count, "spot.pskrep.get_count") \
\
ELEM_(Wefax_state_string, "wefax.state_string") \
ELEM_(Wefax_skip_apt, "wefax.skip_apt") \
@ -2994,7 +3015,7 @@ struct Navtex_send_message : public xmlrpc_c::method
ELEM_(Wefax_send_file, "wefax.send_file") \
\
ELEM_(Navtex_get_message, "navtex.get_message") \
ELEM_(Navtex_send_message, "navtex.send_message") \
struct rm_pred
{

Wyświetl plik

@ -7,7 +7,7 @@
// This file is part of fldigi. Adapted from code contained in JNX source code
// distribution.
// JNX Copyright (C) Paul Lutus
// http://www.arachnoid.com/BiQuadDesigner/index.html
// http://www.arachnoid.com/JNX/index.html
//
// fldigi is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -48,143 +48,16 @@
#include "gettext.h"
#include "navtex.h"
#include "logbook.h"
#include "locator.h"
#include "coordinate.h"
#include "misc.h"
#include "status.h"
#include "strutil.h"
#include "kmlserver.h"
#include "record_loader.h"
class CoordinateT
{
double m_angle ;
bool m_is_lon ;
public:
CoordinateT()
: m_angle(0.0), m_is_lon(true) {};
CoordinateT( double angle, bool is_lon ) : m_angle(angle), m_is_lon(is_lon) {};
CoordinateT( char direction, int degree, int minute, int second )
{
// std::cout << "ctor d=" << direction << " " << degree << " " << minute << " " << second << "\n";
if( ( degree < 0 ) || ( degree > 180.0 ) )
throw std::runtime_error("Invalid degree");
if( ( minute < 0 ) || ( minute >= 60.0 ) )
throw std::runtime_error("Invalid minute");
if( ( second < 0 ) || ( second >= 60.0 ) )
throw std::runtime_error("Invalid second");
m_angle = (double)degree + (double)minute / 60.0 + (double)second / 3600.0 ;
switch( direction )
{
case 'E':
case 'e':
m_angle = -m_angle ;
case 'W':
case 'w':
if( ( degree < -180.0 ) || ( degree > 180.0 ) )
throw std::runtime_error("Invalid longitude degree");
m_is_lon = true ;
break ;
case 'S':
case 's':
m_angle = -m_angle ;
case 'N':
case 'n':
if( ( degree < -90.0 ) || ( degree > 90.0 ) )
throw std::runtime_error("Invalid latitude degree");
m_is_lon = false ;
break ;
default:
throw std::runtime_error("Invalid direction");
}
// std::cout << "Angle=" << m_angle << "\n" ;
}
double angle(void) const { return m_angle ; }
bool is_lon(void) const { return m_is_lon; }
// 57 06 N : It should work with other formats.
// Specific for reading from the file of naxtex stations.
friend std::istream & operator>>( std::istream & istrm, CoordinateT & ref )
{
int degree, minute ;
if( ! istrm ) return istrm ;
istrm >> degree ;
if( ! istrm ) return istrm ;
istrm >> minute ;
if( ! istrm ) return istrm ;
char direction ;
istrm >> direction ;
if( ! istrm ) return istrm ;
ref = CoordinateT( direction, degree, minute, 0 );
// std::cout << "::" << ref << ":" << degree << " " << minute << " " << direction << "\n" ;
return istrm ;
}
class Pair ;
}; // CoordinateT
// Latitude , longitude.
class CoordinateT::Pair
{
CoordinateT m_lon, m_lat ;
public:
Pair() {}
Pair( const CoordinateT & coo1, const CoordinateT & coo2 )
: m_lon( coo1.is_lon() ? coo1 : coo2 )
, m_lat( coo2.is_lon() ? coo1 : coo2 )
{
if( ! ( coo1.is_lon() ^ coo2.is_lon() ) )
{
throw std::runtime_error("Internal inconsistency");
}
}
CoordinateT longitude() const { return m_lon ; }
CoordinateT latitude() const { return m_lat ; }
CoordinateT & longitude() { return m_lon ; }
CoordinateT & latitude() { return m_lat ; }
double distance( const Pair & a ) const
{
double dist, azimuth ;
int res = qrb(
longitude().angle(), latitude().angle(),
a.longitude().angle(), a.latitude().angle(),
&dist, &azimuth );
if( res != RIG_OK) {
throw std::runtime_error("Bad qrb result");
}
return dist ;
}
}; // CoordinateT::Pair
static const char delim = ';';
template< typename Type >
bool read_until_delim( std::istream & istrm, Type & ref )
{
std::string parsed_str ;
if( ! std::getline( istrm, parsed_str, delim ) ) return false ;
std::stringstream sstrm( parsed_str );
sstrm >> ref ;
return sstrm ;
}
static bool read_until_delim( std::istream & istrm, std::string & ref )
{
return std::getline( istrm, ref, delim );
}
#include "FL/fl_ask.H"
/// This models a line of the file defining Navtex stations.
class NavtexRecord
{
std::string m_country ;
@ -194,11 +67,11 @@ class NavtexRecord
std::string m_callsign ;
std::string m_name ;
CoordinateT::Pair m_coordinates ;
std::string m_zone ;
std::string m_language ;
std::string m_locator ;
/// Reads a CSV file.
static const char m_delim = ';';
public:
NavtexRecord()
: m_frequency(0.0)
@ -208,44 +81,33 @@ public:
char origin(void) const { return m_origin; };
const CoordinateT::Pair & coordinates() const { return m_coordinates; }
double frequency(void) const { return m_frequency; };
const std::string & country_code() const { return m_country_code; }
const std::string & country() const { return m_country; }
const std::string & name() const { return m_name; }
const std::string & callsign() const { return m_callsign; }
const std::string & locator() const { return m_locator; }
/// Example: Azores;AZR;490.0;J;CTH;Horta;38 32 N;28 38 W;II;PP
friend std::istream & operator>>( std::istream & istrm, NavtexRecord & rec )
{
std::string input_str ;
if( ! std::getline( istrm, input_str ) ) return istrm ;
std::stringstream str_strm( input_str );
if( read_until_delim( str_strm, rec.m_country )
&& read_until_delim( str_strm, rec.m_country_code )
&& read_until_delim( str_strm, rec.m_frequency )
&& read_until_delim( str_strm, rec.m_origin )
&& read_until_delim( str_strm, rec.m_callsign )
&& read_until_delim( str_strm, rec.m_name )
&& read_until_delim( str_strm, rec.m_coordinates.latitude() )
&& read_until_delim( str_strm, rec.m_coordinates.longitude() )
&& read_until_delim( str_strm, rec.m_zone )
&& read_until_delim( str_strm, rec.m_language )
if( read_until_delim( m_delim, str_strm, rec.m_country )
&& read_until_delim( m_delim, str_strm /* Country code */ )
&& read_until_delim( m_delim, str_strm, rec.m_frequency )
&& read_until_delim( m_delim, str_strm, rec.m_origin )
&& read_until_delim( m_delim, str_strm, rec.m_callsign )
&& read_until_delim( m_delim, str_strm, rec.m_name )
&& read_until_delim( m_delim, str_strm, rec.m_coordinates.latitude() )
&& read_until_delim( m_delim, str_strm, rec.m_coordinates.longitude() )
&& read_until_delim( m_delim, str_strm /* Zone */ )
&& read_until_delim( m_delim, str_strm /* Language */ )
&& ( rec.m_coordinates.latitude().is_lon() == false )
&& ( rec.m_coordinates.longitude().is_lon() == true )
)
{
char buf[64];
int ret = longlat2locator(
rec.m_coordinates.longitude().angle(),
rec.m_coordinates.latitude().angle(),
buf,
3 );
if( ret == RIG_OK ) {
rec.m_locator = buf ;
return istrm ;
}
return istrm ;
}
istrm.setstate(std::ios::eofbit);
@ -253,102 +115,198 @@ public:
}
};
class NavtexCatalog
/// Navtex catalog of stations is used when logging to ADIF file: It gives the station name, callsign etc...
class NavtexCatalog : public RecordLoader< NavtexCatalog >
{
// TODO: Consider a multimap<char, NavtexRecord>
typedef std::deque< NavtexRecord > CatalogType ;
CatalogType m_catalog ;
/// Frequency more or less 1 %: 485-494 kHz, 512-523 kHz etc...
static bool freq_close( double freqA, double freqB )
{
static const double freq_ratio = 1.1 ;
static const double freq_ratio = 1.01 ;
return ( freqA < freqB * freq_ratio ) || ( freqA * freq_ratio > freqB );
}
/// Tells if this is a reasonable Navtex frequency.
static bool freq_acceptable( double freq )
{
return freq_close( freq, 518.0 )
return freq_close( freq, 490.0 )
|| freq_close( freq, 518.0 )
|| freq_close( freq, 4209.5 );
}
typedef std::multimap< double, CatalogType::const_iterator > SolutionType ;
static const NavtexRecord & dflt_solution(void) {
static const NavtexRecord dfltNavtex ;
return dfltNavtex ;
void Clear() {
m_catalog.clear();
}
NavtexCatalog( const std::string & filnam )
{
LOG_INFO("Opening:%s", filnam.c_str());
std::ifstream ifs( filnam.c_str() );
if( !ifs )
{
std::string msg = "Cannot open:" + filnam ;
LOG_ERROR("%s",msg.c_str() );
throw std::runtime_error(msg);
}
for( ; ; )
{
NavtexRecord tmp ;
ifs >> tmp ;
if( !ifs) break ;
bool ReadRecord( std::istream & istrm ) {
NavtexRecord tmp ;
istrm >> tmp ;
if( istrm || istrm.eof() ) {
m_catalog.push_back( tmp );
return true ;
}
ifs.close();
return false ;
}
static const NavtexCatalog & inst() {
static const NavtexCatalog *ptr = NULL;
if( ptr == NULL ) ptr = new NavtexCatalog(progdefaults.NVTX_Catalog);
return *ptr ;
/// Minimal edit distance (Levenshtein) between the pattern and any token of the string.
static double DistToStationName( const std::string & msg, const std::string & pattern ) {
std::stringstream strm( msg );
/// Any big number is OK, if bigger than any string length.
double currDist = 1.7976931348623157e+308; // DBL_MAX ;
typedef std::istream_iterator<std::string> StrmIterStr ;
for( StrmIterStr itStrm( strm ); itStrm != StrmIterStr(); ++itStrm ) {
const std::string tmp = *itStrm ;
currDist = std::min( currDist, (double)levenshtein( tmp, pattern ) );
}
return currDist ;
}
public:
std::string base_filename() const
{
return "NAVTEX_Stations.csv";
}
const char * Description() const
{
return _("Navtex stations");
}
/// Usual frequencies are 490, 518 or 4209 kiloHertz.
static const NavtexRecord & Find(
const NavtexRecord * FindStation(
long long freq_ll,
char origin,
const CoordinateT::Pair & coo )
const std::string & maidenhead,
const std::string & msg)
{
SolutionType sol;
if( maidenhead.empty() ) return NULL;
if( m_catalog.empty() ) {
int nbRecs = LoadAndRegister();
static bool error_signaled = false ;
if( nbRecs <= 0 ) {
LOG_WARN("Error reading Navtex stations file");
if(error_signaled == false) {
fl_alert("Cannot read Navtex file %s", storage_filename().first.c_str() );
error_signaled = true ;
return NULL;
}
}
error_signaled = false ;
}
const CoordinateT::Pair coo( maidenhead );
/// Possible Navtex stations stored by closer first.
typedef std::multimap< double, CatalogType::const_iterator > SolutionType ;
SolutionType solDistKm;
double freq = freq_ll / 1000.0 ; // As kiloHertz in the data file.
bool okFreq = freq_acceptable( freq );
for( CatalogType::const_iterator it = inst().m_catalog.begin(), en = inst().m_catalog.end(); it != en ; ++it )
//LOG_INFO("Operator Maidenhead=%s lon=%lf lat=%lf okFreq=%d Origin=%c",
// maidenhead.c_str(), coo.longitude().angle(), coo.latitude().angle(), okFreq, origin );
for( CatalogType::const_iterator it = m_catalog.begin(), en = m_catalog.end(); it != en ; ++it )
{
/// The origin letters must be identical.
if( origin != it->origin() ) continue ;
/// The two frequencies must be close more or less 10%.
bool freqClose = freq_close( freq, it->frequency() );
if( okFreq && ! freqClose ) continue ;
/// Solutions are stored smallest distance first.
double dist = coo.distance( it->coordinates() );
sol.insert( SolutionType::value_type( dist, it ) );
solDistKm.insert( SolutionType::value_type( dist, it ) );
}
return sol.empty() ? dflt_solution() : *( sol.begin()->second );
}
static const NavtexRecord & Find(
long long freq_ll,
char origin,
const std::string & maidenhead )
{
double lon, lat ;
int res = locator2longlat( &lon, &lat, maidenhead.c_str() );
if( res != RIG_OK ) {
throw std::runtime_error("Cannot decode:" + maidenhead );
};
CoordinateT::Pair coo(
CoordinateT( lon, true ),
CoordinateT( lat, false ) );
return Find( freq_ll, origin, coo );
/// No station found.
if( solDistKm.empty() ) return NULL;
/// Only one station, no ambiguity.
SolutionType::iterator begSolKm = solDistKm.begin();
if( solDistKm.size() == 1 ) return & ( *begSolKm->second );
SolutionType solStrDist ;
// Maybe some station names appear but not others. This can be for example "Maltaradio", "Cullercoat", "Limnos" etc...
for( SolutionType::iterator itSolKm = begSolKm, endSolKm = solDistKm.end(); itSolKm != endSolKm; ++itSolKm ) {
std::stringstream strm ;
strm << itSolKm->second->coordinates();
// LOG_INFO("Name=%s Dist=%lf %s", itSolKm->second->name().c_str(), itSolKm->first, strm.str().c_str() );
// The message is in uppercase anyway, so no need to convert.
double str_dist = DistToStationName( msg, uppercase( itSolKm->second->name() ) );
solStrDist.insert( SolutionType::value_type( str_dist, itSolKm->second ) );
}
// There are at least two elements, so we can do this.
SolutionType::iterator begSolStr = solStrDist.begin();
SolutionType::iterator nxtSolStr = begSolStr;
++nxtSolStr ;
// The first message only contains a string very similar to a radio station.
if( (begSolStr->first < 2) && ( nxtSolStr->first > 2 ) ) {
//LOG_INFO("Levenshtein beg=%lf beg_name=%s next=%lf next_name=%s",
// begSolStr->first, begSolStr->second->name().c_str(),
// nxtSolStr->first, nxtSolStr->second->name().c_str() );
return & (*begSolStr->second) ;
}
// There are at least two elements, and more than one station name, or none of them,
// is contained in the message.
// Just returns the closest element.
return & ( *begSolKm->second );
// Now we could search for a coordinate in the message, and we will keep the station which is the closest
// to this coordinate. We wish to do that anyway in order to map things in KML.
// Possible formats are -(This is experimental):
// 67-04.0N 032-25.7E
// 47-29'30N 003-16'00W
// 6930.1N 01729.9E
// 48-21'45N 004-31'45W
// 58-37N 003-32W
// 314408N 341742E
// 42-42N 005-10E
// 54-02.3N 004-45.8E
// 55-20.76N 014-45.27E
// 55-31.1 N 012-44.7 E
// 5330.4N 01051.5W
// 43 45.0 N - 015 44.8 E
// 34-33.7N 012-28.7E
// 51 10.55 N - 001 51.02 E
// 51.21.67N 002.13.29E
// 73 NORTH 14 EAST
// 58-01.20N 005-27.08W
// 50.56N 007.00,5W
// 5630,1N- 00501,6E
// LAT. 41.06N - LONG 012.57E
// 42 40 01 N - 018 05 10 E
// 40 25 31N - 18 15 30E
// 40-32.2N 000-33.5E
// 58-01.2 NORTH 005-27.1 WEST
// 39-07,7N 026-39,2E
//
// ESTIMATED LIMIT OF ALL KNOWN ICE:
// 4649N 5411W TO 4530N 5400W TO
// 4400N 4900W TO 4545N 4530W TO
// 4715N 4530W TO 5000N 4715W TO
// 5530N 5115W TO 5700N 5545W.
//
}
}; // NavtexCatalog
/// Explanations here: http://www.arachnoid.com/BiQuadDesigner/index.html
class BiQuadraticFilter {
public:
enum Type {
@ -380,7 +338,7 @@ public:
reconfigure(aCenter_freq);
}
private:
// allow parameter change while running
/// Allows parameter change while running
void reconfigure(double cf) {
m_center_freq = cf;
// only used for peaking and shelving filters
@ -448,7 +406,7 @@ private:
m_a2 = (m_gain_abs + 1) - (m_gain_abs - 1) * cs - beta * sn;
break;
}
// prescale filter constants
/// Prescale filter constants
m_b0 /= m_a0;
m_b1 /= m_a0;
m_b2 /= m_a0;
@ -456,7 +414,7 @@ private:
m_a2 /= m_a0;
}
public:
// perform one filtering step
/// Perform one filtering step
double filter(double x) {
y = m_b0 * x + m_b1 * m_x1 + m_b2 * m_x2 - m_a1 * m_y1 - m_a2 * m_y2;
m_x2 = m_x1;
@ -557,7 +515,7 @@ public:
}
// http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive
// Counting set bits, Brian Kernighan's way
/// Counting set bits, Brian Kernighan's way
static bool check_bits(int v) {
int bc = 0;
while (v != 0) {
@ -569,6 +527,9 @@ public:
}
};
/// This is temporary, to manipulate a multi-line string.
static const char * new_line = "\n";
// Coordinates samples:
// 52-08.5N 003-18.0E
// 51-03.93N 001-09.17E
@ -611,7 +572,7 @@ public:
}
}
private:
/// Remove non-Ascii chars, replace new-line by semi-colon etc....
/// Remove non-Ascii chars, replace new-line by special character etc....
void cleanup() {
/// It would be possible to do the change in place, because the new string
/// it shorter than the current one, but at the expense of clarity.
@ -627,7 +588,7 @@ private:
break ;
default : if( chrSeen ) {
if( wasDelim ) {
newStr.push_back('~');
newStr.append(new_line);
} else if( wasSpace ) {
newStr.push_back(' ');
}
@ -722,75 +683,87 @@ public:
void display( const std::string & alt_string ) {
std::string::operator=( alt_string );
cleanup();
long long currFreq = wf->rfcarrier();
if( ! progdefaults.NVTX_AdifLog && ! progdefaults.NVTX_KmlLog ) {
return ;
}
const NavtexRecord * ptrNavRec = NavtexCatalog::InstCatalog().FindStation(currFreq, m_origin, progdefaults.myLocator, *this );
if( ptrNavRec != NULL ) {
LOG_INFO("Locator=%s Origin=%c freq=%" PRId64 " name=%s lon=%lf lat=%lf",
progdefaults.myLocator.c_str(),
m_origin,
currFreq,
ptrNavRec->name().c_str(),
ptrNavRec->coordinates().longitude().angle(),
ptrNavRec->coordinates().latitude().angle() );
} else {
LOG_INFO("Locator=%s Origin=%c freq=%" PRId64 " Navtex station not found",
progdefaults.myLocator.c_str(),
m_origin,
currFreq );
}
if( progdefaults.NVTX_AdifLog ) {
/// For updating the logbook with received messages.
cQsoRec qso_rec ;
QsoHelper qso(MODE_NAVTEX);
long long currFreq = wf->rfcarrier();
if( ! progdefaults.myLocator.empty() ) {
const NavtexRecord & refStat = NavtexCatalog::Find(currFreq, m_origin, progdefaults.myLocator );
LOG_INFO("name=%s lon=%lf lat=%lf",
refStat.name().c_str(),
refStat.coordinates().longitude().angle(),
refStat.coordinates().latitude().angle() );
qso_rec.putField(QTH, refStat.country().c_str() );
qso_rec.putField(CALL, refStat.callsign().c_str() );
qso_rec.putField(COUNTRY, refStat.country().c_str() );
qso_rec.putField(GRIDSQUARE, refStat.locator().c_str() );
qso_rec.putField(NAME, refStat.name().c_str() );
if( ptrNavRec ) {
qso.Push(QTH, ptrNavRec->country() );
qso.Push(CALL, ptrNavRec->callsign() );
qso.Push(COUNTRY, ptrNavRec->country() );
qso.Push(GRIDSQUARE, ptrNavRec->coordinates().locator() );
qso.Push(NAME, ptrNavRec->name() );
/// If the header is clean, the message type is removed from the string.
// In this context, this field cannot be used.
qso_rec.putField(XCHG1, msg_type() );
char numberBuf[32];
sprintf( numberBuf, "%d", m_number );
qso_rec.putField(SRX, numberBuf );
qso.Push(XCHG1, msg_type() );
qso.Push(SRX, strformat( "%d", m_number ) );
} else {
std::string tmpNam("Station_");
tmpNam += m_origin ;
qso_rec.putField(NAME, tmpNam.c_str() );
qso.Push(NAME, std::string("Station_") + m_origin );
}
qso_rec.setDateTime(true);
qso_rec.setDateTime(false);
qso_rec.setFrequency( currFreq );
qso_rec.putField(MODE, mode_info[MODE_NAVTEX].adif_name );
// Sequence of Chars and line-breaks, ASCII CR (code 13) + ASCII LF (code 10)
qso.Push(NOTES, strreplace( *this, new_line, ADIF_EOL ) );
}
// m_qso_rec.putField(QTH, inpQth_log->value());
// m_qso_rec.putField(STATE, inpState_log->value());
// m_qso_rec.putField(VE_PROV, inpVE_Prov_log->value());
// m_qso_rec.putField(QSLRDATE, inpQSLrcvddate_log->value());
// m_qso_rec.putField(QSLSDATE, inpQSLsentdate_log->value());
// m_qso_rec.putField(RST_RCVD, inpRstR_log->value ());
// m_qso_rec.putField(RST_SENT, inpRstS_log->value ());
// m_qso_rec.putField(IOTA, inpIOTA_log->value());
// m_qso_rec.putField(DXCC, inpDXCC_log->value());
// m_qso_rec.putField(CONT, inpCONT_log->value());
// m_qso_rec.putField(CQZ, inpCQZ_log->value());
// m_qso_rec.putField(ITUZ, inpITUZ_log->value());
// m_qso_rec.putField(TX_PWR, inpTX_pwr_log->value());
// Adds a placemark to the navtex KML file.
if( progdefaults.NVTX_KmlLog ) {
if( ptrNavRec ) {
KmlServer::CustomDataT custData ;
custData.Push( "Callsign", ptrNavRec->callsign() );
custData.Push( "Country", ptrNavRec->country() );
custData.Push( "Locator", ptrNavRec->coordinates().locator() );
custData.Push( "Message number", m_number );
custData.Push( "Frequency", currFreq );
qso_rec.putField(NOTES, c_str() );
custData.Push( "Mode", mode_info[MODE_NAVTEX].adif_name );
custData.Push( "Message", *this );
qsodb.qsoNewRec (&qso_rec);
qsodb.isdirty(0);
KmlServer::GetInstance()->Broadcast(
"Navtex",
0,
ptrNavRec->coordinates(),
0,
ptrNavRec->name(),
"navtex_station",
substr( 0, 20 ) + "...",
custData );
}
loadBrowser(true);
adifFile.writeLog (logbook_filename.c_str(), &qsodb);
LOG_INFO( _("Updating log book %s"), logbook_filename.c_str() );
// TODO: Parse the message to extract coordinates.
}
} // display
}; // ccir_message
static const double deviation_f = 90.0;
static const int deviation_f = 90;
static const double dflt_center_freq = 1000.0 ;
class navtex ;
/// Implements PIMPL idiom.
class navtex_implementation {
enum State {
@ -812,7 +785,7 @@ class navtex_implementation {
int m_message_counter ;
static const size_t m_tx_block_len = 1024 ;
// Between -1 and 1.
/// Between -1 and 1.
double m_tx_buf[m_tx_block_len];
size_t m_tx_counter ;
@ -826,13 +799,13 @@ class navtex_implementation {
CCIR476 m_ccir476;
typedef std::list<int> sync_chrs_type ;
sync_chrs_type m_sync_chrs;
ccir_message m_curr_msg ;
sync_chrs_type m_sync_chrs;
ccir_message m_curr_msg ;
int m_c1, m_c2, m_c3;
static const int m_zero_crossings_divisor = 4;
std::vector<int> m_zero_crossings ;
long m_zero_crossing_count;
static const int m_zero_crossings_divisor = 4;
std::vector<int> m_zero_crossings ;
long m_zero_crossing_count;
double m_message_time ;
double m_signal_accumulator ;
double m_mark_f, m_space_f;
@ -857,7 +830,6 @@ class navtex_implementation {
int m_bit_count;
int m_code_bits;
bool m_shift ;
bool m_inverse ;
bool m_pulse_edge_event;
int m_error_count;
int m_valid_count;
@ -899,7 +871,6 @@ public:
m_pulse_edge_event = false;
m_error_count = 0;
m_valid_count = 0;
m_inverse = false;
m_sample_count = 0;
m_next_event_count = 0;
m_zero_crossing_count = 0;
@ -942,6 +913,7 @@ private:
}
}
/// The parameter is appended at the message end.
void flush_message(const std::string & extra_info)
{
if( m_header_found )
@ -951,12 +923,13 @@ private:
}
else
{
display_message( m_curr_msg, "<Lost header>:" + m_curr_msg + extra_info );
display_message( m_curr_msg, "[Lost header]:" + m_curr_msg + extra_info );
}
m_curr_msg.reset_msg();
m_message_time = m_time_sec;
}
/// Checks that we have no waited too long, and if so, flushes the message with a specific terminator.
void process_timeout() {
/// No messaging in SitorB
if ( m_only_sitor_b ) {
@ -985,14 +958,14 @@ private:
/// Maybe the message was already valid.
if( m_header_found )
{
display_message( msg_cut.second, msg_cut.second + ":<Lost trailer>" );
display_message( msg_cut.second, msg_cut.second + ":[Lost trailer]" );
}
else
{
/// Maybe only non-significant chars.
if( ! msg_cut.second.empty() )
{
display_message( msg_cut.second, "<Lost header>:" + msg_cut.second + ":<Lost trailer>" );
display_message( msg_cut.second, "[Lost header]:" + msg_cut.second + ":[Lost trailer]" );
}
}
m_header_found = true;
@ -1033,11 +1006,11 @@ private:
chr = code;
} else if (CCIR476::check_bits(m_c1)) {
chr = m_c1;
LOG_INFO( _("FEC replacement: %x -> %x"), code, m_c1);
LOG_DEBUG("FEC replacement: %x -> %x", code, m_c1);
}
}
if (chr == -1) {
LOG_INFO(_("Fail all options: %x %x"), code, m_c1);
LOG_DEBUG("Fail all options: %x %x", code, m_c1);
} else {
switch (chr) {
case code_rep:
@ -1278,7 +1251,7 @@ public:
// flag the center of signal pulses
m_pulse_edge_event = m_sample_count >= m_next_event_count;
if (m_pulse_edge_event) {
m_averaged_mark_state = (m_signal_accumulator > 0) ^ m_inverse;
m_averaged_mark_state = (m_signal_accumulator > 0) ^ m_ptr_navtex->get_reverse();
m_signal_accumulator = 0;
// set new timeout value, include zero crossing correction
m_next_event_count = m_sample_count + m_bit_sample_count + (int) (m_sync_delta + 0.5);
@ -1349,7 +1322,7 @@ public:
m_bit_count++;
if (m_bit_count == 7) {
if (m_error_count > 0) {
LOG_INFO(_("Error count: %d"), m_error_count);
LOG_DEBUG("Error count: %d", m_error_count);
}
if (process_char(m_code_bits)) {
if (m_error_count > 0) {
@ -1358,7 +1331,7 @@ public:
} else {
m_error_count++;
if (m_error_count > 2) {
LOG_INFO(_("Returning to sync"));
LOG_DEBUG("Returning to sync");
set_state(SYNC_SETUP);
}
}
@ -1388,8 +1361,13 @@ private:
void display_message( ccir_message & ccir_msg, const std::string & alt_string ) {
if( ccir_msg.size() >= (size_t)progdefaults.NVTX_MinSizLoggedMsg )
{
ccir_msg.display(alt_string);
put_received_message( alt_string );
try
{
ccir_msg.display(alt_string);
put_received_message( alt_string );
} catch( const std::exception & exc ) {
LOG_WARN("Caught %s", exc.what() );
}
}
else
{
@ -1412,7 +1390,7 @@ public:
{
guard_lock g( m_sync_rx.mtxp() );
LOG_INFO(_("delay=%f"), max_seconds );
LOG_DEBUG("Delay=%f", max_seconds );
if( m_received_messages.empty() )
{
if( ! m_sync_rx.wait(max_seconds) ) return "Timeout";
@ -1448,8 +1426,7 @@ public:
return res;
}
// Note path std::string can contain null characters.
// TODO: Beware of the extra copy constructor.
/// Note path std::string can contain null characters. TODO: Beware of the extra copy constructor.
std::string encode( const std::string & str ) const
{
std::string res ;
@ -1468,7 +1445,7 @@ public:
}
}
// Input value must be between -1 and 1
/// Input value must be between -1 and 1
void add_sample( double sam )
{
m_tx_buf[ m_tx_counter++ ] = sam ;
@ -1610,6 +1587,7 @@ public:
}; // navtex_implementation
#ifdef NAVTEX_COMMAND_LINE
/// For testing purpose, this file can be compiled and run separately as a command-line program.
int main(int n, const char ** v )
{
printf("%s\n", v[1] );
@ -1637,10 +1615,11 @@ int main(int n, const char ** v )
navtex::navtex (trx_mode md)
{
modem::cap |= CAP_AFC ;
modem::cap |= CAP_AFC | CAP_REV;
navtex::mode = md;
modem::samplerate = 11025;
modem::bandwidth = 2 * deviation_f ;
modem::reverse = false ;
bool only_sitor_b = false ;
switch( md )
{

Wyświetl plik

@ -55,12 +55,12 @@ LOG_FILE_SOURCE(debug::LOG_RIGCONTROL);
using namespace std;
Cserial rigio;
static pthread_mutex_t rigCAT_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t *rigCAT_thread = 0;
static pthread_mutex_t rigCAT_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t rigCAT_thread;
static bool rigCAT_exit = false;
static bool rigCAT_open = false;
static bool rigCAT_bypass = false;
static bool rigCAT_exit = false;
static bool rigCAT_open = false;
static bool rigCAT_bypass = false;
static string sRigWidth = "";
static string sRigMode = "";
@ -93,6 +93,8 @@ bool sendCommand (string s, int retnbr)
if (retval <= 0)
LOG_VERBOSE("Write error %d", retval);
if (retnbr == 0) return true;
memset(replybuff, 0, RXBUFFSIZE + 1);
numread = 0;
MilliSleep( readafter );
@ -393,7 +395,7 @@ long long rigCAT_getfreq(int retries, bool &failed)
f = fm_freqdata(rTemp.data, pData);
if ( f >= rTemp.data.min && f <= rTemp.data.max)
return f;
LOG_VERBOSE("freq: %lld", f);
LOG_VERBOSE("freq: %" PRId64, f);
retry_get_freq: ;
}
}
@ -405,6 +407,10 @@ retry_get_freq: ;
void rigCAT_setfreq(long long f)
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
string strCmd;
@ -444,24 +450,22 @@ void rigCAT_setfreq(long long f)
if (preply->SYMBOL == modeCmd.ok) {
XMLIOS rTemp = *preply;
// send the command
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, rTemp.size);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, rTemp.size)) return;
}
return;
}
preply++;
}
} else {
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, 0);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, 0)) return;
}
}
if (progdefaults.RigCatVSP == false)
@ -470,6 +474,10 @@ void rigCAT_setfreq(long long f)
string rigCAT_getmode()
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return "";
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
list<MODE>::iterator mode;
@ -568,6 +576,10 @@ retry_get_mode: ;
void rigCAT_setmode(const string& md)
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
string strCmd;
@ -616,24 +628,22 @@ void rigCAT_setmode(const string& md)
if (preply->SYMBOL == modeCmd.ok) {
XMLIOS rTemp = *preply;
// send the command
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, rTemp.size);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, rTemp.size)) return;
}
return;
}
preply++;
}
} else {
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, 0);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, 0)) return;
}
}
if (progdefaults.RigCatVSP == false)
@ -642,6 +652,10 @@ void rigCAT_setmode(const string& md)
string rigCAT_getwidth()
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return "";
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
list<BW>::iterator bw;
@ -740,6 +754,10 @@ retry_get_width: ;
void rigCAT_setwidth(const string& w)
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
string strCmd;
@ -792,23 +810,21 @@ void rigCAT_setwidth(const string& w)
if (preply->SYMBOL == modeCmd.ok) {
XMLIOS rTemp = *preply;
// send the command
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, rTemp.size);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, rTemp.size)) return;
}
}
preply++;
}
} else {
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, 0);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, 0)) return;
}
}
LOG_VERBOSE("Retries failed");
@ -816,6 +832,10 @@ void rigCAT_setwidth(const string& w)
void rigCAT_pttON()
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
string strCmd;
@ -845,24 +865,22 @@ void rigCAT_pttON()
if (preply->SYMBOL == modeCmd.ok) {
XMLIOS rTemp = *preply;
// send the command
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, rTemp.size);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, rTemp.size)) return;
}
return;
}
preply++;
}
} else {
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, 0);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, 0)) return;
}
}
LOG_VERBOSE("Retries failed");
@ -870,6 +888,10 @@ void rigCAT_pttON()
void rigCAT_pttOFF()
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
string strCmd;
@ -898,30 +920,33 @@ void rigCAT_pttOFF()
if (preply->SYMBOL == modeCmd.ok) {
XMLIOS rTemp = *preply;
// send the command
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, rTemp.size);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, rTemp.size)) return;
}
return;
}
preply++;
}
} else {
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, 0);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, 0)) return;
}
}
LOG_VERBOSE("Retries failed");
}
void rigCAT_sendINIT(const string& icmd){
void rigCAT_sendINIT(const string& icmd)
{
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
}
XMLIOS modeCmd;
list<XMLIOS>::iterator itrCmd;
string strCmd;
@ -950,24 +975,22 @@ void rigCAT_sendINIT(const string& icmd){
if (preply->SYMBOL == modeCmd.ok) {
XMLIOS rTemp = *preply;
// send the command
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, rTemp.size);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, rTemp.size)) return;
}
return;
}
preply++;
}
} else {
bool ok = false;
for (int n = 0; n < progdefaults.RigCatRetries; n++) {
pthread_mutex_lock(&rigCAT_mutex);
ok = sendCommand(strCmd, 0);
pthread_mutex_unlock(&rigCAT_mutex);
if (ok) return;
MilliSleep(50);
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_exit) return;
if (sendCommand(strCmd, 0)) return;
}
}
LOG_VERBOSE("Retries failed");
@ -1115,23 +1138,17 @@ echo : %c\n",
nonCATrig = false;
init_Xml_RigDialog();
}
} else {
} else { // rigcat thread just being used for the human interface
nonCATrig = true;
init_NoRig_RigDialog();
llFreq = 0;
rigCAT_bypass = false;
rigCAT_exit = false;
rigCAT_thread = new pthread_t;
if (pthread_create(rigCAT_thread, NULL, rigCAT_loop, NULL) < 0) {
LOG_ERROR("nonCATrig pthread_create failed");
if (pthread_create(&rigCAT_thread, NULL, rigCAT_loop, NULL) < 0) {
LOG_ERROR("%s", "pthread_create failed");
rigio.ClosePort();
delete rigCAT_thread;
rigCAT_thread = 0;
return false;
}
LOG_VERBOSE("New thread for nonCATrig %p", rigCAT_thread);
rigCAT_open = true;
return true;
@ -1139,18 +1156,12 @@ echo : %c\n",
llFreq = 0;
rigCAT_bypass = false;
rigCAT_exit = false;
rigCAT_thread = new pthread_t;
if (pthread_create(rigCAT_thread, NULL, rigCAT_loop, NULL) < 0) {
LOG_ERROR("rigCAT pthread_create failed");
if (pthread_create(&rigCAT_thread, NULL, rigCAT_loop, NULL) < 0) {
LOG_ERROR("%s", "pthread_create failed");
rigio.ClosePort();
delete rigCAT_thread;
rigCAT_thread = 0;
return false;
}
LOG_VERBOSE("New rigCAT thread %p", rigCAT_thread);
rigCAT_open = true;
@ -1159,27 +1170,27 @@ echo : %c\n",
void rigCAT_close(void)
{
if (rigCAT_open == false || rigCAT_exit)
if ( rigCAT_open == false || rigCAT_exit == true)
return;
if (rigCAT_thread == 0) return;
{
guard_lock ser_guard( &rigCAT_mutex );
rigCAT_exit = true;
}
LOG_INFO("%s", "Waiting for rigCAT_thread");
pthread_join(rigCAT_thread, NULL);
rigCAT_sendINIT("CLOSE");
pthread_mutex_lock(&rigCAT_mutex);
rigCAT_exit = true;
pthread_mutex_unlock(&rigCAT_mutex);
rigio.ClosePort();
if (!rigCAT_thread) return;
pthread_join(*rigCAT_thread, NULL);
LOG_VERBOSE("Deleting thread %p", rigCAT_thread);
delete rigCAT_thread;
rigCAT_thread = 0;
wf->USB(true);
rigCAT_open = false;
rigCAT_exit = false;
rigCAT_bypass = false;
wf->USB(true);
}
bool rigCAT_active(void)
@ -1238,25 +1249,22 @@ static void *rigCAT_loop(void *args)
bool failed;
for (;;) {
MilliSleep(200);
MilliSleep(100);
if (rigCAT_exit == true)
break;
{
guard_lock ser_guard( &rigCAT_mutex );
if (rigCAT_bypass == true)
continue;
if (rigCAT_exit == true) {
LOG_INFO("%s", "Exit rigCAT loop");
return NULL;
}
pthread_mutex_lock(&rigCAT_mutex);
freq = rigCAT_getfreq(progdefaults.RigCatRetries, failed);
pthread_mutex_unlock(&rigCAT_mutex);
if (rigCAT_bypass == true)
continue;
pthread_mutex_lock(&rigCAT_mutex);
sWidth = rigCAT_getwidth();
pthread_mutex_unlock(&rigCAT_mutex);
}
pthread_mutex_lock(&rigCAT_mutex);
sMode = rigCAT_getmode();
pthread_mutex_unlock(&rigCAT_mutex);
freq = rigCAT_getfreq(progdefaults.RigCatRetries, failed);
if ((freq > 0) && (freq != llFreq)) {
llFreq = freq;
@ -1267,11 +1275,14 @@ static void *rigCAT_loop(void *args)
if (freq > 0)
dl_fldigi::hbtint::rig_set_freq(freq);
sWidth = rigCAT_getwidth();
if (sWidth.size() && sWidth != sRigWidth) {
sRigWidth = sWidth;
show_bw(sWidth);
}
sMode = rigCAT_getmode();
if (sMode.size() && sMode != sRigMode) {
sRigMode = sMode;
if (ModeIsLSB(sMode))
@ -1285,17 +1296,6 @@ static void *rigCAT_loop(void *args)
dl_fldigi::hbtint::rig_set_mode(sMode);
}
wf->USB(true);
pthread_mutex_lock(&rigCAT_mutex);
LOG_DEBUG("Exiting rigCAT loop, closing serial port");
rigio.ClosePort();
pthread_mutex_unlock(&rigCAT_mutex);
rigCAT_open = false;
rigCAT_exit = false;
rigCAT_bypass = false;
return NULL;
}

Plik diff jest za duży Load Diff

Some files were not shown because too many files have changed in this diff Show More