mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-22 12:23:37 -05:00
Merge branch 'feat-dropped-frames' into develop
This commit is contained in:
commit
c99f236dca
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,6 +1,9 @@
|
|||||||
~*
|
~*
|
||||||
TAGS
|
TAGS
|
||||||
tags
|
tags
|
||||||
|
GPATH
|
||||||
|
GRTAGS
|
||||||
|
GTAGS
|
||||||
*~
|
*~
|
||||||
junk*
|
junk*
|
||||||
jnq*
|
jnq*
|
||||||
@ -9,6 +12,9 @@ jnq*
|
|||||||
*.mod
|
*.mod
|
||||||
*.pro.user
|
*.pro.user
|
||||||
*.txt
|
*.txt
|
||||||
|
*.bak
|
||||||
|
!**/CMakeLists.txt
|
||||||
|
__pycache__
|
||||||
cmake-build-debug
|
cmake-build-debug
|
||||||
cmake-build-release
|
cmake-build-release
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
|
@ -41,7 +41,8 @@ bool SoundInput::audioError () const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, AudioDevice * sink, unsigned downSampleFactor, AudioDevice::Channel channel)
|
void SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, AudioDevice * sink
|
||||||
|
, unsigned downSampleFactor, AudioDevice::Channel channel)
|
||||||
{
|
{
|
||||||
Q_ASSERT (sink);
|
Q_ASSERT (sink);
|
||||||
|
|
||||||
@ -62,14 +63,13 @@ void SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, Audi
|
|||||||
Q_EMIT error (tr ("Requested input audio format is not valid."));
|
Q_EMIT error (tr ("Requested input audio format is not valid."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (!device.isFormatSupported (format))
|
||||||
if (!device.isFormatSupported (format))
|
|
||||||
{
|
{
|
||||||
// qDebug () << "Nearest supported audio format:" << device.nearestFormat (format);
|
// qDebug () << "Nearest supported audio format:" << device.nearestFormat (format);
|
||||||
Q_EMIT error (tr ("Requested input audio format is not supported on device."));
|
Q_EMIT error (tr ("Requested input audio format is not supported on device."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// qDebug () << "Selected audio input format:" << format;
|
// qDebug () << "Selected audio input format:" << format;
|
||||||
|
|
||||||
m_stream.reset (new QAudioInput {device, format});
|
m_stream.reset (new QAudioInput {device, format});
|
||||||
if (audioError ())
|
if (audioError ())
|
||||||
@ -79,11 +79,20 @@ void SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, Audi
|
|||||||
|
|
||||||
connect (m_stream.data(), &QAudioInput::stateChanged, this, &SoundInput::handleStateChanged);
|
connect (m_stream.data(), &QAudioInput::stateChanged, this, &SoundInput::handleStateChanged);
|
||||||
|
|
||||||
m_stream->setBufferSize (m_stream->format ().bytesForFrames (framesPerBuffer));
|
//qDebug () << "SoundIn default buffer size (bytes):" << m_stream->bufferSize () << "period size:" << m_stream->periodSize ();
|
||||||
|
// the Windows MME version of QAudioInput uses 1/5 of the buffer
|
||||||
|
// size for period size other platforms seem to optimize themselves
|
||||||
|
#if defined (Q_OS_WIN)
|
||||||
|
m_stream->setBufferSize (m_stream->format ().bytesForFrames (framesPerBuffer * 5));
|
||||||
|
#else
|
||||||
|
Q_UNUSED (framesPerBuffer);
|
||||||
|
#endif
|
||||||
if (sink->initialize (QIODevice::WriteOnly, channel))
|
if (sink->initialize (QIODevice::WriteOnly, channel))
|
||||||
{
|
{
|
||||||
m_stream->start (sink);
|
m_stream->start (sink);
|
||||||
audioError ();
|
audioError ();
|
||||||
|
cummulative_lost_usec_ = -1;
|
||||||
|
//qDebug () << "SoundIn selected buffer size (bytes):" << m_stream->bufferSize () << "peirod size:" << m_stream->periodSize ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -115,9 +124,9 @@ void SoundInput::resume ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundInput::handleStateChanged (QAudio::State newState) const
|
void SoundInput::handleStateChanged (QAudio::State newState)
|
||||||
{
|
{
|
||||||
// qDebug () << "SoundInput::handleStateChanged: newState:" << newState;
|
//qDebug () << "SoundInput::handleStateChanged: newState:" << newState;
|
||||||
|
|
||||||
switch (newState)
|
switch (newState)
|
||||||
{
|
{
|
||||||
@ -126,6 +135,7 @@ void SoundInput::handleStateChanged (QAudio::State newState) const
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case QAudio::ActiveState:
|
case QAudio::ActiveState:
|
||||||
|
reset (false);
|
||||||
Q_EMIT status (tr ("Receiving"));
|
Q_EMIT status (tr ("Receiving"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -152,6 +162,22 @@ void SoundInput::handleStateChanged (QAudio::State newState) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundInput::reset (bool report_dropped_frames)
|
||||||
|
{
|
||||||
|
if (m_stream)
|
||||||
|
{
|
||||||
|
if (cummulative_lost_usec_ >= 0 // don't report first time as we
|
||||||
|
// don't yet known latency
|
||||||
|
&& report_dropped_frames)
|
||||||
|
{
|
||||||
|
auto lost_usec = m_stream->elapsedUSecs () - m_stream->processedUSecs () - cummulative_lost_usec_;
|
||||||
|
Q_EMIT dropped_frames (m_stream->format ().framesForDuration (lost_usec), lost_usec);
|
||||||
|
//qDebug () << "SoundInput::reset: frames dropped:" << m_stream->format ().framesForDuration (lost_usec) << "sec:" << lost_usec / 1.e6;
|
||||||
|
}
|
||||||
|
cummulative_lost_usec_ = m_stream->elapsedUSecs () - m_stream->processedUSecs ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SoundInput::stop()
|
void SoundInput::stop()
|
||||||
{
|
{
|
||||||
if (m_stream)
|
if (m_stream)
|
||||||
|
@ -24,6 +24,7 @@ public:
|
|||||||
SoundInput (QObject * parent = nullptr)
|
SoundInput (QObject * parent = nullptr)
|
||||||
: QObject {parent}
|
: QObject {parent}
|
||||||
, m_sink {nullptr}
|
, m_sink {nullptr}
|
||||||
|
, cummulative_lost_usec_ {0}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,18 +36,21 @@ public:
|
|||||||
Q_SLOT void suspend ();
|
Q_SLOT void suspend ();
|
||||||
Q_SLOT void resume ();
|
Q_SLOT void resume ();
|
||||||
Q_SLOT void stop ();
|
Q_SLOT void stop ();
|
||||||
|
Q_SLOT void reset (bool report_dropped_frames);
|
||||||
|
|
||||||
Q_SIGNAL void error (QString message) const;
|
Q_SIGNAL void error (QString message) const;
|
||||||
Q_SIGNAL void status (QString message) const;
|
Q_SIGNAL void status (QString message) const;
|
||||||
|
Q_SIGNAL void dropped_frames (qint32 dropped, qint64 usec);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// used internally
|
// used internally
|
||||||
Q_SLOT void handleStateChanged (QAudio::State) const;
|
Q_SLOT void handleStateChanged (QAudio::State);
|
||||||
|
|
||||||
bool audioError () const;
|
bool audioError () const;
|
||||||
|
|
||||||
QScopedPointer<QAudioInput> m_stream;
|
QScopedPointer<QAudioInput> m_stream;
|
||||||
QPointer<AudioDevice> m_sink;
|
QPointer<AudioDevice> m_sink;
|
||||||
|
qint64 cummulative_lost_usec_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,15 +9,6 @@
|
|||||||
|
|
||||||
#include "moc_soundout.cpp"
|
#include "moc_soundout.cpp"
|
||||||
|
|
||||||
/*
|
|
||||||
#if defined (WIN32)
|
|
||||||
# define MS_BUFFERED 1000u
|
|
||||||
#else
|
|
||||||
# define MS_BUFFERED 2000u
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
# define MS_BUFFERED 200u
|
|
||||||
|
|
||||||
bool SoundOutput::audioError () const
|
bool SoundOutput::audioError () const
|
||||||
{
|
{
|
||||||
bool result (true);
|
bool result (true);
|
||||||
@ -50,14 +41,16 @@ bool SoundOutput::audioError () const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundOutput::setFormat (QAudioDeviceInfo const& device, unsigned channels, unsigned msBuffered)
|
void SoundOutput::setFormat (QAudioDeviceInfo const& device, unsigned channels, int frames_buffered)
|
||||||
{
|
{
|
||||||
|
if (!device.isNull ())
|
||||||
|
{
|
||||||
Q_ASSERT (0 < channels && channels < 3);
|
Q_ASSERT (0 < channels && channels < 3);
|
||||||
|
|
||||||
m_msBuffered = msBuffered;
|
m_framesBuffered = frames_buffered;
|
||||||
|
|
||||||
QAudioFormat format (device.preferredFormat ());
|
QAudioFormat format (device.preferredFormat ());
|
||||||
// qDebug () << "Preferred audio output format:" << format;
|
// qDebug () << "Preferred audio output format:" << format;
|
||||||
format.setChannelCount (channels);
|
format.setChannelCount (channels);
|
||||||
format.setCodec ("audio/pcm");
|
format.setCodec ("audio/pcm");
|
||||||
format.setSampleRate (48000);
|
format.setSampleRate (48000);
|
||||||
@ -68,44 +61,56 @@ void SoundOutput::setFormat (QAudioDeviceInfo const& device, unsigned channels,
|
|||||||
{
|
{
|
||||||
Q_EMIT error (tr ("Requested output audio format is not valid."));
|
Q_EMIT error (tr ("Requested output audio format is not valid."));
|
||||||
}
|
}
|
||||||
if (!device.isFormatSupported (format))
|
else if (!device.isFormatSupported (format))
|
||||||
{
|
{
|
||||||
Q_EMIT error (tr ("Requested output audio format is not supported on device."));
|
Q_EMIT error (tr ("Requested output audio format is not supported on device."));
|
||||||
}
|
}
|
||||||
// qDebug () << "Selected audio output format:" << format;
|
else
|
||||||
|
{
|
||||||
|
// qDebug () << "Selected audio output format:" << format;
|
||||||
|
|
||||||
m_stream.reset (new QAudioOutput (device, format));
|
m_stream.reset (new QAudioOutput (device, format));
|
||||||
audioError ();
|
audioError ();
|
||||||
m_stream->setVolume (m_volume);
|
m_stream->setVolume (m_volume);
|
||||||
m_stream->setNotifyInterval(100);
|
m_stream->setNotifyInterval(100);
|
||||||
|
error_ = false;
|
||||||
|
|
||||||
connect (m_stream.data(), &QAudioOutput::stateChanged, this, &SoundOutput::handleStateChanged);
|
connect (m_stream.data(), &QAudioOutput::stateChanged, this, &SoundOutput::handleStateChanged);
|
||||||
|
|
||||||
// qDebug() << "A" << m_volume << m_stream->notifyInterval();
|
// qDebug() << "A" << m_volume << m_stream->notifyInterval();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundOutput::restart (QIODevice * source)
|
void SoundOutput::restart (QIODevice * source)
|
||||||
{
|
{
|
||||||
Q_ASSERT (m_stream);
|
if (!m_stream)
|
||||||
|
{
|
||||||
|
if (!error_)
|
||||||
|
{
|
||||||
|
error_ = true; // only signal error once
|
||||||
|
Q_EMIT error (tr ("No audio output device configured."));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// This buffer size is critical since for proper sound streaming. If
|
|
||||||
// it is too short; high activity levels on the machine can starve
|
|
||||||
// the audio buffer. On the other hand the Windows implementation
|
|
||||||
// seems to take the length of the buffer in time to stop the audio
|
|
||||||
// stream even if reset() is used.
|
|
||||||
//
|
|
||||||
// 2 seconds seems a reasonable compromise except for Windows
|
|
||||||
// where things are probably broken.
|
|
||||||
//
|
|
||||||
// we have to set this before every start on the stream because the
|
// we have to set this before every start on the stream because the
|
||||||
// Windows implementation seems to forget the buffer size after a
|
// Windows implementation seems to forget the buffer size after a
|
||||||
// stop.
|
// stop.
|
||||||
m_stream->setBufferSize (m_stream->format().bytesForDuration((m_msBuffered ? m_msBuffered : MS_BUFFERED) * 1000));
|
//qDebug () << "SoundOut default buffer size (bytes):" << m_stream->bufferSize () << "period size:" << m_stream->periodSize ();
|
||||||
// qDebug() << "B" << m_stream->bufferSize() <<
|
if (m_framesBuffered)
|
||||||
// m_stream->periodSize() << m_stream->notifyInterval();
|
{
|
||||||
|
#if defined (Q_OS_WIN)
|
||||||
|
m_stream->setBufferSize (m_stream->format().bytesForFrames (m_framesBuffered));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
m_stream->setCategory ("production");
|
m_stream->setCategory ("production");
|
||||||
m_stream->start (source);
|
m_stream->start (source);
|
||||||
|
// qDebug () << "SoundOut selected buffer size (bytes):" << m_stream->bufferSize () << "period size:" << m_stream->periodSize ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundOutput::suspend ()
|
void SoundOutput::suspend ()
|
||||||
|
@ -18,15 +18,16 @@ class SoundOutput
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
SoundOutput ()
|
SoundOutput ()
|
||||||
: m_msBuffered {0u}
|
: m_framesBuffered {0}
|
||||||
, m_volume {1.0}
|
, m_volume {1.0}
|
||||||
|
, error_ {false}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal attenuation () const;
|
qreal attenuation () const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setFormat (QAudioDeviceInfo const& device, unsigned channels, unsigned msBuffered = 0u);
|
void setFormat (QAudioDeviceInfo const& device, unsigned channels, int frames_buffered = 0);
|
||||||
void restart (QIODevice *);
|
void restart (QIODevice *);
|
||||||
void suspend ();
|
void suspend ();
|
||||||
void resume ();
|
void resume ();
|
||||||
@ -47,8 +48,9 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<QAudioOutput> m_stream;
|
QScopedPointer<QAudioOutput> m_stream;
|
||||||
unsigned m_msBuffered;
|
int m_framesBuffered;
|
||||||
qreal m_volume;
|
qreal m_volume;
|
||||||
|
bool error_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -222,9 +222,12 @@ set (WSJT_QT_CONF_DESTINATION ${QT_CONF_DESTINATION} CACHE PATH "Path for the qt
|
|||||||
#
|
#
|
||||||
# Project sources
|
# Project sources
|
||||||
#
|
#
|
||||||
|
set (fort_qt_CXXSRCS
|
||||||
|
lib/shmem.cpp
|
||||||
|
)
|
||||||
|
|
||||||
set (wsjt_qt_CXXSRCS
|
set (wsjt_qt_CXXSRCS
|
||||||
qt_helpers.cpp
|
qt_helpers.cpp
|
||||||
lib/shmem.cpp
|
|
||||||
widgets/MessageBox.cpp
|
widgets/MessageBox.cpp
|
||||||
MetaDataRegistry.cpp
|
MetaDataRegistry.cpp
|
||||||
Network/NetworkServerLookup.cpp
|
Network/NetworkServerLookup.cpp
|
||||||
@ -730,6 +733,7 @@ set (qcp_CXXSRCS
|
|||||||
|
|
||||||
set (all_CXXSRCS
|
set (all_CXXSRCS
|
||||||
${wsjt_CXXSRCS}
|
${wsjt_CXXSRCS}
|
||||||
|
${fort_qt_CXXSRCS}
|
||||||
${wsjt_qt_CXXSRCS}
|
${wsjt_qt_CXXSRCS}
|
||||||
${wsjt_qtmm_CXXSRCS}
|
${wsjt_qtmm_CXXSRCS}
|
||||||
${wsjtx_CXXSRCS}
|
${wsjtx_CXXSRCS}
|
||||||
@ -744,7 +748,6 @@ set (all_C_and_CXXSRCS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set (TOP_LEVEL_RESOURCES
|
set (TOP_LEVEL_RESOURCES
|
||||||
cty.dat
|
|
||||||
icons/Darwin/wsjtx.iconset/icon_128x128.png
|
icons/Darwin/wsjtx.iconset/icon_128x128.png
|
||||||
contrib/gpl-v3-logo.svg
|
contrib/gpl-v3-logo.svg
|
||||||
artwork/splash.png
|
artwork/splash.png
|
||||||
@ -926,7 +929,9 @@ endif ()
|
|||||||
if (WSJT_GENERATE_DOCS)
|
if (WSJT_GENERATE_DOCS)
|
||||||
add_subdirectory (doc)
|
add_subdirectory (doc)
|
||||||
endif (WSJT_GENERATE_DOCS)
|
endif (WSJT_GENERATE_DOCS)
|
||||||
|
if (EXISTS ${CMAKE_SOURCE_DIR}/tests AND IS_DIRECTORY ${CMAKE_SOURCE_DIR}/tests)
|
||||||
|
add_subdirectory (tests)
|
||||||
|
endif ()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Library building setup
|
# Library building setup
|
||||||
@ -1256,6 +1261,11 @@ if (WIN32)
|
|||||||
target_link_libraries (wsjt_qt Qt5::AxContainer Qt5::AxBase)
|
target_link_libraries (wsjt_qt Qt5::AxContainer Qt5::AxBase)
|
||||||
endif (WIN32)
|
endif (WIN32)
|
||||||
|
|
||||||
|
# build a library of package Qt functionality used in Fortran utilities
|
||||||
|
add_library (fort_qt STATIC ${fort_qt_CXXSRCS})
|
||||||
|
target_link_libraries (fort_qt Qt5::Core)
|
||||||
|
|
||||||
|
# build a library of WSJT Qt multimedia components
|
||||||
add_library (wsjt_qtmm STATIC ${wsjt_qtmm_CXXSRCS} ${wsjt_qtmm_GENUISRCS})
|
add_library (wsjt_qtmm STATIC ${wsjt_qtmm_CXXSRCS} ${wsjt_qtmm_GENUISRCS})
|
||||||
target_link_libraries (wsjt_qtmm Qt5::Multimedia)
|
target_link_libraries (wsjt_qtmm Qt5::Multimedia)
|
||||||
|
|
||||||
@ -1303,9 +1313,9 @@ if (${OPENMP_FOUND} OR APPLE)
|
|||||||
LINK_FLAGS -Wl,--stack,16777216
|
LINK_FLAGS -Wl,--stack,16777216
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
target_link_libraries (jt9 wsjt_fort_omp wsjt_cxx wsjt_qt)
|
target_link_libraries (jt9 wsjt_fort_omp wsjt_cxx fort_qt)
|
||||||
else (${OPENMP_FOUND} OR APPLE)
|
else (${OPENMP_FOUND} OR APPLE)
|
||||||
target_link_libraries (jt9 wsjt_fort wsjt_cxx Qt5::Core)
|
target_link_libraries (jt9 wsjt_fort wsjt_cxx fort_qt)
|
||||||
endif (${OPENMP_FOUND} OR APPLE)
|
endif (${OPENMP_FOUND} OR APPLE)
|
||||||
|
|
||||||
if(WSJT_BUILD_UTILS)
|
if(WSJT_BUILD_UTILS)
|
||||||
@ -1563,6 +1573,7 @@ install (FILES
|
|||||||
)
|
)
|
||||||
|
|
||||||
install (FILES
|
install (FILES
|
||||||
|
cty.dat
|
||||||
contrib/Ephemeris/JPLEPH
|
contrib/Ephemeris/JPLEPH
|
||||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}
|
||||||
#COMPONENT runtime
|
#COMPONENT runtime
|
||||||
|
@ -137,6 +137,8 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QVariant>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QAudioDeviceInfo>
|
#include <QAudioDeviceInfo>
|
||||||
#include <QAudioInput>
|
#include <QAudioInput>
|
||||||
@ -401,6 +403,7 @@ class Configuration::impl final
|
|||||||
public:
|
public:
|
||||||
using FrequencyDelta = Radio::FrequencyDelta;
|
using FrequencyDelta = Radio::FrequencyDelta;
|
||||||
using port_type = Configuration::port_type;
|
using port_type = Configuration::port_type;
|
||||||
|
using audio_info_type = QPair<QAudioDeviceInfo, QList<QVariant> >;
|
||||||
|
|
||||||
explicit impl (Configuration * self
|
explicit impl (Configuration * self
|
||||||
, QNetworkAccessManager * network_manager
|
, QNetworkAccessManager * network_manager
|
||||||
@ -429,9 +432,14 @@ private:
|
|||||||
void read_settings ();
|
void read_settings ();
|
||||||
void write_settings ();
|
void write_settings ();
|
||||||
|
|
||||||
bool load_audio_devices (QAudio::Mode, QComboBox *, QAudioDeviceInfo *);
|
Q_SLOT void lazy_models_load (int);
|
||||||
|
void find_audio_devices ();
|
||||||
|
QAudioDeviceInfo find_audio_device (QAudio::Mode, QComboBox *, QString const& device_name);
|
||||||
|
void load_audio_devices (QAudio::Mode, QComboBox *, QAudioDeviceInfo *);
|
||||||
void update_audio_channels (QComboBox const *, int, QComboBox *, bool);
|
void update_audio_channels (QComboBox const *, int, QComboBox *, bool);
|
||||||
|
|
||||||
|
void find_tab (QWidget *);
|
||||||
|
|
||||||
void initialize_models ();
|
void initialize_models ();
|
||||||
bool split_mode () const
|
bool split_mode () const
|
||||||
{
|
{
|
||||||
@ -477,8 +485,6 @@ private:
|
|||||||
Q_SLOT void on_force_DTR_combo_box_currentIndexChanged (int);
|
Q_SLOT void on_force_DTR_combo_box_currentIndexChanged (int);
|
||||||
Q_SLOT void on_force_RTS_combo_box_currentIndexChanged (int);
|
Q_SLOT void on_force_RTS_combo_box_currentIndexChanged (int);
|
||||||
Q_SLOT void on_rig_combo_box_currentIndexChanged (int);
|
Q_SLOT void on_rig_combo_box_currentIndexChanged (int);
|
||||||
Q_SLOT void on_sound_input_combo_box_currentTextChanged (QString const&);
|
|
||||||
Q_SLOT void on_sound_output_combo_box_currentTextChanged (QString const&);
|
|
||||||
Q_SLOT void on_add_macro_push_button_clicked (bool = false);
|
Q_SLOT void on_add_macro_push_button_clicked (bool = false);
|
||||||
Q_SLOT void on_delete_macro_push_button_clicked (bool = false);
|
Q_SLOT void on_delete_macro_push_button_clicked (bool = false);
|
||||||
Q_SLOT void on_PTT_method_button_group_buttonClicked (int);
|
Q_SLOT void on_PTT_method_button_group_buttonClicked (int);
|
||||||
@ -647,10 +653,8 @@ private:
|
|||||||
bool pwrBandTuneMemory_;
|
bool pwrBandTuneMemory_;
|
||||||
|
|
||||||
QAudioDeviceInfo audio_input_device_;
|
QAudioDeviceInfo audio_input_device_;
|
||||||
bool default_audio_input_device_selected_;
|
|
||||||
AudioDevice::Channel audio_input_channel_;
|
AudioDevice::Channel audio_input_channel_;
|
||||||
QAudioDeviceInfo audio_output_device_;
|
QAudioDeviceInfo audio_output_device_;
|
||||||
bool default_audio_output_device_selected_;
|
|
||||||
AudioDevice::Channel audio_output_channel_;
|
AudioDevice::Channel audio_output_channel_;
|
||||||
|
|
||||||
friend class Configuration;
|
friend class Configuration;
|
||||||
@ -976,8 +980,6 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
|||||||
, transceiver_command_number_ {0}
|
, transceiver_command_number_ {0}
|
||||||
, degrade_ {0.} // initialize to zero each run, not
|
, degrade_ {0.} // initialize to zero each run, not
|
||||||
// saved in settings
|
// saved in settings
|
||||||
, default_audio_input_device_selected_ {false}
|
|
||||||
, default_audio_output_device_selected_ {false}
|
|
||||||
{
|
{
|
||||||
ui_->setupUi (this);
|
ui_->setupUi (this);
|
||||||
|
|
||||||
@ -1100,6 +1102,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
|||||||
//
|
//
|
||||||
// setup hooks to keep audio channels aligned with devices
|
// setup hooks to keep audio channels aligned with devices
|
||||||
//
|
//
|
||||||
|
connect (ui_->configuration_tabs, &QTabWidget::currentChanged, this, &Configuration::impl::lazy_models_load);
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
@ -1130,7 +1133,9 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
|||||||
|
|
||||||
ui_->frequencies_table_view->setModel (&next_frequencies_);
|
ui_->frequencies_table_view->setModel (&next_frequencies_);
|
||||||
ui_->frequencies_table_view->horizontalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
ui_->frequencies_table_view->horizontalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
|
ui_->frequencies_table_view->horizontalHeader ()->setResizeContentsPrecision (0);
|
||||||
ui_->frequencies_table_view->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
ui_->frequencies_table_view->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
|
ui_->frequencies_table_view->verticalHeader ()->setResizeContentsPrecision (0);
|
||||||
ui_->frequencies_table_view->sortByColumn (FrequencyList_v2::frequency_column, Qt::AscendingOrder);
|
ui_->frequencies_table_view->sortByColumn (FrequencyList_v2::frequency_column, Qt::AscendingOrder);
|
||||||
ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::frequency_mhz_column, true);
|
ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::frequency_mhz_column, true);
|
||||||
|
|
||||||
@ -1170,7 +1175,9 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
|||||||
stations_.sort (StationList::band_column);
|
stations_.sort (StationList::band_column);
|
||||||
ui_->stations_table_view->setModel (&next_stations_);
|
ui_->stations_table_view->setModel (&next_stations_);
|
||||||
ui_->stations_table_view->horizontalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
ui_->stations_table_view->horizontalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
|
ui_->stations_table_view->horizontalHeader ()->setResizeContentsPrecision (0);
|
||||||
ui_->stations_table_view->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
ui_->stations_table_view->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
|
ui_->stations_table_view->verticalHeader ()->setResizeContentsPrecision (0);
|
||||||
ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder);
|
ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder);
|
||||||
|
|
||||||
// stations delegates
|
// stations delegates
|
||||||
@ -1189,20 +1196,8 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
|||||||
//
|
//
|
||||||
ui_->highlighting_list_view->setModel (&next_decode_highlighing_model_);
|
ui_->highlighting_list_view->setModel (&next_decode_highlighing_model_);
|
||||||
|
|
||||||
//
|
|
||||||
// load combo boxes with audio setup choices
|
|
||||||
//
|
|
||||||
default_audio_input_device_selected_ = load_audio_devices (QAudio::AudioInput, ui_->sound_input_combo_box, &audio_input_device_);
|
|
||||||
default_audio_output_device_selected_ = load_audio_devices (QAudio::AudioOutput, ui_->sound_output_combo_box, &audio_output_device_);
|
|
||||||
|
|
||||||
update_audio_channels (ui_->sound_input_combo_box, ui_->sound_input_combo_box->currentIndex (), ui_->sound_input_channel_combo_box, false);
|
|
||||||
update_audio_channels (ui_->sound_output_combo_box, ui_->sound_output_combo_box->currentIndex (), ui_->sound_output_channel_combo_box, true);
|
|
||||||
|
|
||||||
ui_->sound_input_channel_combo_box->setCurrentIndex (audio_input_channel_);
|
|
||||||
ui_->sound_output_channel_combo_box->setCurrentIndex (audio_output_channel_);
|
|
||||||
|
|
||||||
enumerate_rigs ();
|
enumerate_rigs ();
|
||||||
initialize_models ();
|
// initialize_models ();
|
||||||
|
|
||||||
transceiver_thread_ = new QThread {this};
|
transceiver_thread_ = new QThread {this};
|
||||||
transceiver_thread_->start ();
|
transceiver_thread_->start ();
|
||||||
@ -1215,8 +1210,35 @@ Configuration::impl::~impl ()
|
|||||||
write_settings ();
|
write_settings ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::impl::lazy_models_load (int current_tab_index)
|
||||||
|
{
|
||||||
|
switch (current_tab_index)
|
||||||
|
{
|
||||||
|
case 2: // Audio
|
||||||
|
//
|
||||||
|
// load combo boxes with audio setup choices
|
||||||
|
//
|
||||||
|
load_audio_devices (QAudio::AudioInput, ui_->sound_input_combo_box, &audio_input_device_);
|
||||||
|
load_audio_devices (QAudio::AudioOutput, ui_->sound_output_combo_box, &audio_output_device_);
|
||||||
|
|
||||||
|
update_audio_channels (ui_->sound_input_combo_box, ui_->sound_input_combo_box->currentIndex (), ui_->sound_input_channel_combo_box, false);
|
||||||
|
update_audio_channels (ui_->sound_output_combo_box, ui_->sound_output_combo_box->currentIndex (), ui_->sound_output_channel_combo_box, true);
|
||||||
|
|
||||||
|
ui_->sound_input_channel_combo_box->setCurrentIndex (audio_input_channel_);
|
||||||
|
ui_->sound_output_channel_combo_box->setCurrentIndex (audio_output_channel_);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Configuration::impl::initialize_models ()
|
void Configuration::impl::initialize_models ()
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
SettingsGroup g {settings_, "Configuration"};
|
||||||
|
find_audio_devices ();
|
||||||
|
}
|
||||||
auto pal = ui_->callsign_line_edit->palette ();
|
auto pal = ui_->callsign_line_edit->palette ();
|
||||||
if (my_callsign_.isEmpty ())
|
if (my_callsign_.isEmpty ())
|
||||||
{
|
{
|
||||||
@ -1238,6 +1260,7 @@ void Configuration::impl::initialize_models ()
|
|||||||
ui_->sbDegrade->setValue (degrade_);
|
ui_->sbDegrade->setValue (degrade_);
|
||||||
ui_->sbBandwidth->setValue (RxBandwidth_);
|
ui_->sbBandwidth->setValue (RxBandwidth_);
|
||||||
ui_->PTT_method_button_group->button (rig_params_.ptt_type)->setChecked (true);
|
ui_->PTT_method_button_group->button (rig_params_.ptt_type)->setChecked (true);
|
||||||
|
|
||||||
ui_->save_path_display_label->setText (save_directory_.absolutePath ());
|
ui_->save_path_display_label->setText (save_directory_.absolutePath ());
|
||||||
ui_->azel_path_display_label->setText (azel_directory_.absolutePath ());
|
ui_->azel_path_display_label->setText (azel_directory_.absolutePath ());
|
||||||
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
|
ui_->CW_id_after_73_check_box->setChecked (id_after_73_);
|
||||||
@ -1390,61 +1413,7 @@ void Configuration::impl::read_settings ()
|
|||||||
save_directory_.setPath (settings_->value ("SaveDir", default_save_directory_.absolutePath ()).toString ());
|
save_directory_.setPath (settings_->value ("SaveDir", default_save_directory_.absolutePath ()).toString ());
|
||||||
azel_directory_.setPath (settings_->value ("AzElDir", default_azel_directory_.absolutePath ()).toString ());
|
azel_directory_.setPath (settings_->value ("AzElDir", default_azel_directory_.absolutePath ()).toString ());
|
||||||
|
|
||||||
{
|
find_audio_devices ();
|
||||||
//
|
|
||||||
// retrieve audio input device
|
|
||||||
//
|
|
||||||
auto saved_name = settings_->value ("SoundInName").toString ();
|
|
||||||
|
|
||||||
// deal with special Windows default audio devices
|
|
||||||
auto default_device = QAudioDeviceInfo::defaultInputDevice ();
|
|
||||||
if (saved_name == default_device.deviceName ())
|
|
||||||
{
|
|
||||||
audio_input_device_ = default_device;
|
|
||||||
default_audio_input_device_selected_ = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
default_audio_input_device_selected_ = false;
|
|
||||||
Q_FOREACH (auto const& p, QAudioDeviceInfo::availableDevices (QAudio::AudioInput)) // available audio input devices
|
|
||||||
{
|
|
||||||
if (p.deviceName () == saved_name)
|
|
||||||
{
|
|
||||||
audio_input_device_ = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// retrieve audio output device
|
|
||||||
//
|
|
||||||
auto saved_name = settings_->value("SoundOutName").toString();
|
|
||||||
|
|
||||||
// deal with special Windows default audio devices
|
|
||||||
auto default_device = QAudioDeviceInfo::defaultOutputDevice ();
|
|
||||||
if (saved_name == default_device.deviceName ())
|
|
||||||
{
|
|
||||||
audio_output_device_ = default_device;
|
|
||||||
default_audio_output_device_selected_ = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
default_audio_output_device_selected_ = false;
|
|
||||||
Q_FOREACH (auto const& p, QAudioDeviceInfo::availableDevices (QAudio::AudioOutput)) // available audio output devices
|
|
||||||
{
|
|
||||||
if (p.deviceName () == saved_name)
|
|
||||||
{
|
|
||||||
audio_output_device_ = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve audio channel info
|
|
||||||
audio_input_channel_ = AudioDevice::fromString (settings_->value ("AudioInputChannel", "Mono").toString ());
|
|
||||||
audio_output_channel_ = AudioDevice::fromString (settings_->value ("AudioOutputChannel", "Mono").toString ());
|
|
||||||
|
|
||||||
type_2_msg_gen_ = settings_->value ("Type2MsgGen", QVariant::fromValue (Configuration::type_2_msg_3_full)).value<Configuration::Type2MsgGen> ();
|
type_2_msg_gen_ = settings_->value ("Type2MsgGen", QVariant::fromValue (Configuration::type_2_msg_3_full)).value<Configuration::Type2MsgGen> ();
|
||||||
|
|
||||||
@ -1547,6 +1516,27 @@ void Configuration::impl::read_settings ()
|
|||||||
pwrBandTuneMemory_ = settings_->value("pwrBandTuneMemory",false).toBool ();
|
pwrBandTuneMemory_ = settings_->value("pwrBandTuneMemory",false).toBool ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::impl::find_audio_devices ()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// retrieve audio input device
|
||||||
|
//
|
||||||
|
auto saved_name = settings_->value ("SoundInName").toString ();
|
||||||
|
audio_input_device_ = find_audio_device (QAudio::AudioInput, ui_->sound_input_combo_box, saved_name);
|
||||||
|
audio_input_channel_ = AudioDevice::fromString (settings_->value ("AudioInputChannel", "Mono").toString ());
|
||||||
|
update_audio_channels (ui_->sound_input_combo_box, ui_->sound_input_combo_box->currentIndex (), ui_->sound_input_channel_combo_box, false);
|
||||||
|
ui_->sound_input_channel_combo_box->setCurrentIndex (audio_input_channel_);
|
||||||
|
|
||||||
|
//
|
||||||
|
// retrieve audio output device
|
||||||
|
//
|
||||||
|
saved_name = settings_->value("SoundOutName").toString();
|
||||||
|
audio_output_channel_ = AudioDevice::fromString (settings_->value ("AudioOutputChannel", "Mono").toString ());
|
||||||
|
audio_output_device_ = find_audio_device (QAudio::AudioOutput, ui_->sound_output_combo_box, saved_name);
|
||||||
|
update_audio_channels (ui_->sound_output_combo_box, ui_->sound_output_combo_box->currentIndex (), ui_->sound_output_channel_combo_box, true);
|
||||||
|
ui_->sound_output_channel_combo_box->setCurrentIndex (audio_output_channel_);
|
||||||
|
}
|
||||||
|
|
||||||
void Configuration::impl::write_settings ()
|
void Configuration::impl::write_settings ()
|
||||||
{
|
{
|
||||||
SettingsGroup g {settings_, "Configuration"};
|
SettingsGroup g {settings_, "Configuration"};
|
||||||
@ -1566,25 +1556,8 @@ void Configuration::impl::write_settings ()
|
|||||||
settings_->setValue ("PTTport", rig_params_.ptt_port);
|
settings_->setValue ("PTTport", rig_params_.ptt_port);
|
||||||
settings_->setValue ("SaveDir", save_directory_.absolutePath ());
|
settings_->setValue ("SaveDir", save_directory_.absolutePath ());
|
||||||
settings_->setValue ("AzElDir", azel_directory_.absolutePath ());
|
settings_->setValue ("AzElDir", azel_directory_.absolutePath ());
|
||||||
|
|
||||||
if (default_audio_input_device_selected_)
|
|
||||||
{
|
|
||||||
settings_->setValue ("SoundInName", QAudioDeviceInfo::defaultInputDevice ().deviceName ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
settings_->setValue ("SoundInName", audio_input_device_.deviceName ());
|
settings_->setValue ("SoundInName", audio_input_device_.deviceName ());
|
||||||
}
|
|
||||||
|
|
||||||
if (default_audio_output_device_selected_)
|
|
||||||
{
|
|
||||||
settings_->setValue ("SoundOutName", QAudioDeviceInfo::defaultOutputDevice ().deviceName ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
settings_->setValue ("SoundOutName", audio_output_device_.deviceName ());
|
settings_->setValue ("SoundOutName", audio_output_device_.deviceName ());
|
||||||
}
|
|
||||||
|
|
||||||
settings_->setValue ("AudioInputChannel", AudioDevice::toString (audio_input_channel_));
|
settings_->setValue ("AudioInputChannel", AudioDevice::toString (audio_input_channel_));
|
||||||
settings_->setValue ("AudioOutputChannel", AudioDevice::toString (audio_output_channel_));
|
settings_->setValue ("AudioOutputChannel", AudioDevice::toString (audio_output_channel_));
|
||||||
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
|
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
|
||||||
@ -1658,6 +1631,7 @@ void Configuration::impl::write_settings ()
|
|||||||
settings_->setValue ("pwrBandTuneMemory", pwrBandTuneMemory_);
|
settings_->setValue ("pwrBandTuneMemory", pwrBandTuneMemory_);
|
||||||
settings_->setValue ("Region", QVariant::fromValue (region_));
|
settings_->setValue ("Region", QVariant::fromValue (region_));
|
||||||
settings_->setValue ("AutoGrid", use_dynamic_grid_);
|
settings_->setValue ("AutoGrid", use_dynamic_grid_);
|
||||||
|
settings_->sync ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::impl::set_rig_invariants ()
|
void Configuration::impl::set_rig_invariants ()
|
||||||
@ -1790,17 +1764,27 @@ void Configuration::impl::set_rig_invariants ()
|
|||||||
bool Configuration::impl::validate ()
|
bool Configuration::impl::validate ()
|
||||||
{
|
{
|
||||||
if (ui_->sound_input_combo_box->currentIndex () < 0
|
if (ui_->sound_input_combo_box->currentIndex () < 0
|
||||||
&& !QAudioDeviceInfo::availableDevices (QAudio::AudioInput).empty ())
|
&& audio_input_device_.isNull ())
|
||||||
{
|
{
|
||||||
|
find_tab (ui_->sound_input_combo_box);
|
||||||
|
MessageBox::critical_message (this, tr ("Invalid audio input device"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ui_->sound_input_channel_combo_box->currentIndex () < 0
|
||||||
|
&& audio_input_device_.isNull ())
|
||||||
|
{
|
||||||
|
find_tab (ui_->sound_input_combo_box);
|
||||||
MessageBox::critical_message (this, tr ("Invalid audio input device"));
|
MessageBox::critical_message (this, tr ("Invalid audio input device"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui_->sound_output_combo_box->currentIndex () < 0
|
if (ui_->sound_output_combo_box->currentIndex () < 0
|
||||||
&& !QAudioDeviceInfo::availableDevices (QAudio::AudioOutput).empty ())
|
&& audio_output_device_.isNull ())
|
||||||
{
|
{
|
||||||
MessageBox::critical_message (this, tr ("Invalid audio out device"));
|
find_tab (ui_->sound_output_combo_box);
|
||||||
return false;
|
MessageBox::information_message (this, tr ("Invalid audio output device"));
|
||||||
|
// don't reject as we can work without an audio output
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ui_->PTT_method_button_group->checkedButton ()->isEnabled ())
|
if (!ui_->PTT_method_button_group->checkedButton ()->isEnabled ())
|
||||||
@ -1822,16 +1806,7 @@ bool Configuration::impl::validate ()
|
|||||||
if (ui_->rbField_Day->isEnabled () && ui_->rbField_Day->isChecked () &&
|
if (ui_->rbField_Day->isEnabled () && ui_->rbField_Day->isChecked () &&
|
||||||
!ui_->Field_Day_Exchange->hasAcceptableInput ())
|
!ui_->Field_Day_Exchange->hasAcceptableInput ())
|
||||||
{
|
{
|
||||||
for (auto * parent = ui_->Field_Day_Exchange->parentWidget (); parent; parent = parent->parentWidget ())
|
find_tab (ui_->Field_Day_Exchange);
|
||||||
{
|
|
||||||
auto index = ui_->configuration_tabs->indexOf (parent);
|
|
||||||
if (index != -1)
|
|
||||||
{
|
|
||||||
ui_->configuration_tabs->setCurrentIndex (index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui_->Field_Day_Exchange->setFocus ();
|
|
||||||
MessageBox::critical_message (this, tr ("Invalid Contest Exchange")
|
MessageBox::critical_message (this, tr ("Invalid Contest Exchange")
|
||||||
, tr ("You must input a valid ARRL Field Day exchange"));
|
, tr ("You must input a valid ARRL Field Day exchange"));
|
||||||
return false;
|
return false;
|
||||||
@ -1840,16 +1815,7 @@ bool Configuration::impl::validate ()
|
|||||||
if (ui_->rbRTTY_Roundup->isEnabled () && ui_->rbRTTY_Roundup->isChecked () &&
|
if (ui_->rbRTTY_Roundup->isEnabled () && ui_->rbRTTY_Roundup->isChecked () &&
|
||||||
!ui_->RTTY_Exchange->hasAcceptableInput ())
|
!ui_->RTTY_Exchange->hasAcceptableInput ())
|
||||||
{
|
{
|
||||||
for (auto * parent = ui_->RTTY_Exchange->parentWidget (); parent; parent = parent->parentWidget ())
|
find_tab (ui_->RTTY_Exchange);
|
||||||
{
|
|
||||||
auto index = ui_->configuration_tabs->indexOf (parent);
|
|
||||||
if (index != -1)
|
|
||||||
{
|
|
||||||
ui_->configuration_tabs->setCurrentIndex (index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui_->RTTY_Exchange->setFocus ();
|
|
||||||
MessageBox::critical_message (this, tr ("Invalid Contest Exchange")
|
MessageBox::critical_message (this, tr ("Invalid Contest Exchange")
|
||||||
, tr ("You must input a valid ARRL RTTY Roundup exchange"));
|
, tr ("You must input a valid ARRL RTTY Roundup exchange"));
|
||||||
return false;
|
return false;
|
||||||
@ -1970,59 +1936,19 @@ void Configuration::impl::accept ()
|
|||||||
// Check to see whether SoundInThread must be restarted,
|
// Check to see whether SoundInThread must be restarted,
|
||||||
// and save user parameters.
|
// and save user parameters.
|
||||||
{
|
{
|
||||||
auto const& device_name = ui_->sound_input_combo_box->currentText ();
|
auto const& selected_device = ui_->sound_input_combo_box->currentData ().value<audio_info_type> ().first;
|
||||||
if (device_name != audio_input_device_.deviceName ())
|
if (selected_device != audio_input_device_)
|
||||||
{
|
{
|
||||||
auto const& default_device = QAudioDeviceInfo::defaultInputDevice ();
|
audio_input_device_ = selected_device;
|
||||||
if (device_name == default_device.deviceName ())
|
|
||||||
{
|
|
||||||
audio_input_device_ = default_device;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool found {false};
|
|
||||||
Q_FOREACH (auto const& d, QAudioDeviceInfo::availableDevices (QAudio::AudioInput))
|
|
||||||
{
|
|
||||||
if (device_name == d.deviceName ())
|
|
||||||
{
|
|
||||||
audio_input_device_ = d;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
audio_input_device_ = default_device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
restart_sound_input_device_ = true;
|
restart_sound_input_device_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto const& device_name = ui_->sound_output_combo_box->currentText ();
|
auto const& selected_device = ui_->sound_output_combo_box->currentData ().value<audio_info_type> ().first;
|
||||||
if (device_name != audio_output_device_.deviceName ())
|
if (selected_device != audio_output_device_)
|
||||||
{
|
{
|
||||||
auto const& default_device = QAudioDeviceInfo::defaultOutputDevice ();
|
audio_output_device_ = selected_device;
|
||||||
if (device_name == default_device.deviceName ())
|
|
||||||
{
|
|
||||||
audio_output_device_ = default_device;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool found {false};
|
|
||||||
Q_FOREACH (auto const& d, QAudioDeviceInfo::availableDevices (QAudio::AudioOutput))
|
|
||||||
{
|
|
||||||
if (device_name == d.deviceName ())
|
|
||||||
{
|
|
||||||
audio_output_device_ = d;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
audio_output_device_ = default_device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
restart_sound_output_device_ = true;
|
restart_sound_output_device_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2306,16 +2232,6 @@ void Configuration::impl::on_PTT_method_button_group_buttonClicked (int /* id */
|
|||||||
set_rig_invariants ();
|
set_rig_invariants ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Configuration::impl::on_sound_input_combo_box_currentTextChanged (QString const& text)
|
|
||||||
{
|
|
||||||
default_audio_input_device_selected_ = QAudioDeviceInfo::defaultInputDevice ().deviceName () == text;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Configuration::impl::on_sound_output_combo_box_currentTextChanged (QString const& text)
|
|
||||||
{
|
|
||||||
default_audio_output_device_selected_ = QAudioDeviceInfo::defaultOutputDevice ().deviceName () == text;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Configuration::impl::on_add_macro_line_edit_editingFinished ()
|
void Configuration::impl::on_add_macro_line_edit_editingFinished ()
|
||||||
{
|
{
|
||||||
ui_->add_macro_line_edit->setText (ui_->add_macro_line_edit->text ().toUpper ());
|
ui_->add_macro_line_edit->setText (ui_->add_macro_line_edit->text ().toUpper ());
|
||||||
@ -2694,6 +2610,7 @@ void Configuration::impl::transceiver_frequency (Frequency f)
|
|||||||
current_offset_ = stations_.offset (f);
|
current_offset_ = stations_.offset (f);
|
||||||
cached_rig_state_.frequency (apply_calibration (f + current_offset_));
|
cached_rig_state_.frequency (apply_calibration (f + current_offset_));
|
||||||
|
|
||||||
|
qDebug () << "Configuration::impl::transceiver_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
|
||||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2719,6 +2636,7 @@ void Configuration::impl::transceiver_tx_frequency (Frequency f)
|
|||||||
cached_rig_state_.tx_frequency (apply_calibration (f + current_tx_offset_));
|
cached_rig_state_.tx_frequency (apply_calibration (f + current_tx_offset_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug () << "Configuration::impl::transceiver_tx_frequency: n:" << transceiver_command_number_ + 1 << "f:" << f;
|
||||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2727,6 +2645,7 @@ void Configuration::impl::transceiver_mode (MODE m)
|
|||||||
{
|
{
|
||||||
cached_rig_state_.online (true); // we want the rig online
|
cached_rig_state_.online (true); // we want the rig online
|
||||||
cached_rig_state_.mode (m);
|
cached_rig_state_.mode (m);
|
||||||
|
qDebug () << "Configuration::impl::transceiver_mode: n:" << transceiver_command_number_ + 1 << "m:" << m;
|
||||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2735,6 +2654,7 @@ void Configuration::impl::transceiver_ptt (bool on)
|
|||||||
cached_rig_state_.online (true); // we want the rig online
|
cached_rig_state_.online (true); // we want the rig online
|
||||||
set_cached_mode ();
|
set_cached_mode ();
|
||||||
cached_rig_state_.ptt (on);
|
cached_rig_state_.ptt (on);
|
||||||
|
qDebug () << "Configuration::impl::transceiver_ptt: n:" << transceiver_command_number_ + 1 << "on:" << on;
|
||||||
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
Q_EMIT set_transceiver (cached_rig_state_, ++transceiver_command_number_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2833,72 +2753,67 @@ void Configuration::impl::close_rig ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the available audio devices into the selection combo box and
|
// find the audio device that matches the specified name, also
|
||||||
// select the default device if the current device isn't set or isn't
|
// populate into the selection combo box with any devices we find in
|
||||||
// available
|
// the search
|
||||||
bool Configuration::impl::load_audio_devices (QAudio::Mode mode, QComboBox * combo_box, QAudioDeviceInfo * device)
|
QAudioDeviceInfo Configuration::impl::find_audio_device (QAudio::Mode mode, QComboBox * combo_box
|
||||||
|
, QString const& device_name)
|
||||||
{
|
{
|
||||||
using std::copy;
|
using std::copy;
|
||||||
using std::back_inserter;
|
using std::back_inserter;
|
||||||
|
|
||||||
bool result {false};
|
|
||||||
|
|
||||||
combo_box->clear ();
|
combo_box->clear ();
|
||||||
|
|
||||||
int current_index = -1;
|
int current_index = -1;
|
||||||
int default_index = -1;
|
auto const& devices = QAudioDeviceInfo::availableDevices (mode);
|
||||||
|
Q_FOREACH (auto const& p, devices)
|
||||||
int extra_items {0};
|
|
||||||
|
|
||||||
auto const& default_device = (mode == QAudio::AudioInput ? QAudioDeviceInfo::defaultInputDevice () : QAudioDeviceInfo::defaultOutputDevice ());
|
|
||||||
|
|
||||||
// deal with special default audio devices on Windows
|
|
||||||
if ("Default Input Device" == default_device.deviceName ()
|
|
||||||
|| "Default Output Device" == default_device.deviceName ())
|
|
||||||
{
|
{
|
||||||
default_index = 0;
|
// qDebug () << "Audio device: input:" << (QAudio::AudioInput == mode) << "name:" << p.deviceName () << "preferred format:" << p.preferredFormat () << "endians:" << p.supportedByteOrders () << "codecs:" << p.supportedCodecs () << "channels:" << p.supportedChannelCounts () << "rates:" << p.supportedSampleRates () << "sizes:" << p.supportedSampleSizes () << "types:" << p.supportedSampleTypes ();
|
||||||
|
|
||||||
QList<QVariant> channel_counts;
|
|
||||||
auto scc = default_device.supportedChannelCounts ();
|
|
||||||
copy (scc.cbegin (), scc.cend (), back_inserter (channel_counts));
|
|
||||||
|
|
||||||
combo_box->addItem (default_device.deviceName (), channel_counts);
|
|
||||||
++extra_items;
|
|
||||||
if (default_device == *device)
|
|
||||||
{
|
|
||||||
current_index = 0;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_FOREACH (auto const& p, QAudioDeviceInfo::availableDevices (mode))
|
|
||||||
{
|
|
||||||
// qDebug () << "Audio device: input:" << (QAudio::AudioInput == mode) << "name:" << p.deviceName () << "preferred format:" << p.preferredFormat () << "endians:" << p.supportedByteOrders () << "codecs:" << p.supportedCodecs () << "channels:" << p.supportedChannelCounts () << "rates:" << p.supportedSampleRates () << "sizes:" << p.supportedSampleSizes () << "types:" << p.supportedSampleTypes ();
|
|
||||||
|
|
||||||
// convert supported channel counts into something we can store in the item model
|
// convert supported channel counts into something we can store in the item model
|
||||||
QList<QVariant> channel_counts;
|
QList<QVariant> channel_counts;
|
||||||
auto scc = p.supportedChannelCounts ();
|
auto scc = p.supportedChannelCounts ();
|
||||||
copy (scc.cbegin (), scc.cend (), back_inserter (channel_counts));
|
copy (scc.cbegin (), scc.cend (), back_inserter (channel_counts));
|
||||||
|
|
||||||
combo_box->addItem (p.deviceName (), channel_counts);
|
combo_box->addItem (p.deviceName (), QVariant::fromValue (audio_info_type {p, channel_counts}));
|
||||||
|
if (p.deviceName () == device_name)
|
||||||
|
{
|
||||||
|
current_index = combo_box->count () - 1;
|
||||||
|
combo_box->setCurrentIndex (current_index);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
combo_box->setCurrentIndex (current_index);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the available audio devices into the selection combo box
|
||||||
|
void Configuration::impl::load_audio_devices (QAudio::Mode mode, QComboBox * combo_box
|
||||||
|
, QAudioDeviceInfo * device)
|
||||||
|
{
|
||||||
|
using std::copy;
|
||||||
|
using std::back_inserter;
|
||||||
|
|
||||||
|
combo_box->clear ();
|
||||||
|
|
||||||
|
int current_index = -1;
|
||||||
|
auto const& devices = QAudioDeviceInfo::availableDevices (mode);
|
||||||
|
Q_FOREACH (auto const& p, devices)
|
||||||
|
{
|
||||||
|
// qDebug () << "Audio device: input:" << (QAudio::AudioInput == mode) << "name:" << p.deviceName () << "preferred format:" << p.preferredFormat () << "endians:" << p.supportedByteOrders () << "codecs:" << p.supportedCodecs () << "channels:" << p.supportedChannelCounts () << "rates:" << p.supportedSampleRates () << "sizes:" << p.supportedSampleSizes () << "types:" << p.supportedSampleTypes ();
|
||||||
|
|
||||||
|
// convert supported channel counts into something we can store in the item model
|
||||||
|
QList<QVariant> channel_counts;
|
||||||
|
auto scc = p.supportedChannelCounts ();
|
||||||
|
copy (scc.cbegin (), scc.cend (), back_inserter (channel_counts));
|
||||||
|
|
||||||
|
combo_box->addItem (p.deviceName (), QVariant::fromValue (audio_info_type {p, channel_counts}));
|
||||||
if (p == *device)
|
if (p == *device)
|
||||||
{
|
{
|
||||||
current_index = combo_box->count () - 1;
|
current_index = combo_box->count () - 1;
|
||||||
}
|
}
|
||||||
else if (p == default_device)
|
|
||||||
{
|
|
||||||
default_index = combo_box->count () - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (current_index < 0) // not found - use default
|
|
||||||
{
|
|
||||||
*device = default_device;
|
|
||||||
result = true;
|
|
||||||
current_index = default_index;
|
|
||||||
}
|
}
|
||||||
combo_box->setCurrentIndex (current_index);
|
combo_box->setCurrentIndex (current_index);
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable only the channels that are supported by the selected audio device
|
// enable only the channels that are supported by the selected audio device
|
||||||
@ -2910,7 +2825,8 @@ void Configuration::impl::update_audio_channels (QComboBox const * source_combo_
|
|||||||
combo_box->setItemData (i, combo_box_item_disabled, Qt::UserRole - 1);
|
combo_box->setItemData (i, combo_box_item_disabled, Qt::UserRole - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (QVariant const& v, source_combo_box->itemData (index).toList ())
|
Q_FOREACH (QVariant const& v
|
||||||
|
, (source_combo_box->itemData (index).value<audio_info_type> ().second))
|
||||||
{
|
{
|
||||||
// enable valid options
|
// enable valid options
|
||||||
int n {v.toInt ()};
|
int n {v.toInt ()};
|
||||||
@ -2930,6 +2846,20 @@ void Configuration::impl::update_audio_channels (QComboBox const * source_combo_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::impl::find_tab (QWidget * target)
|
||||||
|
{
|
||||||
|
for (auto * parent = target->parentWidget (); parent; parent = parent->parentWidget ())
|
||||||
|
{
|
||||||
|
auto index = ui_->configuration_tabs->indexOf (parent);
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
ui_->configuration_tabs->setCurrentIndex (index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target->setFocus ();
|
||||||
|
}
|
||||||
|
|
||||||
// load all the supported rig names into the selection combo box
|
// load all the supported rig names into the selection combo box
|
||||||
void Configuration::impl::enumerate_rigs ()
|
void Configuration::impl::enumerate_rigs ()
|
||||||
{
|
{
|
||||||
|
154
Configuration.ui
154
Configuration.ui
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>559</width>
|
<width>554</width>
|
||||||
<height>553</height>
|
<height>557</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -1349,33 +1349,13 @@ radio interface behave as expected.</string>
|
|||||||
<string>Soundcard</string>
|
<string>Soundcard</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_6">
|
<layout class="QGridLayout" name="gridLayout_6">
|
||||||
<item row="1" column="1">
|
<item row="1" column="0">
|
||||||
<widget class="QComboBox" name="sound_output_combo_box">
|
<widget class="QLabel" name="sound_output_label">
|
||||||
<property name="sizePolicy">
|
<property name="text">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<string>Ou&tput:</string>
|
||||||
<horstretch>1</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="buddy">
|
||||||
<string>Select the audio CODEC to use for transmitting.
|
<cstring>sound_output_combo_box</cstring>
|
||||||
If this is your default device for system sounds then
|
|
||||||
ensure that all system sounds are disabled otherwise
|
|
||||||
you will broadcast any systems sounds generated during
|
|
||||||
transmitting periods.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="sound_input_combo_box">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>1</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select the audio CODEC to use for receiving.</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -1389,33 +1369,6 @@ transmitting periods.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QComboBox" name="sound_input_channel_combo_box">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select the channel to use for receiving.</string>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Mono</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Left</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Right</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Both</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<widget class="QComboBox" name="sound_output_channel_combo_box">
|
<widget class="QComboBox" name="sound_output_channel_combo_box">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
@ -1446,14 +1399,61 @@ both here.</string>
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="sound_output_label">
|
<widget class="QComboBox" name="sound_input_combo_box">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Select the audio CODEC to use for receiving.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="sound_output_combo_box">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Select the audio CODEC to use for transmitting.
|
||||||
|
If this is your default device for system sounds then
|
||||||
|
ensure that all system sounds are disabled otherwise
|
||||||
|
you will broadcast any systems sounds generated during
|
||||||
|
transmitting periods.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QComboBox" name="sound_input_channel_combo_box">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Select the channel to use for receiving.</string>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Ou&tput:</string>
|
<string>Mono</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
</item>
|
||||||
<cstring>sound_output_combo_box</cstring>
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Left</string>
|
||||||
</property>
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Right</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Both</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -1493,7 +1493,8 @@ both here.</string>
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
<string notr="true">background-color: rgb(255, 255, 255);
|
||||||
|
color: rgb(0, 0, 0);</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
@ -1541,7 +1542,8 @@ both here.</string>
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
<string notr="true">background-color: rgb(255, 255, 255);
|
||||||
|
color: rgb(0, 0, 0);</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
@ -2949,14 +2951,20 @@ Right click for insert and delete options.</string>
|
|||||||
<tabstop>use_dynamic_grid</tabstop>
|
<tabstop>use_dynamic_grid</tabstop>
|
||||||
<tabstop>region_combo_box</tabstop>
|
<tabstop>region_combo_box</tabstop>
|
||||||
<tabstop>type_2_msg_gen_combo_box</tabstop>
|
<tabstop>type_2_msg_gen_combo_box</tabstop>
|
||||||
|
<tabstop>decodes_from_top_check_box</tabstop>
|
||||||
|
<tabstop>insert_blank_check_box</tabstop>
|
||||||
|
<tabstop>miles_check_box</tabstop>
|
||||||
<tabstop>TX_messages_check_box</tabstop>
|
<tabstop>TX_messages_check_box</tabstop>
|
||||||
<tabstop>DXCC_check_box</tabstop>
|
<tabstop>DXCC_check_box</tabstop>
|
||||||
|
<tabstop>ppfx_check_box</tabstop>
|
||||||
<tabstop>font_push_button</tabstop>
|
<tabstop>font_push_button</tabstop>
|
||||||
<tabstop>decoded_text_font_push_button</tabstop>
|
<tabstop>decoded_text_font_push_button</tabstop>
|
||||||
<tabstop>monitor_off_check_box</tabstop>
|
<tabstop>monitor_off_check_box</tabstop>
|
||||||
<tabstop>monitor_last_used_check_box</tabstop>
|
<tabstop>monitor_last_used_check_box</tabstop>
|
||||||
<tabstop>quick_call_check_box</tabstop>
|
<tabstop>quick_call_check_box</tabstop>
|
||||||
<tabstop>disable_TX_on_73_check_box</tabstop>
|
<tabstop>disable_TX_on_73_check_box</tabstop>
|
||||||
|
<tabstop>force_call_1st_check_box</tabstop>
|
||||||
|
<tabstop>alternate_bindings_check_box</tabstop>
|
||||||
<tabstop>CW_id_after_73_check_box</tabstop>
|
<tabstop>CW_id_after_73_check_box</tabstop>
|
||||||
<tabstop>enable_VHF_features_check_box</tabstop>
|
<tabstop>enable_VHF_features_check_box</tabstop>
|
||||||
<tabstop>tx_QSY_check_box</tabstop>
|
<tabstop>tx_QSY_check_box</tabstop>
|
||||||
@ -2975,8 +2983,8 @@ Right click for insert and delete options.</string>
|
|||||||
<tabstop>CAT_one_stop_bit_radio_button</tabstop>
|
<tabstop>CAT_one_stop_bit_radio_button</tabstop>
|
||||||
<tabstop>CAT_two_stop_bit_radio_button</tabstop>
|
<tabstop>CAT_two_stop_bit_radio_button</tabstop>
|
||||||
<tabstop>CAT_handshake_default_radio_button</tabstop>
|
<tabstop>CAT_handshake_default_radio_button</tabstop>
|
||||||
<tabstop>CAT_handshake_none_radio_button</tabstop>
|
|
||||||
<tabstop>CAT_handshake_xon_radio_button</tabstop>
|
<tabstop>CAT_handshake_xon_radio_button</tabstop>
|
||||||
|
<tabstop>CAT_handshake_none_radio_button</tabstop>
|
||||||
<tabstop>CAT_handshake_hardware_radio_button</tabstop>
|
<tabstop>CAT_handshake_hardware_radio_button</tabstop>
|
||||||
<tabstop>force_DTR_combo_box</tabstop>
|
<tabstop>force_DTR_combo_box</tabstop>
|
||||||
<tabstop>force_RTS_combo_box</tabstop>
|
<tabstop>force_RTS_combo_box</tabstop>
|
||||||
@ -3014,6 +3022,7 @@ Right click for insert and delete options.</string>
|
|||||||
<tabstop>clear_DX_check_box</tabstop>
|
<tabstop>clear_DX_check_box</tabstop>
|
||||||
<tabstop>opCallEntry</tabstop>
|
<tabstop>opCallEntry</tabstop>
|
||||||
<tabstop>psk_reporter_check_box</tabstop>
|
<tabstop>psk_reporter_check_box</tabstop>
|
||||||
|
<tabstop>psk_reporter_tcpip_check_box</tabstop>
|
||||||
<tabstop>udp_server_line_edit</tabstop>
|
<tabstop>udp_server_line_edit</tabstop>
|
||||||
<tabstop>udp_server_port_spin_box</tabstop>
|
<tabstop>udp_server_port_spin_box</tabstop>
|
||||||
<tabstop>accept_udp_requests_check_box</tabstop>
|
<tabstop>accept_udp_requests_check_box</tabstop>
|
||||||
@ -3028,9 +3037,13 @@ Right click for insert and delete options.</string>
|
|||||||
<tabstop>stations_table_view</tabstop>
|
<tabstop>stations_table_view</tabstop>
|
||||||
<tabstop>highlighting_list_view</tabstop>
|
<tabstop>highlighting_list_view</tabstop>
|
||||||
<tabstop>reset_highlighting_to_defaults_push_button</tabstop>
|
<tabstop>reset_highlighting_to_defaults_push_button</tabstop>
|
||||||
|
<tabstop>highlight_by_mode_check_box</tabstop>
|
||||||
|
<tabstop>only_fields_check_box</tabstop>
|
||||||
|
<tabstop>include_WAE_check_box</tabstop>
|
||||||
|
<tabstop>rescan_log_push_button</tabstop>
|
||||||
<tabstop>LotW_CSV_URL_line_edit</tabstop>
|
<tabstop>LotW_CSV_URL_line_edit</tabstop>
|
||||||
<tabstop>LotW_CSV_fetch_push_button</tabstop>
|
|
||||||
<tabstop>LotW_days_since_upload_spin_box</tabstop>
|
<tabstop>LotW_days_since_upload_spin_box</tabstop>
|
||||||
|
<tabstop>LotW_CSV_fetch_push_button</tabstop>
|
||||||
<tabstop>sbNtrials</tabstop>
|
<tabstop>sbNtrials</tabstop>
|
||||||
<tabstop>sbAggressive</tabstop>
|
<tabstop>sbAggressive</tabstop>
|
||||||
<tabstop>cbTwoPass</tabstop>
|
<tabstop>cbTwoPass</tabstop>
|
||||||
@ -3039,13 +3052,18 @@ Right click for insert and delete options.</string>
|
|||||||
<tabstop>sbTxDelay</tabstop>
|
<tabstop>sbTxDelay</tabstop>
|
||||||
<tabstop>cbx2ToneSpacing</tabstop>
|
<tabstop>cbx2ToneSpacing</tabstop>
|
||||||
<tabstop>cbx4ToneSpacing</tabstop>
|
<tabstop>cbx4ToneSpacing</tabstop>
|
||||||
|
<tabstop>rbLowSidelobes</tabstop>
|
||||||
|
<tabstop>rbMaxSensitivity</tabstop>
|
||||||
|
<tabstop>gbSpecialOpActivity</tabstop>
|
||||||
<tabstop>rbFox</tabstop>
|
<tabstop>rbFox</tabstop>
|
||||||
|
<tabstop>rbHound</tabstop>
|
||||||
<tabstop>rbNA_VHF_Contest</tabstop>
|
<tabstop>rbNA_VHF_Contest</tabstop>
|
||||||
<tabstop>rbEU_VHF_Contest</tabstop>
|
|
||||||
<tabstop>rbField_Day</tabstop>
|
<tabstop>rbField_Day</tabstop>
|
||||||
<tabstop>Field_Day_Exchange</tabstop>
|
<tabstop>Field_Day_Exchange</tabstop>
|
||||||
|
<tabstop>rbEU_VHF_Contest</tabstop>
|
||||||
<tabstop>rbRTTY_Roundup</tabstop>
|
<tabstop>rbRTTY_Roundup</tabstop>
|
||||||
<tabstop>RTTY_Exchange</tabstop>
|
<tabstop>RTTY_Exchange</tabstop>
|
||||||
|
<tabstop>rbWW_DIGI</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections>
|
<connections>
|
||||||
@ -3116,12 +3134,12 @@ Right click for insert and delete options.</string>
|
|||||||
</connections>
|
</connections>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="PTT_method_button_group"/>
|
<buttongroup name="PTT_method_button_group"/>
|
||||||
<buttongroup name="TX_mode_button_group"/>
|
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||||
<buttongroup name="CAT_handshake_button_group"/>
|
<buttongroup name="CAT_handshake_button_group"/>
|
||||||
|
<buttongroup name="split_mode_button_group"/>
|
||||||
|
<buttongroup name="TX_mode_button_group"/>
|
||||||
<buttongroup name="TX_audio_source_button_group"/>
|
<buttongroup name="TX_audio_source_button_group"/>
|
||||||
<buttongroup name="special_op_activity_button_group"/>
|
<buttongroup name="special_op_activity_button_group"/>
|
||||||
<buttongroup name="CAT_data_bits_button_group"/>
|
<buttongroup name="CAT_data_bits_button_group"/>
|
||||||
<buttongroup name="split_mode_button_group"/>
|
|
||||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -56,6 +56,7 @@ void Detector::clear ()
|
|||||||
|
|
||||||
qint64 Detector::writeData (char const * data, qint64 maxSize)
|
qint64 Detector::writeData (char const * data, qint64 maxSize)
|
||||||
{
|
{
|
||||||
|
//qDebug () << "Detector::writeData: size:" << maxSize;
|
||||||
static unsigned mstr0=999999;
|
static unsigned mstr0=999999;
|
||||||
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
|
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
|
||||||
unsigned mstr = ms0 % int(1000.0*m_period); // ms into the nominal Tx start time
|
unsigned mstr = ms0 % int(1000.0*m_period); // ms into the nominal Tx start time
|
||||||
@ -119,8 +120,7 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
|
|||||||
remaining -= numFramesProcessed;
|
remaining -= numFramesProcessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we drop any data past the end of the buffer on the floor until
|
||||||
|
// the next period starts
|
||||||
return maxSize; // we drop any data past the end of the buffer on
|
return maxSize;
|
||||||
// the floor until the next period starts
|
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,14 @@ void Modulator::start (QString mode, unsigned symbolsLength, double framesPerSym
|
|||||||
// qDebug() << "delay_ms:" << delay_ms << "mstr:" << mstr << "m_silentFrames:" << m_silentFrames << "m_ic:" << m_ic << "m_state:" << m_state;
|
// qDebug() << "delay_ms:" << delay_ms << "mstr:" << mstr << "m_silentFrames:" << m_silentFrames << "m_ic:" << m_ic << "m_state:" << m_state;
|
||||||
|
|
||||||
m_stream = stream;
|
m_stream = stream;
|
||||||
if (m_stream) m_stream->restart (this);
|
if (m_stream)
|
||||||
|
{
|
||||||
|
m_stream->restart (this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug () << "Modulator::start: no audio output stream assigned";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Modulator::tune (bool newState)
|
void Modulator::tune (bool newState)
|
||||||
|
@ -465,7 +465,11 @@ void MessageClient::set_server (QString const& server)
|
|||||||
{
|
{
|
||||||
// queue a host address lookup
|
// queue a host address lookup
|
||||||
TRACE_UDP ("server host DNS lookup:" << server);
|
TRACE_UDP ("server host DNS lookup:" << server);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
|
||||||
m_->dns_lookup_id_ = QHostInfo::lookupHost (server, &*m_, &MessageClient::impl::host_info_results);
|
m_->dns_lookup_id_ = QHostInfo::lookupHost (server, &*m_, &MessageClient::impl::host_info_results);
|
||||||
|
#else
|
||||||
|
m_->dns_lookup_id_ = QHostInfo::lookupHost (server, &*m_, SLOT (host_info_results (QHostInfo)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,6 @@ public:
|
|||||||
|
|
||||||
// This timer sets the interval to check for spots to send.
|
// This timer sets the interval to check for spots to send.
|
||||||
connect (&report_timer_, &QTimer::timeout, [this] () {send_report ();});
|
connect (&report_timer_, &QTimer::timeout, [this] () {send_report ();});
|
||||||
report_timer_.start (MIN_SEND_INTERVAL * 1000);
|
|
||||||
|
|
||||||
// This timer repeats the sending of IPFIX templates and receiver
|
// This timer repeats the sending of IPFIX templates and receiver
|
||||||
// information if we are using UDP, in case server has been
|
// information if we are using UDP, in case server has been
|
||||||
@ -80,7 +79,6 @@ public:
|
|||||||
send_receiver_data_ = 3; // three times
|
send_receiver_data_ = 3; // three times
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
descriptor_timer_.start (1 * 60 * 60 * 1000); // hourly
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_connection ()
|
void check_connection ()
|
||||||
@ -156,6 +154,25 @@ public:
|
|||||||
// use this for pseudo connection with UDP, allows us to use
|
// use this for pseudo connection with UDP, allows us to use
|
||||||
// QIODevice::write() instead of QUDPSocket::writeDatagram()
|
// QIODevice::write() instead of QUDPSocket::writeDatagram()
|
||||||
socket_->connectToHost (HOST, SERVICE_PORT, QAbstractSocket::WriteOnly);
|
socket_->connectToHost (HOST, SERVICE_PORT, QAbstractSocket::WriteOnly);
|
||||||
|
|
||||||
|
if (!report_timer_.isActive ())
|
||||||
|
{
|
||||||
|
report_timer_.start (MIN_SEND_INTERVAL * 1000);
|
||||||
|
}
|
||||||
|
if (!descriptor_timer_.isActive ())
|
||||||
|
{
|
||||||
|
descriptor_timer_.start (1 * 60 * 60 * 1000); // hourly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop ()
|
||||||
|
{
|
||||||
|
if (socket_)
|
||||||
|
{
|
||||||
|
socket_->disconnectFromHost ();
|
||||||
|
}
|
||||||
|
descriptor_timer_.stop ();
|
||||||
|
report_timer_.stop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_report (bool send_residue = false);
|
void send_report (bool send_residue = false);
|
||||||
@ -402,7 +419,13 @@ void PSKReporter::impl::send_report (bool send_residue)
|
|||||||
writeUtfString (tx_out, spot.grid_);
|
writeUtfString (tx_out, spot.grid_);
|
||||||
tx_out
|
tx_out
|
||||||
<< quint8 (1u) // REPORTER_SOURCE_AUTOMATIC
|
<< quint8 (1u) // REPORTER_SOURCE_AUTOMATIC
|
||||||
<< static_cast<quint32> (spot.time_.toSecsSinceEpoch ());
|
<< static_cast<quint32> (
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
|
||||||
|
spot.time_.toSecsSinceEpoch ()
|
||||||
|
#else
|
||||||
|
spot.time_.toMSecsSinceEpoch () / 1000
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto len = payload_.size () + tx_data_.size ();
|
auto len = payload_.size () + tx_data_.size ();
|
||||||
@ -429,7 +452,13 @@ void PSKReporter::impl::send_report (bool send_residue)
|
|||||||
// insert Length and Export Time
|
// insert Length and Export Time
|
||||||
set_length (message, payload_);
|
set_length (message, payload_);
|
||||||
message.device ()->seek (2 * sizeof (quint16));
|
message.device ()->seek (2 * sizeof (quint16));
|
||||||
message << static_cast<quint32> (QDateTime::currentDateTime ().toSecsSinceEpoch ());
|
message << static_cast<quint32> (
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
|
||||||
|
QDateTime::currentDateTime ().toSecsSinceEpoch ()
|
||||||
|
#else
|
||||||
|
QDateTime::currentDateTime ().toMSecsSinceEpoch () / 1000
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
// Send data to PSK Reporter site
|
// Send data to PSK Reporter site
|
||||||
socket_->write (payload_); // TODO: handle errors
|
socket_->write (payload_); // TODO: handle errors
|
||||||
@ -465,6 +494,7 @@ void PSKReporter::reconnect ()
|
|||||||
|
|
||||||
void PSKReporter::setLocalStation (QString const& call, QString const& gridSquare, QString const& antenna)
|
void PSKReporter::setLocalStation (QString const& call, QString const& gridSquare, QString const& antenna)
|
||||||
{
|
{
|
||||||
|
m_->check_connection ();
|
||||||
if (call != m_->rx_call_ || gridSquare != m_->rx_grid_ || antenna != m_->rx_ant_)
|
if (call != m_->rx_call_ || gridSquare != m_->rx_grid_ || antenna != m_->rx_ant_)
|
||||||
{
|
{
|
||||||
m_->send_receiver_data_ = m_->socket_
|
m_->send_receiver_data_ = m_->socket_
|
||||||
@ -478,6 +508,7 @@ void PSKReporter::setLocalStation (QString const& call, QString const& gridSquar
|
|||||||
bool PSKReporter::addRemoteStation (QString const& call, QString const& grid, Radio::Frequency freq
|
bool PSKReporter::addRemoteStation (QString const& call, QString const& grid, Radio::Frequency freq
|
||||||
, QString const& mode, int snr)
|
, QString const& mode, int snr)
|
||||||
{
|
{
|
||||||
|
m_->check_connection ();
|
||||||
if (m_->socket_ && m_->socket_->isValid ())
|
if (m_->socket_ && m_->socket_->isValid ())
|
||||||
{
|
{
|
||||||
if (QAbstractSocket::UnconnectedState == m_->socket_->state ())
|
if (QAbstractSocket::UnconnectedState == m_->socket_->state ())
|
||||||
@ -490,7 +521,14 @@ bool PSKReporter::addRemoteStation (QString const& call, QString const& grid, Ra
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSKReporter::sendReport ()
|
void PSKReporter::sendReport (bool last)
|
||||||
{
|
{
|
||||||
|
if (m_->socket_ && QAbstractSocket::ConnectedState == m_->socket_->state ())
|
||||||
|
{
|
||||||
m_->send_report (true);
|
m_->send_report (true);
|
||||||
|
}
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
m_->stop ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
//
|
//
|
||||||
// Flush any pending spots to PSK Reporter
|
// Flush any pending spots to PSK Reporter
|
||||||
//
|
//
|
||||||
void sendReport ();
|
void sendReport (bool last = false);
|
||||||
|
|
||||||
Q_SIGNAL void errorOccurred (QString const& reason);
|
Q_SIGNAL void errorOccurred (QString const& reason);
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ public:
|
|||||||
, carry_ {false}
|
, carry_ {false}
|
||||||
, seed_ {{rand (), rand (), rand (), rand (), rand (), rand (), rand (), rand ()}}
|
, seed_ {{rand (), rand (), rand (), rand (), rand (), rand (), rand (), rand ()}}
|
||||||
, gen_ {seed_}
|
, gen_ {seed_}
|
||||||
, dist_ {1, 100}
|
, dist_ {0, 99}
|
||||||
{
|
{
|
||||||
auto num_bands = configuration_->bands ()->rowCount ();
|
auto num_bands = configuration_->bands ()->rowCount ();
|
||||||
for (auto& flags : bands_)
|
for (auto& flags : bands_)
|
||||||
|
@ -319,12 +319,12 @@ AD1CCty::AD1CCty (Configuration const * configuration)
|
|||||||
{
|
{
|
||||||
Q_ASSERT (configuration);
|
Q_ASSERT (configuration);
|
||||||
// TODO: G4WJS - consider doing the following asynchronously to
|
// TODO: G4WJS - consider doing the following asynchronously to
|
||||||
// speed up startup. Not urgent as it takes less than 1s on a Core
|
// speed up startup. Not urgent as it takes less than 0.5s on a Core
|
||||||
// i7 reading BIG CTY.DAT.
|
// i7 reading BIG CTY.DAT.
|
||||||
QDir dataPath {QStandardPaths::writableLocation (QStandardPaths::DataLocation)};
|
QDir dataPath {QStandardPaths::writableLocation (QStandardPaths::DataLocation)};
|
||||||
m_->path_ = dataPath.exists (file_name)
|
m_->path_ = dataPath.exists (file_name)
|
||||||
? dataPath.absoluteFilePath (file_name) // user override
|
? dataPath.absoluteFilePath (file_name) // user override
|
||||||
: QString {":/"} + file_name; // or original in the resources FS
|
: configuration->data_dir ().absoluteFilePath (file_name); // or original
|
||||||
QFile file {m_->path_};
|
QFile file {m_->path_};
|
||||||
if (file.open (QFile::ReadOnly))
|
if (file.open (QFile::ReadOnly))
|
||||||
{
|
{
|
||||||
|
2
main.cpp
2
main.cpp
@ -97,7 +97,7 @@ namespace
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// ### Add timestamps to all debug messages
|
// ### Add timestamps to all debug messages
|
||||||
// qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}");
|
// qSetMessagePattern ("[%{time yyyyMMdd HH:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}");
|
||||||
|
|
||||||
init_random_seed ();
|
init_random_seed ();
|
||||||
|
|
||||||
|
@ -15,14 +15,14 @@ namespace
|
|||||||
Radio::Frequency lower_bound_;
|
Radio::Frequency lower_bound_;
|
||||||
Radio::Frequency upper_bound_;
|
Radio::Frequency upper_bound_;
|
||||||
} constexpr ADIF_bands[] = {
|
} constexpr ADIF_bands[] = {
|
||||||
{"2190m", 136000u, 137000u},
|
{"2190m", 135700u, 137800u},
|
||||||
{"630m", 472000u, 479000u},
|
{"630m", 472000u, 479000u},
|
||||||
{"560m", 501000u, 504000u},
|
{"560m", 501000u, 504000u},
|
||||||
{"160m", 1800000u, 2000000u},
|
{"160m", 1800000u, 2000000u},
|
||||||
{"80m", 3500000u, 4000000u},
|
{"80m", 3500000u, 4000000u},
|
||||||
{"60m", 5060000u, 5450000u},
|
{"60m", 5060000u, 5450000u},
|
||||||
{"40m", 7000000u, 7300000u},
|
{"40m", 7000000u, 7300000u},
|
||||||
{"30m", 10000000u, 10150000u},
|
{"30m", 10100000u, 10150000u},
|
||||||
{"20m", 14000000u, 14350000u},
|
{"20m", 14000000u, 14350000u},
|
||||||
{"17m", 18068000u, 18168000u},
|
{"17m", 18068000u, 18168000u},
|
||||||
{"15m", 21000000u, 21450000u},
|
{"15m", 21000000u, 21450000u},
|
||||||
|
@ -37,14 +37,14 @@ void update_dynamic_property (QWidget * widget, char const * property, QVariant
|
|||||||
widget->update ();
|
widget->update ();
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime qt_round_date_time_to (QDateTime dt, int seconds)
|
QDateTime qt_round_date_time_to (QDateTime dt, int milliseconds)
|
||||||
{
|
{
|
||||||
dt.setSecsSinceEpoch (dt.addSecs (seconds - 1).toSecsSinceEpoch () / seconds * seconds);
|
dt.setMSecsSinceEpoch (dt.addMSecs (milliseconds / 2).toMSecsSinceEpoch () / milliseconds * milliseconds);
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime qt_truncate_date_time_to (QDateTime dt, int seconds)
|
QDateTime qt_truncate_date_time_to (QDateTime dt, int milliseconds)
|
||||||
{
|
{
|
||||||
dt.setSecsSinceEpoch (dt.toSecsSinceEpoch () / seconds * seconds);
|
dt.setMSecsSinceEpoch (dt.toMSecsSinceEpoch () / milliseconds * milliseconds);
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
@ -69,11 +69,11 @@ QString font_as_stylesheet (QFont const&);
|
|||||||
// conditional style sheet updates
|
// conditional style sheet updates
|
||||||
void update_dynamic_property (QWidget *, char const * property, QVariant const& value);
|
void update_dynamic_property (QWidget *, char const * property, QVariant const& value);
|
||||||
|
|
||||||
// round a QDateTime instance to an interval
|
// round a QDateTime instance to an integral interval of milliseconds
|
||||||
QDateTime qt_round_date_time_to (QDateTime dt, int seconds);
|
QDateTime qt_round_date_time_to (QDateTime dt, int milliseconds);
|
||||||
|
|
||||||
// truncate a QDateTime to an interval
|
// truncate a QDateTime to an integral interval of milliseconds
|
||||||
QDateTime qt_truncate_date_time_to (QDateTime dt, int seconds);
|
QDateTime qt_truncate_date_time_to (QDateTime dt, int milliseconds);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class VPtr
|
class VPtr
|
||||||
|
23
tests/CMakeLists.txt
Normal file
23
tests/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
find_package (Qt5Test 5 REQUIRED)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Compiler options
|
||||||
|
#
|
||||||
|
set (CMAKE_CXX_STANDARD 11)
|
||||||
|
add_compile_options ("$<$<COMPILE_LANGUAGE:Fortran>:-Wall;-Wno-conversion;-fno-second-underscore;-fno-f2c>")
|
||||||
|
add_compile_options ("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:Debug>>:-fbounds-check>")
|
||||||
|
add_compile_options ("$<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<NOT:$<CONFIG:Debug>>>:-funroll-all-loops>")
|
||||||
|
add_compile_options ("$<$<AND:$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>,$<OR:$<C_COMPILER_ID:GNU>,$<C_COMPILER_ID:Clang>,$<C_COMPILER_ID:AppleClang>>>:-Wall;-Wextra>")
|
||||||
|
add_compile_options ("$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:GNU>>:-Wno-pragmas>")
|
||||||
|
add_compile_options ("$<$<AND:$<OR:$<C_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:GNU>>,$<NOT:$<CONFIG:Debug>>>:-fdata-sections;-ffunction-sections>")
|
||||||
|
if (${OPENMP_FOUND} OR APPLE)
|
||||||
|
add_compile_options ("$<$<AND:$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>,$<C_COMPILER_ID:GNU>>:${OpenMP_C_FLAGS}>")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Tell CMake to run moc when necessary
|
||||||
|
set (CMAKE_AUTOMOC ON)
|
||||||
|
include_directories (${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
|
add_executable (test_qt_helpers test_qt_helpers.cpp)
|
||||||
|
target_link_libraries (test_qt_helpers wsjt_qt Qt5::Test)
|
||||||
|
add_test (test_qt_helpers test_qt_helpers)
|
138
tests/test_qt_helpers.cpp
Normal file
138
tests/test_qt_helpers.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#include <QtTest>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "qt_helpers.hpp"
|
||||||
|
|
||||||
|
class TestQtHelpers
|
||||||
|
: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_SLOT void round_15s_date_time_up ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 500}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 30)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_15s_date_time_up ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 500}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_15s_date_time_down ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 499}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_15s_date_time_down ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 499}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_15s_date_time_on ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 15}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_15s_date_time_on ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 15}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_15s_date_time_under ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 14, 999}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_15s_date_time_under ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 14, 999}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_15s_date_time_over ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 15, 1}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_15s_date_time_over ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 15, 1}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 15000), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_7p5s_date_time_up ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 26, 250}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 30)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_7p5s_date_time_up ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 26, 250}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_7p5s_date_time_down ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 26, 249}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_7p5s_date_time_down ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 26, 249}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_7p5s_date_time_on ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 500}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_7p5s_date_time_on ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 500}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_7p5s_date_time_under ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 499}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_7p5s_date_time_under ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 499}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void round_7p5s_date_time_over ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 501}};
|
||||||
|
QCOMPARE (qt_round_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SLOT void truncate_7p5s_date_time_over ()
|
||||||
|
{
|
||||||
|
QDateTime dt {QDate {2020, 8, 6}, QTime {14, 15, 22, 501}};
|
||||||
|
QCOMPARE (qt_truncate_date_time_to (dt, 7500), QDateTime (QDate (2020, 8, 6), QTime (14, 15, 22, 500)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_MAIN (TestQtHelpers);
|
||||||
|
|
||||||
|
#include "test_qt_helpers.moc"
|
@ -209,6 +209,8 @@ namespace
|
|||||||
QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"};
|
QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"};
|
||||||
auto quint32_max = std::numeric_limits<quint32>::max ();
|
auto quint32_max = std::numeric_limits<quint32>::max ();
|
||||||
constexpr int N_WIDGETS {34};
|
constexpr int N_WIDGETS {34};
|
||||||
|
constexpr int rx_chunk_size {3456}; // audio samples at 12000 Hz
|
||||||
|
constexpr int tx_audio_buffer_size {48000 / 5}; // audio frames at 48000 Hz
|
||||||
|
|
||||||
bool message_is_73 (int type, QStringList const& msg_parts)
|
bool message_is_73 (int type, QStringList const& msg_parts)
|
||||||
{
|
{
|
||||||
@ -283,7 +285,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
m_idleMinutes {0},
|
m_idleMinutes {0},
|
||||||
m_nSubMode {0},
|
m_nSubMode {0},
|
||||||
m_nclearave {1},
|
m_nclearave {1},
|
||||||
m_pctx {0},
|
|
||||||
m_nseq {0},
|
m_nseq {0},
|
||||||
m_nWSPRdecodes {0},
|
m_nWSPRdecodes {0},
|
||||||
m_k0 {9999999},
|
m_k0 {9999999},
|
||||||
@ -309,7 +310,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
m_bShMsgs {false},
|
m_bShMsgs {false},
|
||||||
m_bSWL {false},
|
m_bSWL {false},
|
||||||
m_uploading {false},
|
m_uploading {false},
|
||||||
m_txNext {false},
|
|
||||||
m_grid6 {false},
|
m_grid6 {false},
|
||||||
m_tuneup {false},
|
m_tuneup {false},
|
||||||
m_bTxTime {false},
|
m_bTxTime {false},
|
||||||
@ -394,8 +394,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
},
|
},
|
||||||
m_sfx {"P", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A"},
|
m_sfx {"P", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A"},
|
||||||
mem_jt9 {shdmem},
|
mem_jt9 {shdmem},
|
||||||
m_msAudioOutputBuffered (0u),
|
|
||||||
m_framesAudioInputBuffered (RX_SAMPLE_RATE / 10),
|
|
||||||
m_downSampleFactor (downSampleFactor),
|
m_downSampleFactor (downSampleFactor),
|
||||||
m_audioThreadPriority (QThread::HighPriority),
|
m_audioThreadPriority (QThread::HighPriority),
|
||||||
m_bandEdited {false},
|
m_bandEdited {false},
|
||||||
@ -471,9 +469,23 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
connect (this, &MainWindow::startAudioInputStream, m_soundInput, &SoundInput::start);
|
connect (this, &MainWindow::startAudioInputStream, m_soundInput, &SoundInput::start);
|
||||||
connect (this, &MainWindow::suspendAudioInputStream, m_soundInput, &SoundInput::suspend);
|
connect (this, &MainWindow::suspendAudioInputStream, m_soundInput, &SoundInput::suspend);
|
||||||
connect (this, &MainWindow::resumeAudioInputStream, m_soundInput, &SoundInput::resume);
|
connect (this, &MainWindow::resumeAudioInputStream, m_soundInput, &SoundInput::resume);
|
||||||
|
connect (this, &MainWindow::reset_audio_input_stream, m_soundInput, &SoundInput::reset);
|
||||||
connect (this, &MainWindow::finished, m_soundInput, &SoundInput::stop);
|
connect (this, &MainWindow::finished, m_soundInput, &SoundInput::stop);
|
||||||
connect(m_soundInput, &SoundInput::error, this, &MainWindow::showSoundInError);
|
connect(m_soundInput, &SoundInput::error, this, &MainWindow::showSoundInError);
|
||||||
// connect(m_soundInput, &SoundInput::status, this, &MainWindow::showStatusMessage);
|
// connect(m_soundInput, &SoundInput::status, this, &MainWindow::showStatusMessage);
|
||||||
|
connect (m_soundInput, &SoundInput::dropped_frames, this, [this] (qint32 dropped_frames, qint64 usec) {
|
||||||
|
if (dropped_frames > 48000 / 5) // 1/5 second
|
||||||
|
{
|
||||||
|
showStatusMessage (tr ("%1 (%2 sec) audio frames dropped").arg (dropped_frames).arg (usec / 1.e6, 5, 'f', 3));
|
||||||
|
}
|
||||||
|
if (dropped_frames > 48000) // 1 second
|
||||||
|
{
|
||||||
|
MessageBox::warning_message (this
|
||||||
|
, tr ("Audio Source")
|
||||||
|
, tr ("Reduce system load")
|
||||||
|
, tr ("Excessive dropped samples - %1 (%2 sec) audio frames dropped").arg (dropped_frames).arg (usec / 1.e6, 5, 'f', 3));
|
||||||
|
}
|
||||||
|
});
|
||||||
connect (&m_audioThread, &QThread::finished, m_soundInput, &QObject::deleteLater);
|
connect (&m_audioThread, &QThread::finished, m_soundInput, &QObject::deleteLater);
|
||||||
|
|
||||||
connect (this, &MainWindow::finished, this, &MainWindow::close);
|
connect (this, &MainWindow::finished, this, &MainWindow::close);
|
||||||
@ -937,14 +949,24 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
connect (&m_wav_future_watcher, &QFutureWatcher<void>::finished, this, &MainWindow::diskDat);
|
connect (&m_wav_future_watcher, &QFutureWatcher<void>::finished, this, &MainWindow::diskDat);
|
||||||
|
|
||||||
connect(&watcher3, SIGNAL(finished()),this,SLOT(fast_decode_done()));
|
connect(&watcher3, SIGNAL(finished()),this,SLOT(fast_decode_done()));
|
||||||
Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, m_detector, m_downSampleFactor, m_config.audio_input_channel ());
|
if (!m_config.audio_input_device ().isNull ())
|
||||||
Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (), AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2, m_msAudioOutputBuffered);
|
{
|
||||||
|
Q_EMIT startAudioInputStream (m_config.audio_input_device ()
|
||||||
|
, rx_chunk_size * m_downSampleFactor
|
||||||
|
, m_detector, m_downSampleFactor, m_config.audio_input_channel ());
|
||||||
|
}
|
||||||
|
if (!m_config.audio_output_device ().isNull ())
|
||||||
|
{
|
||||||
|
Q_EMIT initializeAudioOutputStream (m_config.audio_output_device ()
|
||||||
|
, AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2
|
||||||
|
, tx_audio_buffer_size);
|
||||||
|
}
|
||||||
Q_EMIT transmitFrequency (ui->TxFreqSpinBox->value () - m_XIT);
|
Q_EMIT transmitFrequency (ui->TxFreqSpinBox->value () - m_XIT);
|
||||||
|
|
||||||
enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook
|
enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook
|
||||||
|
|
||||||
ui->label_9->setStyleSheet("QLabel{background-color: #aabec8}");
|
ui->label_9->setStyleSheet("QLabel{color: #000000; background-color: #aabec8}");
|
||||||
ui->label_10->setStyleSheet("QLabel{background-color: #aabec8}");
|
ui->label_10->setStyleSheet("QLabel{color: #000000; background-color: #aabec8}");
|
||||||
|
|
||||||
// this must be done before initializing the mode as some modes need
|
// this must be done before initializing the mode as some modes need
|
||||||
// to turn off split on the rig e.g. WSPR
|
// to turn off split on the rig e.g. WSPR
|
||||||
@ -972,7 +994,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
}
|
}
|
||||||
m_saveDecoded=ui->actionSave_decoded->isChecked();
|
m_saveDecoded=ui->actionSave_decoded->isChecked();
|
||||||
m_saveAll=ui->actionSave_all->isChecked();
|
m_saveAll=ui->actionSave_all->isChecked();
|
||||||
ui->sbTxPercent->setValue(m_pctx);
|
|
||||||
ui->TxPowerComboBox->setCurrentIndex(int(.3 * m_dBm + .2));
|
ui->TxPowerComboBox->setCurrentIndex(int(.3 * m_dBm + .2));
|
||||||
ui->cbUploadWSPR_Spots->setChecked(m_uploadWSPRSpots);
|
ui->cbUploadWSPR_Spots->setChecked(m_uploadWSPRSpots);
|
||||||
if((m_ndepth&7)==1) ui->actionQuickDecode->setChecked(true);
|
if((m_ndepth&7)==1) ui->actionQuickDecode->setChecked(true);
|
||||||
@ -995,12 +1016,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
|||||||
m_isort=-3;
|
m_isort=-3;
|
||||||
m_max_dB=70;
|
m_max_dB=70;
|
||||||
m_CQtype="CQ";
|
m_CQtype="CQ";
|
||||||
|
|
||||||
if(m_mode=="WSPR" and m_pctx>0) {
|
|
||||||
QPalette palette {ui->sbTxPercent->palette ()};
|
|
||||||
palette.setColor(QPalette::Base,Qt::yellow);
|
|
||||||
ui->sbTxPercent->setPalette(palette);
|
|
||||||
}
|
|
||||||
fixStop();
|
fixStop();
|
||||||
VHF_features_enabled(m_config.enable_VHF_features());
|
VHF_features_enabled(m_config.enable_VHF_features());
|
||||||
m_wideGraph->setVHF(m_config.enable_VHF_features());
|
m_wideGraph->setVHF(m_config.enable_VHF_features());
|
||||||
@ -1144,7 +1159,7 @@ void MainWindow::writeSettings()
|
|||||||
m_settings->setValue("GUItab",ui->tabWidget->currentIndex());
|
m_settings->setValue("GUItab",ui->tabWidget->currentIndex());
|
||||||
m_settings->setValue("OutBufSize",outBufSize);
|
m_settings->setValue("OutBufSize",outBufSize);
|
||||||
m_settings->setValue ("HoldTxFreq", ui->cbHoldTxFreq->isChecked ());
|
m_settings->setValue ("HoldTxFreq", ui->cbHoldTxFreq->isChecked ());
|
||||||
m_settings->setValue("PctTx",m_pctx);
|
m_settings->setValue("PctTx", ui->sbTxPercent->value ());
|
||||||
m_settings->setValue("dBm",m_dBm);
|
m_settings->setValue("dBm",m_dBm);
|
||||||
m_settings->setValue("RR73",m_send_RR73);
|
m_settings->setValue("RR73",m_send_RR73);
|
||||||
m_settings->setValue ("WSPRPreferType1", ui->WSPR_prefer_type_1_check_box->isChecked ());
|
m_settings->setValue ("WSPRPreferType1", ui->WSPR_prefer_type_1_check_box->isChecked ());
|
||||||
@ -1235,7 +1250,8 @@ void MainWindow::readSettings()
|
|||||||
ui->TxFreqSpinBox->setValue(0); // ensure a change is signaled
|
ui->TxFreqSpinBox->setValue(0); // ensure a change is signaled
|
||||||
ui->TxFreqSpinBox->setValue(m_settings->value("TxFreq",1500).toInt());
|
ui->TxFreqSpinBox->setValue(m_settings->value("TxFreq",1500).toInt());
|
||||||
m_ndepth=m_settings->value("NDepth",3).toInt();
|
m_ndepth=m_settings->value("NDepth",3).toInt();
|
||||||
m_pctx=m_settings->value("PctTx",20).toInt();
|
ui->sbTxPercent->setValue (m_settings->value ("PctTx", 20).toInt ());
|
||||||
|
on_sbTxPercent_valueChanged (ui->sbTxPercent->value ());
|
||||||
m_dBm=m_settings->value("dBm",37).toInt();
|
m_dBm=m_settings->value("dBm",37).toInt();
|
||||||
m_send_RR73=m_settings->value("RR73",false).toBool();
|
m_send_RR73=m_settings->value("RR73",false).toBool();
|
||||||
if(m_send_RR73) {
|
if(m_send_RR73) {
|
||||||
@ -1244,7 +1260,6 @@ void MainWindow::readSettings()
|
|||||||
}
|
}
|
||||||
ui->WSPR_prefer_type_1_check_box->setChecked (m_settings->value ("WSPRPreferType1", true).toBool ());
|
ui->WSPR_prefer_type_1_check_box->setChecked (m_settings->value ("WSPRPreferType1", true).toBool ());
|
||||||
m_uploadWSPRSpots=m_settings->value("UploadSpots",false).toBool();
|
m_uploadWSPRSpots=m_settings->value("UploadSpots",false).toBool();
|
||||||
if(!m_uploadWSPRSpots) ui->cbUploadWSPR_Spots->setStyleSheet("QCheckBox{background-color: yellow}");
|
|
||||||
ui->cbNoOwnCall->setChecked(m_settings->value("NoOwnCall",false).toBool());
|
ui->cbNoOwnCall->setChecked(m_settings->value("NoOwnCall",false).toBool());
|
||||||
ui->band_hopping_group_box->setChecked (m_settings->value ("BandHopping", false).toBool());
|
ui->band_hopping_group_box->setChecked (m_settings->value ("BandHopping", false).toBool());
|
||||||
// setup initial value of tx attenuator
|
// setup initial value of tx attenuator
|
||||||
@ -1277,8 +1292,6 @@ void MainWindow::readSettings()
|
|||||||
// use these initialisation settings to tune the audio o/p buffer
|
// use these initialisation settings to tune the audio o/p buffer
|
||||||
// size and audio thread priority
|
// size and audio thread priority
|
||||||
m_settings->beginGroup ("Tune");
|
m_settings->beginGroup ("Tune");
|
||||||
m_msAudioOutputBuffered = m_settings->value ("Audio/OutputBufferMs").toInt ();
|
|
||||||
m_framesAudioInputBuffered = m_settings->value ("Audio/InputBufferFrames", RX_SAMPLE_RATE / 10).toInt ();
|
|
||||||
m_audioThreadPriority = static_cast<QThread::Priority> (m_settings->value ("Audio/ThreadPriority", QThread::HighPriority).toInt () % 8);
|
m_audioThreadPriority = static_cast<QThread::Priority> (m_settings->value ("Audio/ThreadPriority", QThread::HighPriority).toInt () % 8);
|
||||||
m_settings->endGroup ();
|
m_settings->endGroup ();
|
||||||
|
|
||||||
@ -1536,6 +1549,10 @@ void MainWindow::dataSink(qint64 frames)
|
|||||||
if(m_mode!="WSPR") decode(); //Start decoder
|
if(m_mode!="WSPR") decode(); //Start decoder
|
||||||
|
|
||||||
if(m_mode=="FT8" and !m_diskData and (m_ihsym==m_earlyDecode or m_ihsym==m_earlyDecode2)) return;
|
if(m_mode=="FT8" and !m_diskData and (m_ihsym==m_earlyDecode or m_ihsym==m_earlyDecode2)) return;
|
||||||
|
if (!m_diskData)
|
||||||
|
{
|
||||||
|
Q_EMIT reset_audio_input_stream (true); // signals dropped samples
|
||||||
|
}
|
||||||
if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR" or m_mode=="FST4W")) {
|
if(!m_diskData and (m_saveAll or m_saveDecoded or m_mode=="WSPR" or m_mode=="FST4W")) {
|
||||||
//Always save unless "Save None"; may delete later
|
//Always save unless "Save None"; may delete later
|
||||||
if(m_TRperiod < 60) {
|
if(m_TRperiod < 60) {
|
||||||
@ -1614,14 +1631,15 @@ QString MainWindow::save_wave_file (QString const& name, short const * data, int
|
|||||||
format.setChannelCount (1);
|
format.setChannelCount (1);
|
||||||
format.setSampleSize (16);
|
format.setSampleSize (16);
|
||||||
format.setSampleType (QAudioFormat::SignedInt);
|
format.setSampleType (QAudioFormat::SignedInt);
|
||||||
auto source = QString {"%1, %2"}.arg (my_callsign).arg (my_grid);
|
auto source = QString {"%1; %2"}.arg (my_callsign).arg (my_grid);
|
||||||
auto comment = QString {"Mode=%1%2, Freq=%3%4"}
|
auto comment = QString {"Mode=%1%2; Freq=%3%4"}
|
||||||
.arg (mode)
|
.arg (mode)
|
||||||
.arg (QString {(mode.contains ('J') && !mode.contains ('+')) || mode.startsWith ("FST4")
|
.arg (QString {(mode.contains ('J') && !mode.contains ('+'))
|
||||||
? QString {", Sub Mode="} + QChar {'A' + sub_mode}
|
|| mode.startsWith ("FST4") || mode.startsWith ("QRA")
|
||||||
|
? QString {"; Sub Mode="} + QString::number (int (samples / 12000)) + QChar {'A' + sub_mode}
|
||||||
: QString {}})
|
: QString {}})
|
||||||
.arg (Radio::frequency_MHz_string (frequency))
|
.arg (Radio::frequency_MHz_string (frequency))
|
||||||
.arg (QString {mode!="WSPR" ? QString {", DXCall=%1, DXGrid=%2"}
|
.arg (QString {mode!="WSPR" ? QString {"; DXCall=%1; DXGrid=%2"}
|
||||||
.arg (his_call)
|
.arg (his_call)
|
||||||
.arg (his_grid).toLocal8Bit () : ""});
|
.arg (his_grid).toLocal8Bit () : ""});
|
||||||
BWFFile::InfoDictionary list_info {
|
BWFFile::InfoDictionary list_info {
|
||||||
@ -1783,6 +1801,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
|
|||||||
auto callsign = m_config.my_callsign ();
|
auto callsign = m_config.my_callsign ();
|
||||||
auto my_grid = m_config.my_grid ();
|
auto my_grid = m_config.my_grid ();
|
||||||
SpecOp nContest0=m_config.special_op_id();
|
SpecOp nContest0=m_config.special_op_id();
|
||||||
|
auto psk_on = m_config.spot_to_psk_reporter ();
|
||||||
if (QDialog::Accepted == m_config.exec ()) {
|
if (QDialog::Accepted == m_config.exec ()) {
|
||||||
checkMSK144ContestType();
|
checkMSK144ContestType();
|
||||||
if (m_config.my_callsign () != callsign) {
|
if (m_config.my_callsign () != callsign) {
|
||||||
@ -1796,18 +1815,25 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog
|
|||||||
on_dxGridEntry_textChanged (m_hisGrid); // recalculate distances in case of units change
|
on_dxGridEntry_textChanged (m_hisGrid); // recalculate distances in case of units change
|
||||||
enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook
|
enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook
|
||||||
|
|
||||||
if(m_config.spot_to_psk_reporter ()) pskSetLocal ();
|
pskSetLocal ();
|
||||||
|
// this will close the connection to PSKReporter if it has been
|
||||||
|
// disabled
|
||||||
|
if (psk_on && !m_config.spot_to_psk_reporter ())
|
||||||
|
{
|
||||||
|
m_psk_Reporter.sendReport (true);
|
||||||
|
}
|
||||||
|
|
||||||
if(m_config.restart_audio_input ()) {
|
if(m_config.restart_audio_input ()) {
|
||||||
Q_EMIT startAudioInputStream (m_config.audio_input_device (),
|
Q_EMIT startAudioInputStream (m_config.audio_input_device ()
|
||||||
m_framesAudioInputBuffered, m_detector, m_downSampleFactor,
|
, rx_chunk_size * m_downSampleFactor
|
||||||
m_config.audio_input_channel ());
|
, m_detector, m_downSampleFactor
|
||||||
|
, m_config.audio_input_channel ());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_config.restart_audio_output ()) {
|
if(m_config.restart_audio_output ()) {
|
||||||
Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (),
|
Q_EMIT initializeAudioOutputStream (m_config.audio_output_device ()
|
||||||
AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2,
|
, AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2
|
||||||
m_msAudioOutputBuffered);
|
, tx_audio_buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayDialFrequency ();
|
displayDialFrequency ();
|
||||||
@ -1909,18 +1935,14 @@ void MainWindow::on_autoButton_clicked (bool checked)
|
|||||||
m_nclearave=1;
|
m_nclearave=1;
|
||||||
echocom_.nsum=0;
|
echocom_.nsum=0;
|
||||||
}
|
}
|
||||||
if(m_mode=="WSPR" or m_mode=="FST4W") {
|
|
||||||
QPalette palette {ui->sbTxPercent->palette ()};
|
|
||||||
if(m_auto or m_pctx==0) {
|
|
||||||
palette.setColor(QPalette::Base,Qt::white);
|
|
||||||
} else {
|
|
||||||
palette.setColor(QPalette::Base,Qt::yellow);
|
|
||||||
}
|
|
||||||
ui->sbTxPercent->setPalette(palette);
|
|
||||||
}
|
|
||||||
m_tAutoOn=QDateTime::currentMSecsSinceEpoch()/1000;
|
m_tAutoOn=QDateTime::currentMSecsSinceEpoch()/1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_sbTxPercent_valueChanged (int n)
|
||||||
|
{
|
||||||
|
update_dynamic_property (ui->sbTxPercent, "notx", !n);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::auto_tx_mode (bool state)
|
void MainWindow::auto_tx_mode (bool state)
|
||||||
{
|
{
|
||||||
ui->autoButton->setChecked (state);
|
ui->autoButton->setChecked (state);
|
||||||
@ -2279,8 +2301,8 @@ bool MainWindow::eventFilter (QObject * object, QEvent * event)
|
|||||||
void MainWindow::createStatusBar() //createStatusBar
|
void MainWindow::createStatusBar() //createStatusBar
|
||||||
{
|
{
|
||||||
tx_status_label.setAlignment (Qt::AlignHCenter);
|
tx_status_label.setAlignment (Qt::AlignHCenter);
|
||||||
tx_status_label.setMinimumSize (QSize {150, 18});
|
tx_status_label.setMinimumSize (QSize {100, 18});
|
||||||
tx_status_label.setStyleSheet ("QLabel{background-color: #00ff00}");
|
tx_status_label.setStyleSheet ("QLabel{color: #000000; background-color: #00ff00}");
|
||||||
tx_status_label.setFrameStyle (QFrame::Panel | QFrame::Sunken);
|
tx_status_label.setFrameStyle (QFrame::Panel | QFrame::Sunken);
|
||||||
statusBar()->addWidget (&tx_status_label);
|
statusBar()->addWidget (&tx_status_label);
|
||||||
|
|
||||||
@ -2328,37 +2350,37 @@ void MainWindow::setup_status_bar (bool vhf)
|
|||||||
mode_label.setText (m_mode);
|
mode_label.setText (m_mode);
|
||||||
}
|
}
|
||||||
if ("ISCAT" == m_mode) {
|
if ("ISCAT" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ff9933}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff9933}");
|
||||||
} else if ("JT9" == m_mode) {
|
} else if ("JT9" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ff6ec7}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff6ec7}");
|
||||||
} else if ("JT4" == m_mode) {
|
} else if ("JT4" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #cc99ff}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #cc99ff}");
|
||||||
} else if ("Echo" == m_mode) {
|
} else if ("Echo" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #66ffff}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #66ffff}");
|
||||||
} else if ("JT9+JT65" == m_mode) {
|
} else if ("JT9+JT65" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ffff66}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ffff66}");
|
||||||
} else if ("JT65" == m_mode) {
|
} else if ("JT65" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #66ff66}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #66ff66}");
|
||||||
} else if ("QRA64" == m_mode) {
|
} else if ("QRA64" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #99ff33}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #99ff33}");
|
||||||
} else if ("MSK144" == m_mode) {
|
} else if ("MSK144" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ff6666}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff6666}");
|
||||||
} else if ("FT4" == m_mode) {
|
} else if ("FT4" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ff0099}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff0099}");
|
||||||
} else if ("FT8" == m_mode) {
|
} else if ("FT8" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ff6699}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff6699}");
|
||||||
} else if ("FST4" == m_mode) {
|
} else if ("FST4" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #99ff66}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #99ff66}");
|
||||||
} else if ("FST4W" == m_mode) {
|
} else if ("FST4W" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #6699ff}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #6699ff}");
|
||||||
} else if ("FreqCal" == m_mode) {
|
} else if ("FreqCal" == m_mode) {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ff9933}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff9933}");
|
||||||
}
|
}
|
||||||
last_tx_label.setText (QString {});
|
last_tx_label.setText (QString {});
|
||||||
if (m_mode.contains (QRegularExpression {R"(^(Echo|ISCAT))"})) {
|
if (m_mode.contains (QRegularExpression {R"(^(Echo|ISCAT))"})) {
|
||||||
if (band_hopping_label.isVisible ()) statusBar ()->removeWidget (&band_hopping_label);
|
if (band_hopping_label.isVisible ()) statusBar ()->removeWidget (&band_hopping_label);
|
||||||
} else if (m_mode=="WSPR") {
|
} else if (m_mode=="WSPR") {
|
||||||
mode_label.setStyleSheet ("QLabel{background-color: #ff66ff}");
|
mode_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff66ff}");
|
||||||
if (!band_hopping_label.isVisible ()) {
|
if (!band_hopping_label.isVisible ()) {
|
||||||
statusBar ()->addWidget (&band_hopping_label);
|
statusBar ()->addWidget (&band_hopping_label);
|
||||||
band_hopping_label.show ();
|
band_hopping_label.show ();
|
||||||
@ -2689,7 +2711,7 @@ void MainWindow::on_actionOpen_triggered() //Open File
|
|||||||
m_path=fname;
|
m_path=fname;
|
||||||
int i1=fname.lastIndexOf("/");
|
int i1=fname.lastIndexOf("/");
|
||||||
QString baseName=fname.mid(i1+1);
|
QString baseName=fname.mid(i1+1);
|
||||||
tx_status_label.setStyleSheet("QLabel{background-color: #99ffff}");
|
tx_status_label.setStyleSheet("QLabel{color: #000000; background-color: #99ffff}");
|
||||||
tx_status_label.setText(" " + baseName + " ");
|
tx_status_label.setText(" " + baseName + " ");
|
||||||
on_stopButton_clicked();
|
on_stopButton_clicked();
|
||||||
m_diskData=true;
|
m_diskData=true;
|
||||||
@ -2769,7 +2791,7 @@ void MainWindow::on_actionOpen_next_in_directory_triggered() //Open Next
|
|||||||
m_path=fname;
|
m_path=fname;
|
||||||
int i1=fname.lastIndexOf("/");
|
int i1=fname.lastIndexOf("/");
|
||||||
QString baseName=fname.mid(i1+1);
|
QString baseName=fname.mid(i1+1);
|
||||||
tx_status_label.setStyleSheet("QLabel{background-color: #99ffff}");
|
tx_status_label.setStyleSheet("QLabel{color: #000000; background-color: #99ffff}");
|
||||||
tx_status_label.setText(" " + baseName + " ");
|
tx_status_label.setText(" " + baseName + " ");
|
||||||
m_diskData=true;
|
m_diskData=true;
|
||||||
read_wav_file (fname);
|
read_wav_file (fname);
|
||||||
@ -3109,7 +3131,8 @@ void MainWindow::decode() //decode()
|
|||||||
//newdat=1 ==> this is new data, must do the big FFT
|
//newdat=1 ==> this is new data, must do the big FFT
|
||||||
//nagain=1 ==> decode only at fQSO +/- Tol
|
//nagain=1 ==> decode only at fQSO +/- Tol
|
||||||
|
|
||||||
char *to = (char*)mem_jt9->data();
|
if (auto * to = reinterpret_cast<char *> (mem_jt9->data()))
|
||||||
|
{
|
||||||
char *from = (char*) dec_data.ipc;
|
char *from = (char*) dec_data.ipc;
|
||||||
int size=sizeof(struct dec_data);
|
int size=sizeof(struct dec_data);
|
||||||
if(dec_data.params.newdat==0) {
|
if(dec_data.params.newdat==0) {
|
||||||
@ -3159,6 +3182,7 @@ void MainWindow::decode() //decode()
|
|||||||
to_jt9(m_ihsym,1,-1); //Send m_ihsym to jt9[.exe] and start decoding
|
to_jt9(m_ihsym,1,-1); //Send m_ihsym to jt9[.exe] and start decoding
|
||||||
decodeBusy(true);
|
decodeBusy(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void::MainWindow::fast_decode_done()
|
void::MainWindow::fast_decode_done()
|
||||||
@ -3206,12 +3230,14 @@ void::MainWindow::fast_decode_done()
|
|||||||
|
|
||||||
void MainWindow::to_jt9(qint32 n, qint32 istart, qint32 idone)
|
void MainWindow::to_jt9(qint32 n, qint32 istart, qint32 idone)
|
||||||
{
|
{
|
||||||
dec_data_t * dd = reinterpret_cast<dec_data_t *> (mem_jt9->data());
|
if (auto * dd = reinterpret_cast<dec_data_t *> (mem_jt9->data()))
|
||||||
|
{
|
||||||
mem_jt9->lock ();
|
mem_jt9->lock ();
|
||||||
dd->ipc[0]=n;
|
dd->ipc[0]=n;
|
||||||
if(istart>=0) dd->ipc[1]=istart;
|
if(istart>=0) dd->ipc[1]=istart;
|
||||||
if(idone>=0) dd->ipc[2]=idone;
|
if(idone>=0) dd->ipc[2]=idone;
|
||||||
mem_jt9->unlock ();
|
mem_jt9->unlock ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::decodeDone ()
|
void MainWindow::decodeDone ()
|
||||||
@ -3268,7 +3294,8 @@ void MainWindow::readFromStdout() //readFromStdout
|
|||||||
line_read = line_read.left (64);
|
line_read = line_read.left (64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(m_mode!="FT8" and m_mode!="FT4") {
|
if (m_mode!="FT8" and m_mode!="FT4"
|
||||||
|
&& !m_mode.startsWith ("FST4")) {
|
||||||
//Pad 22-char msg to at least 37 chars
|
//Pad 22-char msg to at least 37 chars
|
||||||
line_read = line_read.left(44) + " " + line_read.mid(44);
|
line_read = line_read.left(44) + " " + line_read.mid(44);
|
||||||
}
|
}
|
||||||
@ -3486,9 +3513,8 @@ void MainWindow::readFromStdout() //readFromStdout
|
|||||||
bool okToPost=(nsec > int(4*m_TRperiod)/5);
|
bool okToPost=(nsec > int(4*m_TRperiod)/5);
|
||||||
if(m_mode=="FST4W" and okToPost) {
|
if(m_mode=="FST4W" and okToPost) {
|
||||||
line_read=line_read.left(22) + " CQ " + line_read.trimmed().mid(22);
|
line_read=line_read.left(22) + " CQ " + line_read.trimmed().mid(22);
|
||||||
int n=line_read.trimmed().size();
|
auto p = line_read.lastIndexOf (' ');
|
||||||
line_read=line_read.trimmed().left(n-3);
|
DecodedText FST4W_post {QString::fromUtf8 (line_read.left (p).constData ())};
|
||||||
DecodedText FST4W_post {QString::fromUtf8(line_read.constData())};
|
|
||||||
pskPost(FST4W_post);
|
pskPost(FST4W_post);
|
||||||
} else {
|
} else {
|
||||||
if (stdMsg && okToPost) pskPost(decodedtext);
|
if (stdMsg && okToPost) pskPost(decodedtext);
|
||||||
@ -3721,26 +3747,22 @@ void MainWindow::guiUpdate()
|
|||||||
if(m_mode=="WSPR" or m_mode=="FST4W") {
|
if(m_mode=="WSPR" or m_mode=="FST4W") {
|
||||||
if(m_nseq==0 and m_ntr==0) { //Decide whether to Tx or Rx
|
if(m_nseq==0 and m_ntr==0) { //Decide whether to Tx or Rx
|
||||||
m_tuneup=false; //This is not an ATU tuneup
|
m_tuneup=false; //This is not an ATU tuneup
|
||||||
if(ui->sbTxPercent->isEnabled () && m_pctx==0) m_WSPR_tx_next = false; //Don't transmit if m_pctx=0
|
|
||||||
bool btx = m_auto && m_WSPR_tx_next; // To Tx, we need m_auto and
|
bool btx = m_auto && m_WSPR_tx_next; // To Tx, we need m_auto and
|
||||||
// scheduled transmit
|
// scheduled transmit
|
||||||
if(m_auto and m_txNext) btx=true; //TxNext button overrides
|
m_WSPR_tx_next = false;
|
||||||
if(m_auto && ui->sbTxPercent->isEnabled () && m_pctx==100) btx=true; //Always transmit
|
|
||||||
|
|
||||||
if(btx) {
|
if(btx) {
|
||||||
m_ntr=-1; //This says we will have transmitted
|
m_ntr=-1; //This says we will have transmitted
|
||||||
m_txNext=false;
|
ui->pbTxNext->setChecked (false);
|
||||||
ui->pbTxNext->setChecked(false);
|
|
||||||
m_bTxTime=true; //Start a WSPR or FST4W Tx sequence
|
m_bTxTime=true; //Start a WSPR or FST4W Tx sequence
|
||||||
} else {
|
} else {
|
||||||
// This will be a WSPR or FST4W Rx sequence.
|
// This will be a WSPR or FST4W Rx sequence.
|
||||||
m_ntr=1; //This says we will have received
|
m_ntr=1; //This says we will have received
|
||||||
m_bTxTime=false; //Start a WSPR or FST4W Rx sequence
|
m_bTxTime=false; //Start a WSPR or FST4W Rx sequence
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// For all modes other than WSPR and Fst4W
|
// For all modes other than WSPR and Fst4W
|
||||||
m_bTxTime = (t2p >= tx1) and (t2p < tx2);
|
m_bTxTime = (t2p >= tx1) and (t2p < tx2);
|
||||||
if(m_mode=="Echo") m_bTxTime = m_bTxTime and m_bEchoTxOK;
|
if(m_mode=="Echo") m_bTxTime = m_bTxTime and m_bEchoTxOK;
|
||||||
if(m_mode=="FT8" and ui->tx5->currentText().contains("/B ")) {
|
if(m_mode=="FT8" and ui->tx5->currentText().contains("/B ")) {
|
||||||
@ -4276,11 +4298,11 @@ void MainWindow::guiUpdate()
|
|||||||
m_nsendingsh=0;
|
m_nsendingsh=0;
|
||||||
if(s[4]==64) m_nsendingsh=1;
|
if(s[4]==64) m_nsendingsh=1;
|
||||||
if(m_nsendingsh==1 or m_currentMessageType==7) {
|
if(m_nsendingsh==1 or m_currentMessageType==7) {
|
||||||
tx_status_label.setStyleSheet("QLabel{background-color: #66ffff}");
|
tx_status_label.setStyleSheet("QLabel{color: #000000; background-color: #66ffff}");
|
||||||
} else if(m_nsendingsh==-1 or m_currentMessageType==6) {
|
} else if(m_nsendingsh==-1 or m_currentMessageType==6) {
|
||||||
tx_status_label.setStyleSheet("QLabel{background-color: #ffccff}");
|
tx_status_label.setStyleSheet("QLabel{color: #000000; background-color: #ffccff}");
|
||||||
} else {
|
} else {
|
||||||
tx_status_label.setStyleSheet("QLabel{background-color: #ffff33}");
|
tx_status_label.setStyleSheet("QLabel{color: #000000; background-color: #ffff33}");
|
||||||
}
|
}
|
||||||
if(m_tune) {
|
if(m_tune) {
|
||||||
tx_status_label.setText("Tx: TUNE");
|
tx_status_label.setText("Tx: TUNE");
|
||||||
@ -4299,11 +4321,11 @@ void MainWindow::guiUpdate()
|
|||||||
}
|
}
|
||||||
} else if(m_monitoring) {
|
} else if(m_monitoring) {
|
||||||
if (!m_tx_watchdog) {
|
if (!m_tx_watchdog) {
|
||||||
tx_status_label.setStyleSheet("QLabel{background-color: #00ff00}");
|
tx_status_label.setStyleSheet("QLabel{color: #000000; background-color: #00ff00}");
|
||||||
auto t = tr ("Receiving");
|
auto t = tr ("Receiving");
|
||||||
if(m_mode=="MSK144") {
|
if(m_mode=="MSK144") {
|
||||||
int npct=int(100.0*m_fCPUmskrtd/0.298667);
|
int npct=int(100.0*m_fCPUmskrtd/0.298667);
|
||||||
if(npct>90) tx_status_label.setStyleSheet("QLabel{background-color: #ff0000}");
|
if(npct>90) tx_status_label.setStyleSheet("QLabel{color: #000000; background-color: #ff0000}");
|
||||||
t += QString {" %1%"}.arg (npct, 2);
|
t += QString {" %1%"}.arg (npct, 2);
|
||||||
}
|
}
|
||||||
tx_status_label.setText (t);
|
tx_status_label.setText (t);
|
||||||
@ -5017,7 +5039,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie
|
|||||||
// m_nextGrid=message_words.at(3);
|
// m_nextGrid=message_words.at(3);
|
||||||
// m_nextRpt=message.report();
|
// m_nextRpt=message.report();
|
||||||
// ui->labNextCall->setText("Next: " + m_nextCall);
|
// ui->labNextCall->setText("Next: " + m_nextCall);
|
||||||
// ui->labNextCall->setStyleSheet("QLabel {background-color: #66ff66}");
|
// ui->labNextCall->setStyleSheet("QLabel {color: #000000; background-color: #66ff66}");
|
||||||
// }
|
// }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -5742,8 +5764,6 @@ void MainWindow::on_tx6_editingFinished() //tx6 edited
|
|||||||
void MainWindow::on_RoundRobin_currentTextChanged(QString text)
|
void MainWindow::on_RoundRobin_currentTextChanged(QString text)
|
||||||
{
|
{
|
||||||
ui->sbTxPercent->setEnabled (text == tr ("Random"));
|
ui->sbTxPercent->setEnabled (text == tr ("Random"));
|
||||||
m_WSPR_tx_next = false; // cancel any pending Tx to avoid
|
|
||||||
// undesirable consecutive Tx periods
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6852,7 +6872,11 @@ void MainWindow::band_changed (Frequency f)
|
|||||||
}
|
}
|
||||||
m_lastBand.clear ();
|
m_lastBand.clear ();
|
||||||
m_bandEdited = false;
|
m_bandEdited = false;
|
||||||
m_psk_Reporter.sendReport(); // Upload any queued spots before changing band
|
if (m_config.spot_to_psk_reporter ())
|
||||||
|
{
|
||||||
|
// Upload any queued spots before changing band
|
||||||
|
m_psk_Reporter.sendReport();
|
||||||
|
}
|
||||||
if (!m_transmitting) monitor (true);
|
if (!m_transmitting) monitor (true);
|
||||||
if ("FreqCal" == m_mode)
|
if ("FreqCal" == m_mode)
|
||||||
{
|
{
|
||||||
@ -7178,15 +7202,16 @@ void MainWindow::handle_transceiver_update (Transceiver::TransceiverState const&
|
|||||||
{
|
{
|
||||||
Transceiver::TransceiverState old_state {m_rigState};
|
Transceiver::TransceiverState old_state {m_rigState};
|
||||||
//transmitDisplay (s.ptt ());
|
//transmitDisplay (s.ptt ());
|
||||||
if (s.ptt () && !m_rigState.ptt ()) { // safe to start audio
|
if (s.ptt () // && !m_rigState.ptt ()
|
||||||
|
) { // safe to start audio
|
||||||
// (caveat - DX Lab Suite Commander)
|
// (caveat - DX Lab Suite Commander)
|
||||||
if (m_tx_when_ready && g_iptt) { // waiting to Tx and still needed
|
if (m_tx_when_ready && g_iptt) { // waiting to Tx and still needed
|
||||||
int ms_delay=1000*m_config.txDelay();
|
int ms_delay=1000*m_config.txDelay();
|
||||||
if(m_mode=="FT4") ms_delay=20;
|
if(m_mode=="FT4") ms_delay=20;
|
||||||
ptt1Timer.start(ms_delay); //Start-of-transmission sequencer delay
|
ptt1Timer.start(ms_delay); //Start-of-transmission sequencer delay
|
||||||
}
|
|
||||||
m_tx_when_ready = false;
|
m_tx_when_ready = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_rigState = s;
|
m_rigState = s;
|
||||||
auto old_freqNominal = m_freqNominal;
|
auto old_freqNominal = m_freqNominal;
|
||||||
if (!old_freqNominal)
|
if (!old_freqNominal)
|
||||||
@ -7221,9 +7246,7 @@ void MainWindow::handle_transceiver_update (Transceiver::TransceiverState const&
|
|||||||
|| !(ui->cbCQTx->isEnabled () && ui->cbCQTx->isVisible () && ui->cbCQTx->isChecked()))) {
|
|| !(ui->cbCQTx->isEnabled () && ui->cbCQTx->isVisible () && ui->cbCQTx->isChecked()))) {
|
||||||
m_lastDialFreq = m_freqNominal;
|
m_lastDialFreq = m_freqNominal;
|
||||||
m_secBandChanged=QDateTime::currentMSecsSinceEpoch()/1000;
|
m_secBandChanged=QDateTime::currentMSecsSinceEpoch()/1000;
|
||||||
if (m_config.spot_to_psk_reporter ()) {
|
|
||||||
pskSetLocal ();
|
pskSetLocal ();
|
||||||
}
|
|
||||||
statusChanged();
|
statusChanged();
|
||||||
m_wideGraph->setDialFreq(m_freqNominal / 1.e6);
|
m_wideGraph->setDialFreq(m_freqNominal / 1.e6);
|
||||||
}
|
}
|
||||||
@ -7526,6 +7549,8 @@ bool MainWindow::shortList(QString callsign)
|
|||||||
|
|
||||||
void MainWindow::pskSetLocal ()
|
void MainWindow::pskSetLocal ()
|
||||||
{
|
{
|
||||||
|
if (!m_config.spot_to_psk_reporter ()) return;
|
||||||
|
|
||||||
// find the station row, if any, that matches the band we are on
|
// find the station row, if any, that matches the band we are on
|
||||||
auto stations = m_config.stations ();
|
auto stations = m_config.stations ();
|
||||||
auto matches = stations->match (stations->index (0, StationList::band_column)
|
auto matches = stations->match (stations->index (0, StationList::band_column)
|
||||||
@ -8017,8 +8042,8 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout
|
|||||||
|
|
||||||
QString MainWindow::beacon_start_time (int n)
|
QString MainWindow::beacon_start_time (int n)
|
||||||
{
|
{
|
||||||
auto bt = qt_truncate_date_time_to (QDateTime::currentDateTimeUtc ().addSecs (n), m_TRperiod);
|
auto bt = qt_truncate_date_time_to (QDateTime::currentDateTimeUtc ().addSecs (n), m_TRperiod * 1.e3);
|
||||||
if (m_TRperiod < 60)
|
if (m_TRperiod < 60.)
|
||||||
{
|
{
|
||||||
return bt.toString ("HHmmss");
|
return bt.toString ("HHmmss");
|
||||||
}
|
}
|
||||||
@ -8072,17 +8097,18 @@ void MainWindow::uploadWSPRSpots (bool direct_post, QString const& decode_text)
|
|||||||
QString rfreq = QString("%1").arg((m_dialFreqRxWSPR + 1500) / 1e6, 0, 'f', 6);
|
QString rfreq = QString("%1").arg((m_dialFreqRxWSPR + 1500) / 1e6, 0, 'f', 6);
|
||||||
QString tfreq = QString("%1").arg((m_dialFreqRxWSPR +
|
QString tfreq = QString("%1").arg((m_dialFreqRxWSPR +
|
||||||
ui->TxFreqSpinBox->value()) / 1e6, 0, 'f', 6);
|
ui->TxFreqSpinBox->value()) / 1e6, 0, 'f', 6);
|
||||||
|
auto pct = QString::number (ui->autoButton->isChecked () ? ui->sbTxPercent->value () : 0);
|
||||||
if (!direct_post)
|
if (!direct_post)
|
||||||
{
|
{
|
||||||
wsprNet->upload (m_config.my_callsign (), m_config.my_grid (), rfreq, tfreq,
|
wsprNet->upload (m_config.my_callsign (), m_config.my_grid (), rfreq, tfreq,
|
||||||
m_mode, m_TRperiod, QString::number (ui->autoButton->isChecked () ? m_pctx : 0),
|
m_mode, m_TRperiod, pct,
|
||||||
QString::number (m_dBm), version (),
|
QString::number (m_dBm), version (),
|
||||||
m_config.writeable_data_dir ().absoluteFilePath ("wspr_spots.txt"));
|
m_config.writeable_data_dir ().absoluteFilePath ("wspr_spots.txt"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wsprNet->post (m_config.my_callsign (), m_config.my_grid (), rfreq, tfreq,
|
wsprNet->post (m_config.my_callsign (), m_config.my_grid (), rfreq, tfreq,
|
||||||
m_mode, m_TRperiod, QString::number (ui->autoButton->isChecked () ? m_pctx : 0),
|
m_mode, m_TRperiod, pct,
|
||||||
QString::number (m_dBm), version (), decode_text);
|
QString::number (m_dBm), version (), decode_text);
|
||||||
}
|
}
|
||||||
if (!decode_text.size ())
|
if (!decode_text.size ())
|
||||||
@ -8108,24 +8134,9 @@ void MainWindow::on_TxPowerComboBox_currentIndexChanged(int index)
|
|||||||
m_dBm = ui->TxPowerComboBox->itemData (index).toInt ();
|
m_dBm = ui->TxPowerComboBox->itemData (index).toInt ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_sbTxPercent_valueChanged(int n)
|
|
||||||
{
|
|
||||||
m_pctx=n;
|
|
||||||
if(m_pctx>0) {
|
|
||||||
ui->pbTxNext->setEnabled(true);
|
|
||||||
} else {
|
|
||||||
m_txNext=false;
|
|
||||||
ui->pbTxNext->setChecked(false);
|
|
||||||
ui->pbTxNext->setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_cbUploadWSPR_Spots_toggled(bool b)
|
void MainWindow::on_cbUploadWSPR_Spots_toggled(bool b)
|
||||||
{
|
{
|
||||||
m_uploadWSPRSpots=b;
|
m_uploadWSPRSpots=b;
|
||||||
if(m_uploadWSPRSpots) ui->cbUploadWSPR_Spots->setStyleSheet("");
|
|
||||||
if(!m_uploadWSPRSpots) ui->cbUploadWSPR_Spots->setStyleSheet(
|
|
||||||
"QCheckBox{background-color: yellow}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_WSPRfreqSpinBox_valueChanged(int n)
|
void MainWindow::on_WSPRfreqSpinBox_valueChanged(int n)
|
||||||
@ -8135,11 +8146,20 @@ void MainWindow::on_WSPRfreqSpinBox_valueChanged(int n)
|
|||||||
|
|
||||||
void MainWindow::on_pbTxNext_clicked(bool b)
|
void MainWindow::on_pbTxNext_clicked(bool b)
|
||||||
{
|
{
|
||||||
m_txNext=b;
|
if (b && !ui->autoButton->isChecked ())
|
||||||
|
{
|
||||||
|
ui->autoButton->click (); // make sure Tx is possible
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::WSPR_scheduling ()
|
void MainWindow::WSPR_scheduling ()
|
||||||
{
|
{
|
||||||
|
if (ui->pbTxNext->isEnabled () && ui->pbTxNext->isChecked ())
|
||||||
|
{
|
||||||
|
// Tx Next button overrides all scheduling
|
||||||
|
m_WSPR_tx_next = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
QString t=ui->RoundRobin->currentText();
|
QString t=ui->RoundRobin->currentText();
|
||||||
if(m_mode=="FST4W" and t != tr ("Random")) {
|
if(m_mode=="FST4W" and t != tr ("Random")) {
|
||||||
bool ok;
|
bool ok;
|
||||||
@ -8152,10 +8172,14 @@ void MainWindow::WSPR_scheduling ()
|
|||||||
int nsec=ms/1000;
|
int nsec=ms/1000;
|
||||||
int ntr=m_TRperiod;
|
int ntr=m_TRperiod;
|
||||||
int j=((nsec+ntr-1) % (n*ntr))/ntr;
|
int j=((nsec+ntr-1) % (n*ntr))/ntr;
|
||||||
m_WSPR_tx_next=(i==j);
|
m_WSPR_tx_next = i == j;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_WSPR_tx_next = false;
|
m_WSPR_tx_next = false;
|
||||||
|
if (!ui->sbTxPercent->isEnabled () || !ui->sbTxPercent->value ())
|
||||||
|
{
|
||||||
|
return; // don't schedule if %age disabled or zero
|
||||||
|
}
|
||||||
if (m_config.is_transceiver_online () // need working rig control for hopping
|
if (m_config.is_transceiver_online () // need working rig control for hopping
|
||||||
&& !m_config.is_dummy_rig ()
|
&& !m_config.is_dummy_rig ()
|
||||||
&& ui->band_hopping_group_box->isChecked ()) {
|
&& ui->band_hopping_group_box->isChecked ()) {
|
||||||
@ -8442,7 +8466,7 @@ void MainWindow::tx_watchdog (bool triggered)
|
|||||||
m_bTxTime=false;
|
m_bTxTime=false;
|
||||||
if (m_tune) stop_tuning ();
|
if (m_tune) stop_tuning ();
|
||||||
if (m_auto) auto_tx_mode (false);
|
if (m_auto) auto_tx_mode (false);
|
||||||
tx_status_label.setStyleSheet ("QLabel{background-color: #ff0000}");
|
tx_status_label.setStyleSheet ("QLabel{color: #000000; background-color: #ff0000}");
|
||||||
tx_status_label.setText (tr ("Runaway Tx watchdog"));
|
tx_status_label.setText (tr ("Runaway Tx watchdog"));
|
||||||
QApplication::alert (this);
|
QApplication::alert (this);
|
||||||
}
|
}
|
||||||
|
@ -346,6 +346,7 @@ private:
|
|||||||
int TRperiod=60) const;
|
int TRperiod=60) const;
|
||||||
Q_SIGNAL void outAttenuationChanged (qreal) const;
|
Q_SIGNAL void outAttenuationChanged (qreal) const;
|
||||||
Q_SIGNAL void toggleShorthand () const;
|
Q_SIGNAL void toggleShorthand () const;
|
||||||
|
Q_SIGNAL void reset_audio_input_stream (bool report_dropped_frames) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_mode (QString const& mode);
|
void set_mode (QString const& mode);
|
||||||
@ -445,7 +446,6 @@ private:
|
|||||||
qint32 m_nclearave;
|
qint32 m_nclearave;
|
||||||
qint32 m_minSync;
|
qint32 m_minSync;
|
||||||
qint32 m_dBm;
|
qint32 m_dBm;
|
||||||
qint32 m_pctx;
|
|
||||||
qint32 m_nseq;
|
qint32 m_nseq;
|
||||||
qint32 m_nWSPRdecodes;
|
qint32 m_nWSPRdecodes;
|
||||||
qint32 m_k0;
|
qint32 m_k0;
|
||||||
@ -504,7 +504,6 @@ private:
|
|||||||
bool m_bSWL;
|
bool m_bSWL;
|
||||||
bool m_uploadWSPRSpots;
|
bool m_uploadWSPRSpots;
|
||||||
bool m_uploading;
|
bool m_uploading;
|
||||||
bool m_txNext;
|
|
||||||
bool m_grid6;
|
bool m_grid6;
|
||||||
bool m_tuneup;
|
bool m_tuneup;
|
||||||
bool m_bTxTime;
|
bool m_bTxTime;
|
||||||
@ -666,8 +665,6 @@ private:
|
|||||||
|
|
||||||
QSharedMemory *mem_jt9;
|
QSharedMemory *mem_jt9;
|
||||||
QString m_QSOText;
|
QString m_QSOText;
|
||||||
unsigned m_msAudioOutputBuffered;
|
|
||||||
unsigned m_framesAudioInputBuffered;
|
|
||||||
unsigned m_downSampleFactor;
|
unsigned m_downSampleFactor;
|
||||||
QThread::Priority m_audioThreadPriority;
|
QThread::Priority m_audioThreadPriority;
|
||||||
bool m_bandEdited;
|
bool m_bandEdited;
|
||||||
|
@ -376,6 +376,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton:checked {
|
<string notr="true">QPushButton:checked {
|
||||||
|
color: #000000;
|
||||||
background-color: #00ff00;
|
background-color: #00ff00;
|
||||||
border-style: outset;
|
border-style: outset;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -447,6 +448,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton:checked {
|
<string notr="true">QPushButton:checked {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
background-color: cyan;
|
background-color: cyan;
|
||||||
border-style: outset;
|
border-style: outset;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -480,6 +482,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton:checked {
|
<string notr="true">QPushButton:checked {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
background-color: red;
|
background-color: red;
|
||||||
border-style: outset;
|
border-style: outset;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -523,6 +526,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton:checked {
|
<string notr="true">QPushButton:checked {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
background-color: red;
|
background-color: red;
|
||||||
border-style: outset;
|
border-style: outset;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -997,6 +1001,7 @@ Not available to nonstandard callsign holders.</string>
|
|||||||
<widget class="QPushButton" name="pbBestSP">
|
<widget class="QPushButton" name="pbBestSP">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton:checked {
|
<string notr="true">QPushButton:checked {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
background-color: red;
|
background-color: red;
|
||||||
border-style: outset;
|
border-style: outset;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -2158,6 +2163,12 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Percentage of minute sequences devoted to transmitting.</string>
|
<string>Percentage of minute sequences devoted to transmitting.</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QSpinBox:enabled[notx="true"] {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
background-color: rgb(255, 255, 0);
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
@ -2341,6 +2352,12 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Upload decoded messages to WSPRnet.org.</string>
|
<string>Upload decoded messages to WSPRnet.org.</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QCheckBox:unchecked {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
|
background-color: rgb(255, 255, 0);
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Upload spots</string>
|
<string>Upload spots</string>
|
||||||
</property>
|
</property>
|
||||||
@ -2380,6 +2397,7 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QPushButton:checked {
|
<string notr="true">QPushButton:checked {
|
||||||
|
color: rgb(0, 0, 0);
|
||||||
background-color: red;
|
background-color: red;
|
||||||
border-style: outset;
|
border-style: outset;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -2485,8 +2503,7 @@ list. The list can be maintained in Settings (F2).</string>
|
|||||||
}
|
}
|
||||||
QLabel[oob="true"] {
|
QLabel[oob="true"] {
|
||||||
background-color: red;
|
background-color: red;
|
||||||
}
|
}</string>
|
||||||
</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>14.078 000</string>
|
<string>14.078 000</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user