Merge branch 'release-2.3.0' into develop

This commit is contained in:
Bill Somerville 2020-11-27 01:15:36 +00:00
commit 62174cc76b
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
17 changed files with 1027 additions and 826 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 3.9 FATAL_ERROR)
cmake_minimum_required (VERSION 3.7.2 FATAL_ERROR)
if (APPLE)
#
@ -46,9 +46,9 @@ endif ()
project (wsjtx
VERSION 2.3.0.0
DESCRIPTION "WSJT-X: Digital Modes for Weak Signal Communications in Amateur Radio"
LANGUAGES C CXX Fortran
)
set (PROJECT_DESCRIPTION "WSJT-X: Digital Modes for Weak Signal Communications in Amateur Radio")
#
# Local CMake modules and support files
@ -838,7 +838,7 @@ endif ()
if (WIN32)
set (Boost_USE_STATIC_LIBS OFF)
endif ()
find_package (Boost 1.63 REQUIRED COMPONENTS log_setup log)
find_package (Boost 1.62 REQUIRED COMPONENTS log_setup log)
#
# OpenMP
@ -1053,7 +1053,7 @@ query_qmake (QT_HOST_DATA QT_DATA_DIR)
set (QT_MKSPECS_DIR ${QT_DATA_DIR}/mkspecs)
# project definitions
add_definitions (-DQT5 -DCMAKE_BUILD -DBIGSYM=1)
add_definitions (-DQT5 -DCMAKE_BUILD -DBIGSYM=1 -DBOOST_ALL_DYN_LINK)
if (CMAKE_HOST_UNIX)
add_definitions (-DUNIX)
elseif (CMAKE_HOST_WIN32)
@ -1309,7 +1309,7 @@ target_link_libraries (qcp Qt5::Widgets Qt5::PrintSupport)
# build a library of package Qt functionality
add_library (wsjt_qt STATIC ${wsjt_qt_CXXSRCS} ${wsjt_qt_GENUISRCS} ${GENAXSRCS})
# set wsjtx_udp exports to static variants
target_compile_definitions (wsjt_qt PUBLIC UDP_STATIC_DEFINE BOOST_LOG_DYN_LINK)
target_compile_definitions (wsjt_qt PUBLIC UDP_STATIC_DEFINE)
target_link_libraries (wsjt_qt Boost::log qcp Qt5::Widgets Qt5::Network Qt5::Sql)
target_include_directories (wsjt_qt BEFORE PRIVATE ${hamlib_INCLUDE_DIRS})
if (WIN32)
@ -1818,7 +1818,7 @@ set (CPACK_MONOLITHIC_INSTALL 1)
set (CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
set (CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set (CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set (CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set (CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}${BUILD_TYPE_REVISION}")
if (WIN32)
set (CPACK_GENERATOR "NSIS")
@ -1852,11 +1852,11 @@ else ()
endif ()
set (CPACK_DEBIAN_PACKAGE_HOMEPAGE "${PROJECT_HOMEPAGE}")
set (CPACK_DEBIAN_PACKAGE_DEPENDS "libgfortran5 (>=8.3) | libgfortran4 (>=7.3) | libgfortran3 (>=6.3), libfftw3-single3 (>=3.3), libgomp1 (>=6), libqt5serialport5 (>=5.7), libqt5multimedia5-plugins (>=5.7), libqt5widgets5 (>=5.7), libqt5network5 (>=5.7), libqt5printsupport5 (>=5.7), libqt5sql5-sqlite (>=5.7), libusb-1.0-0 (>=1.0.21), libboost-log1.65.1 (>=1.62.0) | libboost-log1.65.1 (>=1.65.1) | libboost-log1.67.0 (>=1.67.0) | libboost-log1.71.0 (>=1.71.0)")
set (CPACK_DEBIAN_PACKAGE_DEPENDS "libgfortran5 (>=8.3) | libgfortran4 (>=7.3) | libgfortran3 (>=6.3), libfftw3-single3 (>=3.3), libgomp1 (>=6), libqt5serialport5 (>=5.7), libqt5multimedia5-plugins (>=5.7), libqt5widgets5 (>=5.7), libqt5network5 (>=5.7), libqt5printsupport5 (>=5.7), libqt5sql5-sqlite (>=5.7), libusb-1.0-0 (>=1.0.21), libboost-log1.62.0 (>=1.62.0) | libboost-log1.65.1 (>=1.65.1) | libboost-log1.67.0 (>=1.67.0) | libboost-log1.71.0 (>=1.71.0) | libboost-log1.74.0 (>=1.74.0)")
set (CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set (CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
set (CPACK_RPM_PACKAGE_REQUIRES "qt5-qtbase >= 5.9, qt5-qtserialport >= 5.9, qt5-qtmultimedia >= 5.9, qt5-qtsvg >= 5.9, libusbx >= 1.0.22, libgfortran >= 7, libgomp >= 7, fftw-libs-single >= 3.3")
set (CPACK_RPM_PACKAGE_REQUIRES "qt5-qtbase >= 5.9, qt5-qtserialport >= 5.9, qt5-qtmultimedia >= 5.9, qt5-qtsvg >= 5.9, libusbx >= 1.0.22, libgfortran >= 7, libgomp >= 7, fftw-libs-single >= 3.3, boost-log >= 1.62")
set (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /usr/share/pixmaps /usr/share/applications /usr/share/man /usr/share/man1)
configure_file ("${PROJECT_SOURCE_DIR}/CMakeCPackOptions.cmake.in"

View File

@ -1076,9 +1076,6 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
});
lotw_users_.set_local_file_path (writeable_data_dir_.absoluteFilePath ("lotw-user-activity.csv"));
// load the dictionary if it exists, fetch and load if it doesn't
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text ());
//
// validation
//
@ -1239,6 +1236,19 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
audio_output_device_ = next_audio_output_device_;
audio_output_channel_ = next_audio_output_channel_;
bool fetch_if_needed {false};
for (auto const& item : decode_highlighing_model_.items ())
{
if (DecodeHighlightingModel::Highlight::LotW == item.type_)
{
fetch_if_needed = item.enabled_;
break;
}
}
// load the LoTW users dictionary if it exists, fetch and load if it
// doesn't and we need it
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text (), fetch_if_needed);
transceiver_thread_ = new QThread {this};
transceiver_thread_->start ();
}

View File

@ -1,22 +1,41 @@
Notes on WSJT-X Installation for Mac OS X
-----------------------------------------
Important: If you are using the new Mac with the M1 chip then please read
the section marked: BEGIN M1. Otherwise BEGIN INTEL applies.
If you have already downloaded a previous version of WSJT-X then I suggest
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
before proceeding.
If you have installed a previous version of WSJT-X before, then there is no
need to change anything on your system so proceed to NEXT. If you upgrade macOS
it is possible that you might need to re-install the sysctl.conf file.
I recommend that you follow the installation instructions especially if you
are moving from v2.2 to v2.3 of WSJT-X or you have upgraded macOS.
BEGIN:
BEGIN M1:
Double-click on the wsjtx-...-Darwin.dmg file you have downloaded from K1JT's web-site.
Now open a Terminal window by going to Applications->Utilities and clicking on Terminal.
There are two system variables that must be set manually since the M1 Macs do not recognise
automatic parameter settings by means of the sysctl.conf file present in the download.
Type these commands - you will be asked for your password which will not be echoed:
sudo sysctl -w kern.sysv.shmmax=104857600
sudo sysctl -w kern.sysv.shmall=25600
It is important to note that these parameter settings will not survive a reboot. If you
need to reboot your Mac, then these commands must be re-entered. Now proceed to NEXT.
BEGIN INTEL:
Double-click on the wsjtx-...-Darwin.dmg file you have downloaded from K1JT's web-site.
Now open a Terminal window by going to Applications->Utilities and clicking on Terminal.
Along with this ReadMe file there is a file: sysctl.conf which must be copied to a
system area by typing this line in the Terminal window and then pressing the Return key.
system area by typing these two lines in the Terminal window and then pressing the Return key
after each line.
sudo cp /Volumes/WSJT-X/sysctl.conf /etc
@ -28,7 +47,7 @@ change has been made by typing:
sysctl -a | grep sysv.shm
If shmmax is not shown as 14680064 then contact me since WSJT-X will fail to load with
If shmmax is not shown as 104857600 then contact me since WSJT-X will fail to load with
an error message: "Unable to create shared memory segment".
You can now close the Terminal window. It will not be necessary to repeat this procedure
@ -77,23 +96,20 @@ Please email me if you have problems.
--- John G4KLA (g4kla@rmnjmn.co.uk)
Addendum: Information about sysctl.conf and multiple instances of wsjt-x.
Addendum: Information about sysctl.conf and multiple instances of WSJT-X.
WSJT-X makes use of a block of memory which is shared between different parts of
the code. The normal allocation of shared memory on a Mac is insufficient and this
has to be increased. The sysctl.conf file is used for this purpose. You can
use a Mac editor to examine sysctl.conf. (Do not use another editor - the file
would be probably be corrupted.)
would probably be corrupted.)
There are two important parameters that you need to consider. shmmax determines the
amount of shared memory that must be allocated for WSJT-X to operate. This is 14680064 (14MB)
and this is defined in the sysctl.conf file and should not be changed.
It is possible to run two instances of WSJT-X simultaneously. See "Section 16.2
Frequently asked Questions" in the User Guide. If you wish to run more than two instances
simultaneously, the sysctl.conf file needs to be modified. Please email me with your
requirements and I will provide a replacement sysctl.conf to suit.
It is possible to run more than one instance of WSJT-X simultaneously. See
"Section 16.2 Frequently asked Questions" in the User Guide. The second important parameter
shmall=17920 determines how many instances are permitted. This is calculated as:
(shmall x 4096/14680064) = 5.
The sysctl.conf file is configured to permit up to 5 instances of wsjtx to run simultaneously.
If this limitation is acceptable then you can continue to install the sysctl.conf file without making any
alterations. Otherwise you must edit the file to increase shmall according to this calculation.
If two instances of WSJT-X are running, it is likely that you might need additional
audio devices, from two rigs for example. Visit Audio MIDI Setup and create an Aggregate Device
which will allow you to specific more than one interface. I recommend you consult Apple's guide
on combining multiple audio interfaces which is at https://support.apple.com/en-us/HT202000.

21
INSTALL
View File

@ -23,10 +23,10 @@ Building from Source
====================
On Linux systems some of the prerequisite libraries are available in
the mainstream distribution repositories. They are Qt v5 and FFTW v3.
For MS Windows see the section "Building from Source on MS Windows"
below. For Apple Mac see the section "Building from Source on Apple
Mac".
the mainstream distribution repositories. They are Qt v5, FFTW v3, and
the Boost C++ libraries. For MS Windows see the section "Building
from Source on MS Windows" below. For Apple Mac see the section
"Building from Source on Apple Mac".
Qt v5, preferably v5.9 or later is required to build WSJT-X.
@ -43,12 +43,13 @@ the libfftw library development package. Normally installing the
library development package pulls in all the FFTW v3 libraries
including the single precision variant.
The Hamlib library optionally requires the libusb-1.0-1 library, if
the development version (libusb-1.0-0-dev) is available Hamlib will
configure its custom USB device back end drivers. Most rigs do not
require this so normally you can choose not to install libusb-1.0-dev
but if you have a SoftRock USB or similar SDR that uses a custom USB
interface then it is required.
The Hamlib library requires the readline development package and
optionally requires the libusb-1.0-1 library, if the development
version (libusb-1.0-0-dev) is available Hamlib will configure its
custom USB device back end drivers. Most rigs do not require this so
normally you can choose not to install libusb-1.0-dev but if you have
a SoftRock USB or similar SDR that uses a custom USB interface then it
is required.
The Hamlib library is required. Currently WSJT-X needs to be built
using a forked version of the Hamlib git master. This fork contains

View File

@ -22,7 +22,7 @@ namespace Radio
QRegularExpression valid_callsign_regexp {R"(\d[[:alpha:]]|[[:alpha:]]\d)"};
// standard callsign
QRegularExpression strict_standard_callsign_re {R"(^([A-Z][0-9]?|[0-9][A-Z])[0-9][A-Z]{0,3}$)"};
QRegularExpression strict_standard_callsign_re {R"(^([A-Z][0-9]?|[0-9A-Z][A-Z])[0-9][A-Z]{0,3}$)"};
// suffixes that are often used and should not be interpreted as a
// DXCC Entity prefix used as a suffix

View File

@ -259,53 +259,53 @@ HamlibTransceiver::HamlibTransceiver (logger_type * logger,
// rig_->state.obj = this;
if (!is_dummy_)
//
// user defined Hamlib settings
//
auto settings_file_name = QStandardPaths::locate (QStandardPaths::AppConfigLocation
, "hamlib_settings.json");
if (!settings_file_name.isEmpty ())
{
//
// user defined Hamlib settings
//
auto settings_file_name = QStandardPaths::locate (QStandardPaths::AppConfigLocation
, "hamlib_settings.json");
if (!settings_file_name.isEmpty ())
QFile settings_file {settings_file_name};
qDebug () << "Using Hamlib settings file:" << settings_file_name;
if (settings_file.open (QFile::ReadOnly))
{
QFile settings_file {settings_file_name};
qDebug () << "Using Hamlib settings file:" << settings_file_name;
if (settings_file.open (QFile::ReadOnly))
QJsonParseError status;
auto settings_doc = QJsonDocument::fromJson (settings_file.readAll (), &status);
if (status.error)
{
QJsonParseError status;
auto settings_doc = QJsonDocument::fromJson (settings_file.readAll (), &status);
if (status.error)
{
throw error {tr ("Hamlib settings file error: %1 at character offset %2")
.arg (status.errorString ()).arg (status.offset)};
}
qDebug () << "Hamlib settings JSON:" << settings_doc.toJson ();
if (!settings_doc.isObject ())
{
throw error {tr ("Hamlib settings file error: top level must be a JSON object")};
}
auto const& settings = settings_doc.object ();
throw error {tr ("Hamlib settings file error: %1 at character offset %2")
.arg (status.errorString ()).arg (status.offset)};
}
qDebug () << "Hamlib settings JSON:" << settings_doc.toJson ();
if (!settings_doc.isObject ())
{
throw error {tr ("Hamlib settings file error: top level must be a JSON object")};
}
auto const& settings = settings_doc.object ();
//
// configuration settings
//
auto const& config = settings["config"];
if (!config.isUndefined ())
//
// configuration settings
//
auto const& config = settings["config"];
if (!config.isUndefined ())
{
if (!config.isObject ())
{
if (!config.isObject ())
{
throw error {tr ("Hamlib settings file error: config must be a JSON object")};
}
auto const& config_list = config.toObject ();
for (auto item = config_list.constBegin (); item != config_list.constEnd (); ++item)
{
set_conf (item.key ().toLocal8Bit ().constData ()
, (*item).toVariant ().toString ().toLocal8Bit ().constData ());
}
throw error {tr ("Hamlib settings file error: config must be a JSON object")};
}
auto const& config_list = config.toObject ();
for (auto item = config_list.constBegin (); item != config_list.constEnd (); ++item)
{
set_conf (item.key ().toLocal8Bit ().constData ()
, (*item).toVariant ().toString ().toLocal8Bit ().constData ());
}
}
}
}
if (!is_dummy_)
{
switch (rig_->caps->port_type)
{
case RIG_PORT_SERIAL:

View File

@ -35,7 +35,7 @@ namespace trivial = logging::trivial;
namespace keywords = logging::keywords;
namespace expr = logging::expressions;
namespace sinks = logging::sinks;
namespace ptime = boost::posix_time;
namespace posix_time = boost::posix_time;
namespace gregorian = boost::gregorian;
namespace container = boost::container;
@ -139,7 +139,9 @@ WSJTXLogging::WSJTXLogging ()
app_data.absoluteFilePath ("logs/wsjtx_syslog_%Y-%m.log").toStdString ()
, keywords::time_based_rotation = sinks::file::rotation_at_time_point (gregorian::greg_day (1), 0, 0, 0)
, keywords::open_mode = std::ios_base::out | std::ios_base::app
#if BOOST_VERSION / 100 >= 1063
, keywords::enable_final_rotation = false
#endif
);
sys_sink->locked_backend ()->set_file_collector
@ -166,8 +168,8 @@ WSJTXLogging::WSJTXLogging ()
(
expr::stream
<< "[" << channel
<< "][" << expr::format_date_time<ptime::ptime> ("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
<< "][" << expr::format_date_time<ptime::time_duration> ("Uptime", "%O:%M:%S.%f")
<< "][" << expr::format_date_time<posix_time::ptime> ("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
<< "][" << expr::format_date_time<posix_time::time_duration> ("Uptime", "%O:%M:%S.%f")
<< "][" << trivial::severity
<< "] " << expr::message
);

View File

@ -197,7 +197,7 @@ function (document)
-a data-uri!
-a VERSION_MAJOR=${WSJTX_VERSION_MAJOR}
-a VERSION_MINOR=${WSJTX_VERSION_MINOR}
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}
-a VERSION_PATCH=${WSJTX_VERSION_PATCH}${BUILD_TYPE_REVISION}
-a VERSION=${wsjtx_VERSION}
-D ${CMAKE_CURRENT_BINARY_DIR}
-o ${_docbook_file} ${_source_name}

View File

@ -43,7 +43,7 @@ CMake
-----
Download and install a recent version from the official CMake web
site. A default installation is fine. I am currently using v3.18.3,
site. A default installation is fine. I am currently using v3.18.4,
versions as old as v3.9 should work.
Other tools and libraries without installers
@ -59,8 +59,10 @@ FFTW v3 DFT library
-------------------
The MS Windows builds of FFTW3 can be downloaded from
http://www.fftw.org/install/windows.html and unzipped into C:\Tools.
You only need the 64-bit package.
http://www.fftw.org/install/windows.html. The ZIP archives for this
package have no directory structure so create a directory under C:\
Tools\ called fftw-3.3.5-dll64 and unzip the archive there. You only
need the 64-bit package.
libusb library
--------------

View File

@ -82,12 +82,12 @@ Common steps
Download and extract the latest Boost library sources, at the time of
writing that was
https://dl.bintray.com/boostorg/release/1.74.0/source/boost_1_74_0.7z
. Extract to some convenient location, I use %HOME%\src .
. Extract to some convenient location, I use %USERPROFILE%\src .
Download and extract the libbacktrace sources from
https://github.com/ianlancetaylor/libbacktrace as follows.
cd %HOME%\src
cd %USERPROFILE%\src
mkdir github.com
cd github.com
mkdir ianlancetaylor
@ -101,8 +101,8 @@ names are unique per architecture and tool-chain. This saves a lot of
space as the boost header files are quite big, and there's no need to
install multiple copies.
Create a new file %HOME%\src\boost_1_74_0\project-config.jam with the
following three lines to specify how Boost.Build finds the
Create a new file %USERPROFILE%\src\boost_1_74_0\project-config.jam
with the following three lines to specify how Boost.Build finds the
libbacktrace library matched to your relevant C++ compliers:
import toolset ;
@ -133,13 +133,15 @@ tool-chain bundled with your Qt binary installation. Verify the
correct compiler is in the PATH. i.e. it identifies (g++ --version) as
i686-posix-dwarf-rev0.
cd %HOME%\src\boost_1_74_0\tools\build
cd %USERPROFILE%\src\boost_1_74_0\tools\build
bootstrap.bat mingw
.\b2 --prefix=C:\Tools\boost-build\MinGW32 install
cd ..\..
C:\Tools\boost-build\MinGW32\bin\b2 -j8 toolset=gcc ^
--build-dir=%HOME%\build\boost ^
--build-type=complete --prefix=C:\Tools\boost install
--build-dir=%USERPROFILE%\build\boost ^
address-model=32 architecture=x86 variant=debug,release ^
link=shared threading=multi ^
--with-log --with-stacktrace --prefix=C:\Tools\boost install
If all is well you should see the following line about a 1/3 of the
way through the initial configuration steps.
@ -156,7 +158,7 @@ warnings can usually be ignored. If successful; you can release some
space by cleaning the build tree:
C:\Tools\boost-build\MinGW32\bin\b2 toolset=gcc ^
--build-dir=%HOME%\build\boost ^
--build-dir=%USERPROFILE%\build\boost ^
--build-type=complete clean
64-bit
@ -179,13 +181,16 @@ compilers and the project-config.jam file you created above. With a v7
gcc-8~64. My example matches my 64-bit Qt v5.15.0 with the bundled
MinGW64 v8.1.0.
cd %HOME%\src\boost_1_74_0\tools\build
bootstrap.bat
cd %USERPROFILE%\src\boost_1_74_0\tools\build
bootstrap.bat mingw
.\b2 --prefix=C:\Tools\boost-build\MinGW64 install
cd ..\..
C:\Tools\boost-build\MinGW64\bin\b2 -j8 toolset=gcc-8~64 ^
address-model=64 --build-dir=%HOME%\build\boost ^
--build-type=complete --prefix=C:\Tools\boost install
address-model=64 architecture=x86 variant=debug,release ^
link=shared threading=multi ^
--with-log --with-stacktrace ^
--build-dir=%USERPROFILE%\build\boost ^
--prefix=C:\Tools\boost install
If all is well you should see the following line about a 1/3 of the
way through the initial configuration steps.
@ -202,9 +207,8 @@ warnings can usually be ignored. If successful; you can release some
space by cleaning the build tree:
C:\Tools\boost-build\MinGW32\bin\b2 toolset=gcc-8~64 ^
address-model=64 --build-dir=%HOME%\build\boost ^
address-model=64 --build-dir=%USERPROFILE%\build\boost ^
--build-type=complete clean
Run-time Environment
--------------------
@ -226,15 +230,12 @@ configuration tool-chain file:
# ...
set (BOOSTDIR C:/Tools/boost)
set (QTDIR C:/Qt/5.12.9/mingw73_32)
# set (QTDIR C:/Qt/5.15.0/mingw81_32)
set (QTDIR C:/Qt/5.15.2/mingw81_32)
set (FFTWDIR C:/Tools/fftw-3.3.5-dll32)
set (HAMLIBDIR C:/test-install/hamlib/mingw32/debug)
set (LIBUSBDIR C:/Tools/libusb-1.0.23)
set (PYTHONDIR C:/Python27)
set (ASCIIDOCDIR C:/Tools/asciidoc-master)
# where to find required packages
set (CMAKE_PREFIX_PATH ${BOOSTDIR} ${QTDIR} ${FFTWDIR} ${HAMLIBDIR} ${HAMLIBDIR}/bin ${LIBUSBDIR} ${PYTHONDIR} ${ASCIIDOCDIR})
set (CMAKE_PREFIX_PATH ${BOOSTDIR} ${QTDIR} ${FFTWDIR} ${HAMLIBDIR} ${HAMLIBDIR}/bin ${LIBUSBDIR})
# ...

View File

@ -43,7 +43,8 @@ You may also need to execute the following command in a terminal:
....
sudo apt install libgfortran5 libqt5widgets5 libqt5network5 \
libqt5printsupport5 libqt5multimedia5-plugins libqt5serialport5 \
libqt5sql5-sqlite libfftw3-single3 libgomp1 libusb-1.0-0
libqt5sql5-sqlite libfftw3-single3 libgomp1 libboost-all-dev \
libusb-1.0-0
....
Fedora, CentOS, Red Hat, and other rpm-based systems:
@ -75,5 +76,5 @@ You may also need to execute the following command in a terminal:
....
sudo dnf install libgfortran fftw-libs-single qt5-qtbase \
qt5-qtmultimedia qt5-qtserialport qt5-qtsvg \
qt5-qtserialport libgomp libusbx
qt5-qtserialport libgomp boost libusbx
....

View File

@ -76,7 +76,13 @@ namespace
switch (static_cast<QMetaType::Type> (v.type ()))
{
case QMetaType::QByteArray:
os << "0x" << v.toByteArray ().toHex (':').toStdString ();
os << "0x"
#if QT_VERSION >= QT_VERSION_CHECK (5, 9, 0)
<< v.toByteArray ().toHex (':').toStdString ()
#else
<< v.toByteArray ().toHex ().toStdString ()
#endif
;
break;
case QMetaType::QBitArray:

View File

@ -0,0 +1,92 @@
#ifndef MULTI_GEOMETRY_WIDGET_HPP__
#define MULTI_GEOMETRY_WIDGET_HPP__
#include <cstddef>
#include <utility>
#include <array>
#include <QWidget>
#include <QByteArray>
#include <QEvent>
//
// Class MultiGeometryWidget<N, Widget> - Decorate a QWidget type with
// switchable geometries
//
// The abstract base class imbues a Qt Widget type with N alternative
// geometries. Sub-classes can initialise the currently selected
// geometry and the initial geometries using geometries. To switch
// geometry call select_geometry(n) which saves the current geometry
// and switches to the n'th saved geometry.
//
template<std::size_t N, typename Widget=QWidget>
class MultiGeometryWidget
: public Widget
{
public:
template<typename... Args>
explicit MultiGeometryWidget (Args&&... args)
: Widget {std::forward<Args> (args)...}
, current_geometry_ {0}
{
}
void geometries (std::size_t current
, std::array<QByteArray, N> const& the_geometries = std::array<QByteArray, N> {})
{
Q_ASSERT (current < the_geometries.size ());
saved_geometries_ = the_geometries;
current_geometry_ = current;
Widget::restoreGeometry (saved_geometries_[current_geometry_]);
}
std::array<QByteArray, N> const& geometries () const {return saved_geometries_;}
std::size_t current () {return current_geometry_;}
// Call this to select a new geometry denoted by the 'n' argument,
// any actual layout changes should be made in the implementation of
// the change_layout operation below.
void select_geometry (std::size_t n)
{
Q_ASSERT (n < N);
auto geometry = Widget::saveGeometry ();
change_layout (n);
saved_geometries_[current_geometry_] = geometry;
current_geometry_ = n;
// Defer restoration of the window geometry until the layour
// request event has been processed, this is necessary otherwise
// the final geometry may be affected by widgets not shown in the
// new layout.
desired_geometry_ = saved_geometries_[n];
}
protected:
virtual ~MultiGeometryWidget () {}
private:
// Override this operation to implement any layout changes for the
// geometry specified by the argument 'n'.
virtual void change_layout (std::size_t n) = 0;
bool event (QEvent * e) override
{
auto ret = Widget::event (e);
if (QEvent::LayoutRequest == e->type ()
&& desired_geometry_.size ())
{
// Restore the new desired geometry and flag that we have done
// so by clearing the desired_geometry_ member variable.
QByteArray geometry;
std::swap (geometry, desired_geometry_);
Widget::restoreGeometry (geometry);
}
return ret;
}
std::size_t current_geometry_;
std::array<QByteArray, N> saved_geometries_;
QByteArray desired_geometry_;
};
#endif

View File

@ -236,7 +236,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
MultiSettings * multi_settings, QSharedMemory *shdmem,
unsigned downSampleFactor,
QSplashScreen * splash, QProcessEnvironment const& env, QWidget *parent) :
QMainWindow(parent),
MultiGeometryWidget {parent},
m_env {env},
m_network_manager {this},
m_valid {true},
@ -1022,24 +1022,21 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
}
ui->pbBestSP->setVisible(m_mode=="FT4");
if(!ui->cbMenus->isChecked()) {
ui->cbMenus->setChecked(true);
ui->cbMenus->setChecked(false);
}
// this must be the last statement of constructor
if (!m_valid) throw std::runtime_error {"Fatal initialization exception"};
}
void MainWindow::not_GA_warning_message ()
{
// MessageBox::critical_message (this,
// "This is a pre-release version of WSJT-X 2.3.0 made\n"
// "available for testing purposes. By design it will\n"
// "be nonfunctional after 0000 UTC on Nov 17, 2020.");
// auto now = QDateTime::currentDateTimeUtc ();
// if (now >= QDateTime {{2020, 11, 17}, {0, 0}, Qt::UTC}) {
// Q_EMIT finished ();
// }
MessageBox::critical_message (this,
"This is a pre-release version of WSJT-X 2.3.0 made\n"
"available for testing purposes. By design it will\n"
"be nonfunctional after 0000 UTC on Jan 19, 2021.");
auto now = QDateTime::currentDateTimeUtc ();
if (now >= QDateTime {{2021, 1, 19}, {0, 0}, Qt::UTC}) {
Q_EMIT finished ();
}
}
void MainWindow::initialize_fonts ()
@ -1094,8 +1091,33 @@ MainWindow::~MainWindow()
void MainWindow::writeSettings()
{
m_settings->beginGroup("MainWindow");
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue ("geometryNoControls", m_geometryNoControls);
if (ui->actionSWL_Mode->isChecked ())
{
m_settings->setValue ("SWLView", true);
m_settings->setValue ("ShowMenus", ui->cbMenus->isChecked ());
m_settings->setValue ("geometry", geometries ()[0]);
m_settings->setValue ("SWLModeGeometry", saveGeometry ());
m_settings->setValue ("geometryNoControls", geometries ()[2]);
}
else
{
if (ui->cbMenus->isChecked())
{
m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ());
m_settings->setValue ("ShowMenus", true);
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue ("SWLModeGeometry", geometries ()[1]);
m_settings->setValue ("geometryNoControls", geometries ()[2]);
}
else
{
m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ());
m_settings->setValue ("ShowMenus", false);
m_settings->setValue ("geometry", geometries ()[0]);
m_settings->setValue ("SWLModeGeometry", geometries ()[1]);
m_settings->setValue ("geometryNoControls", saveGeometry ());
}
}
m_settings->setValue ("state", saveState ());
m_settings->setValue("MRUdir", m_path);
m_settings->setValue("TxFirst",m_txFirst);
@ -1105,7 +1127,6 @@ void MainWindow::writeSettings()
m_settings->setValue ("MsgAvgDisplayed", m_msgAvgWidget && m_msgAvgWidget->isVisible ());
m_settings->setValue ("FoxLogDisplayed", m_foxLogWindow && m_foxLogWindow->isVisible ());
m_settings->setValue ("ContestLogDisplayed", m_contestLogWindow && m_contestLogWindow->isVisible ());
m_settings->setValue("ShowMenus",ui->cbMenus->isChecked());
m_settings->setValue("CallFirst",ui->cbFirst->isChecked());
m_settings->setValue("HoundSort",ui->comboBoxHoundSort->currentIndex());
m_settings->setValue("FoxNlist",ui->sbNlist->value());
@ -1159,9 +1180,8 @@ void MainWindow::writeSettings()
m_settings->setValue("pwrBandTuneMemory",m_pwrBandTuneMemory);
m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ());
m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ());
m_settings->setValue("SplitterState",ui->splitter->saveState());
m_settings->setValue("SplitterState",ui->decodes_splitter->saveState());
m_settings->setValue("Blanker",ui->sbNB->value());
m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ());
{
QList<QVariant> coeffs; // suitable for QSettings
@ -1180,8 +1200,17 @@ void MainWindow::readSettings()
ui->cbAutoSeq->setVisible(false);
ui->cbFirst->setVisible(false);
m_settings->beginGroup("MainWindow");
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
m_geometryNoControls = m_settings->value ("geometryNoControls",saveGeometry()).toByteArray();
std::array<QByteArray, 3> the_geometries;
the_geometries[0] = m_settings->value ("geometry", saveGeometry ()).toByteArray ();
the_geometries[1] = m_settings->value ("SWLModeGeometry", saveGeometry ()).toByteArray ();
the_geometries[2] = m_settings->value ("geometryNoControls", saveGeometry ()).toByteArray ();
auto SWL_mode = m_settings->value ("SWLView", false).toBool ();
auto show_menus = m_settings->value ("ShowMenus", true).toBool ();
ui->actionSWL_Mode->setChecked (SWL_mode);
ui->cbMenus->setChecked (show_menus);
auto current_view_mode = SWL_mode ? 1 : show_menus ? 0 : 2;
change_layout (current_view_mode);
geometries (current_view_mode, the_geometries);
restoreState (m_settings->value ("state", saveState ()).toByteArray ());
ui->dxCallEntry->setText (m_settings->value ("DXcall", QString {}).toString ());
ui->dxGridEntry->setText (m_settings->value ("DXgrid", QString {}).toString ());
@ -1191,7 +1220,6 @@ void MainWindow::readSettings()
auto displayMsgAvg = m_settings->value ("MsgAvgDisplayed", false).toBool ();
auto displayFoxLog = m_settings->value ("FoxLogDisplayed", false).toBool ();
auto displayContestLog = m_settings->value ("ContestLogDisplayed", false).toBool ();
ui->cbMenus->setChecked(m_settings->value("ShowMenus",true).toBool());
ui->cbFirst->setChecked(m_settings->value("CallFirst",true).toBool());
ui->comboBoxHoundSort->setCurrentIndex(m_settings->value("HoundSort",3).toInt());
ui->sbNlist->setValue(m_settings->value("FoxNlist",12).toInt());
@ -1265,10 +1293,8 @@ void MainWindow::readSettings()
m_pwrBandTuneMemory=m_settings->value("pwrBandTuneMemory").toHash();
ui->actionEnable_AP_FT8->setChecked (m_settings->value ("FT8AP", false).toBool());
ui->actionEnable_AP_JT65->setChecked (m_settings->value ("JT65AP", false).toBool());
ui->splitter->restoreState(m_settings->value("SplitterState").toByteArray());
ui->decodes_splitter->restoreState(m_settings->value("SplitterState").toByteArray());
ui->sbNB->setValue(m_settings->value("Blanker",0).toInt());
ui->actionSWL_Mode->setChecked (m_settings->value ("SWLView", false).toBool ());
on_actionSWL_Mode_triggered (ui->actionSWL_Mode->isChecked ());
{
auto const& coeffs = m_settings->value ("PhaseEqualizationCoefficients"
, QList<QVariant> {0., 0., 0., 0., 0.}).toList ();
@ -2568,37 +2594,52 @@ void MainWindow::on_actionCopyright_Notice_triggered()
MessageBox::warning_message(this, message);
}
// Implement the MultiGeometryWidget::change_layout() operation.
void MainWindow::change_layout (std::size_t n)
{
switch (n)
{
case 1: // SWL view
ui->menuBar->show ();
ui->lower_panel_widget->hide ();
trim_view (false); // ensure we can switch back
break;
case 2: // hide menus view
ui->menuBar->hide ();
ui->lower_panel_widget->show ();
trim_view (true);
break;
default: // normal view
ui->menuBar->setVisible (ui->cbMenus->isChecked ());
ui->lower_panel_widget->show ();
trim_view (!ui->cbMenus->isChecked ());
break;
}
}
void MainWindow::on_actionSWL_Mode_triggered (bool checked)
{
ui->lower_panel_widget->setVisible (!checked);
if (checked)
{
hideMenus (false); // make sure we can be turned off
}
select_geometry (checked ? 1 : ui->cbMenus->isChecked () ? 0 : 2);
}
// This allows the window to shrink by removing certain things
// and reducing space used by controls
void MainWindow::hideMenus(bool checked)
void MainWindow::trim_view (bool checked)
{
int spacing = checked ? 1 : 6;
if (checked) {
statusBar ()->removeWidget (&auto_tx_label);
minimumSize().setHeight(450);
minimumSize().setWidth(700);
restoreGeometry(m_geometryNoControls);
updateGeometry();
} else {
m_geometryNoControls = saveGeometry();
statusBar ()->addWidget(&auto_tx_label);
minimumSize().setHeight(520);
minimumSize().setWidth(770);
}
ui->menuBar->setVisible(!checked);
if(m_mode!="FreqCal" and m_mode!="WSPR" and m_mode!="FST4W") {
if (m_mode != "FreqCal" && m_mode != "WSPR" && m_mode != "FST4W") {
ui->lh_decodes_title_label->setVisible(!checked);
ui->rh_decodes_title_label->setVisible(!checked);
}
ui->lh_decodes_headings_label->setVisible(!checked);
ui->rh_decodes_headings_label->setVisible(!checked);
ui->gridLayout_5->layout()->setSpacing(spacing);
ui->horizontalLayout_2->layout()->setSpacing(spacing);
ui->horizontalLayout_5->layout()->setSpacing(spacing);
@ -3025,8 +3066,8 @@ void MainWindow::decode() //decode()
dec_data.params.nutc=dec_data.params.nutc/100;
}
if(dec_data.params.nagain==0 && dec_data.params.newdat==1 && (!m_diskData)) {
auto t_start = qt_truncate_date_time_to (QDateTime::currentDateTimeUtc (), m_TRperiod * 1.e3);
auto t = t_start.time ();
m_dateTimeSeqStart = qt_truncate_date_time_to (QDateTime::currentDateTimeUtc (), m_TRperiod * 1.e3);
auto t = m_dateTimeSeqStart.time ();
dec_data.params.nutc = t.hour () * 100 + t.minute ();
if (m_TRperiod < 60.)
{
@ -5918,7 +5959,11 @@ void MainWindow::displayWidgets(qint64 n)
if(i==31) ui->cbRxAll->setVisible(b);
if(i==32) ui->cbCQonly->setVisible(b);
if(i==33) ui->sbTR_FST4W->setVisible(b);
if(i==34) ui->sbF_Low->setVisible(b);
if (34 == i) // adjust the stacked widget
{
ui->opt_controls_stack->setCurrentIndex (b ? 1 : 0);
ui->sbF_Low->setVisible(b);
}
if(i==35) ui->sbF_High->setVisible(b);
j=j>>1;
}
@ -8431,7 +8476,7 @@ void MainWindow::update_watchdog_label ()
void MainWindow::on_cbMenus_toggled(bool b)
{
hideMenus(!b);
select_geometry (!b ? 2 : ui->actionSWL_Mode->isChecked () ? 1 : 0);
}
void MainWindow::on_cbCQonly_toggled(bool)

View File

@ -26,6 +26,7 @@
#include <QFuture>
#include <QFutureWatcher>
#include "MultiGeometryWidget.hpp"
#include "NonInheritingProcess.hpp"
#include "Audio/AudioDevice.hpp"
#include "commons.h"
@ -94,7 +95,8 @@ class MultiSettings;
class EqualizationToolsDialog;
class DecodedText;
class MainWindow : public QMainWindow
class MainWindow
: public MultiGeometryWidget<3, QMainWindow>
{
Q_OBJECT;
@ -130,7 +132,8 @@ public slots:
void msgAvgDecode2();
void fastPick(int x0, int x1, int y);
protected:
private:
void change_layout (std::size_t) override;
void keyPressEvent (QKeyEvent *) override;
void closeEvent(QCloseEvent *) override;
void childEvent(QChildEvent *) override;
@ -353,7 +356,7 @@ private:
void astroUpdate ();
void writeAllTxt(QString message);
void auto_sequence (DecodedText const& message, unsigned start_tolerance, unsigned stop_tolerance);
void hideMenus(bool b);
void trim_view (bool b);
void foxTest();
void setColorHighlighting();
void chkFT4();

File diff suppressed because it is too large Load Diff

View File

@ -20,15 +20,15 @@ AutoFlush="false"
# Line Formats available: TimeStamp, Uptime, Severity, LineID (counter), ProcessID, ThreadID, Line, File, Function
# TimeStamp and Uptime support boost date time format:
# http://www.boost.org/doc/libs/1_60_0/doc/html/date_time/date_time_io.html#date_time.format_flags
Format="[%TimeStamp(format=\"%Y-%m-%d %H:%M:%S.%f\")%][%Uptime(format=\"%O:%M:%S.%f\")%][%Severity%] %File%(%Line%) %Function%: %Message%"
Format="[%TimeStamp(format=\"%Y-%m-%d %H:%M:%S.%f\")%][%Uptime(format=\"%O:%M:%S.%f\")%][%Channel%][%Severity%] %File%(%Line%) %Function%: %Message%"
# Target directory in which rotated files will be stored.
Target="${AppLocalDataLocation}/old_logs"
Target="${AppLocalDataLocation}/logs"
# FileName pattern to use. %N is a counter for files.
FileName="${AppLocalDataLocation}/wsjtx_syslog.log"
TargetFileName="${AppLocalDataLocation}/old_logs/wsjtx_syslog_%Y-%m-%d_%H-%M-%S.%N.log"
TargetFileName="${AppLocalDataLocation}/old_logs/wsjtx_syslog_%Y-%m_%2N.log"
# RotationSize in bytes, File size, in bytes, upon which file rotation will be performed.
# Time based rotation also available via RotationInterval and RotationTimePoint see boost log docs.
RotationSize="1048576"
RotationSize="5242880" # 5 Mbyte
# If Append is true then do not start a new log file for each session
Append="true"
# EnableFinalRotation will rotate on close, make this false if using Append true
@ -36,10 +36,10 @@ EnableFinalRotation="false"
# Matching used so that only files matching FileName pattern are deleted.
ScanForFiles="Matching"
# MaxSize - Total size of files in the target directory in bytes upon which the oldest file will be deleted.
#MaxSize=100485760
MaxSize="1073741824" # 1 Gbyte total
# MinFreeSpace - Minimum free space in the Target directory in bytes. Above this value oldest file is deleted.
#MinFreeSpace=1485760
MaxFiles="10"
MinFreeSpace="42949672960" # 40 Gbyte
MaxFiles="50"
# Specify level of log, options are: trace, debug, info, warning, error, fatal
# Since Channel not part of filter all log output will be included.
# If only SYSLOG logging desired, change to: Filter="%Severity% >= trace & %Channel% matches \"SYSLOG\""
@ -58,20 +58,20 @@ Append="true"
# http://www.boost.org/doc/libs/1_60_0/doc/html/date_time/date_time_io.html#date_time.format_flags
Format="[%TimeStamp(format=\"%Y-%m-%d %H:%M:%S.%f\")%][%Uptime(format=\"%O:%M:%S.%f\")%][%Severity%] %Message%"
# Target directory in which rotated files will be stored.
Target="${AppLocalDataLocation}/old_logs"
Target="${AppLocalDataLocation}/logs"
# FileName pattern to use. %N is a counter for files.
FileName="${AppLocalDataLocation}/wsjtx_datalog.log"
TargetFileName="wsjtx_datalog_%5N.log"
# RotationSize in bytes, File size, in bytes, upon which file rotation will be performed.
# Time based rotation also available via RotationInterval and RotationTimePoint see boost log docs.
RotationSize="1048576"
RotationSize="5242880"
EnableFinalRotation="false"
# Matching used so that only files matching FileName pattern are deleted.
ScanForFiles="Matching"
# MaxSize - Total size of files in the target directory in bytes upon which the oldest file will be deleted.
#MaxSize=100485760
MaxSize="1073741824"
# MinFreeSpace - Minimum free space in the Target directory in bytes. Above this value oldest file is deleted.
#MinFreeSpace=1485760
MinFreeSpace="42949672960"
MaxFiles="10"
# Specify level of log, options are: trace, debug, info, warning, error, fatal
# Specify Channel otherwise all log output will be included.