kopia lustrzana https://github.com/jamescoxon/dl-fldigi
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.cxxpull/1/head
commit
1d7d18fabd
86
ChangeLog
86
ChangeLog
|
@ -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
|
||||
|
||||
|
|
10
configure.ac
10
configure.ac
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -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
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -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.
|
@ -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
|
||||
|
|
24
m4/xmlrpc.m4
24
m4/xmlrpc.m4
|
@ -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"])
|
||||
])
|
3855
po/dl-fldigi.pot
3855
po/dl-fldigi.pot
Plik diff jest za duży
Load Diff
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}} {}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
*/
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
|
||||
#define TWOPI (2.0 * M_PI)
|
||||
|
||||
class modem : public morse {
|
||||
class modem {
|
||||
protected:
|
||||
cMorse morse;
|
||||
trx_mode mode;
|
||||
SoundBase *scard;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 (;;) {
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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];
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
|
|
@ -128,7 +128,6 @@ private:
|
|||
int rtty_bits;
|
||||
RTTY_PARITY rtty_parity;
|
||||
int rtty_stop;
|
||||
bool rtty_reverse;
|
||||
bool rtty_msbfirst;
|
||||
|
||||
int bflen;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("");
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>");
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "debug.h"
|
||||
#include "icons.h"
|
||||
#include "qrunner.h"
|
||||
#include "timeops.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
130
src/main.cxx
130
src/main.cxx
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
Ładowanie…
Reference in New Issue