WSJT-X/TransceiverBase.cpp
Bill Somerville 04de2ce95d Rig polling not detecting changes against cached values correctly
The  PollingTransceiver class  was not  dealing with  frequency change
commands correctly when the mode was not specified.

Improved some diagnostic messages.

Only leave transmit mode when PTT is seen to drop.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx-1.4@4885 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
2015-01-08 23:45:58 +00:00

317 lines
5.3 KiB
C++

#include "TransceiverBase.hpp"
#include <exception>
#include <QString>
#include "pimpl_impl.hpp"
namespace
{
auto const unexpected = TransceiverBase::tr ("Unexpected rig error");
}
class TransceiverBase::impl final
: public QObject
{
Q_OBJECT;
public:
impl (TransceiverBase * parent)
: parent_ {parent}
{
connect (this, &TransceiverBase::impl::updated, this, &TransceiverBase::impl::update_complete, Qt::QueuedConnection);
}
impl (impl const&) = delete;
impl& operator = (impl const&) = delete;
Q_SIGNAL void updated ();
Q_SLOT void update_complete ()
{
if (parent_->do_pre_update ())
{
Q_EMIT parent_->update (state_);
}
}
TransceiverBase * parent_;
TransceiverState state_;
};
#include "TransceiverBase.moc"
TransceiverBase::TransceiverBase ()
: m_ {this}
{
}
TransceiverBase::~TransceiverBase ()
{
}
void TransceiverBase::start () noexcept
{
QString message;
try
{
if (m_->state_.online ())
{
m_->state_.online (false);
// ensure PTT isn't left set
do_ptt (false);
do_post_ptt (false);
do_stop ();
do_post_stop ();
}
do_start ();
do_post_start ();
m_->state_.online (true);
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
if (!message.isEmpty ())
{
offline (message);
}
}
void TransceiverBase::stop () noexcept
{
QString message;
try
{
if (m_->state_.online ())
{
m_->state_.online (false);
// ensure PTT isn't left set
do_ptt (false);
do_post_ptt (false);
}
do_stop ();
do_post_stop ();
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
if (!message.isEmpty ())
{
offline (message);
}
else
{
Q_EMIT finished ();
}
}
void TransceiverBase::frequency (Frequency f, MODE m) noexcept
{
QString message;
try
{
if (m_->state_.online ())
{
do_frequency (f, m);
do_post_frequency (f, m);
}
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
if (!message.isEmpty ())
{
offline (message);
}
}
void TransceiverBase::tx_frequency (Frequency tx, bool rationalise_mode) noexcept
{
QString message;
try
{
if (m_->state_.online ())
{
do_tx_frequency (tx, rationalise_mode);
do_post_tx_frequency (tx, rationalise_mode);
}
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
if (!message.isEmpty ())
{
offline (message);
}
}
void TransceiverBase::mode (MODE m, bool rationalise) noexcept
{
QString message;
try
{
if (m_->state_.online ())
{
do_mode (m, rationalise);
do_post_mode (m, rationalise);
}
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
if (!message.isEmpty ())
{
offline (message);
}
}
void TransceiverBase::ptt (bool on) noexcept
{
QString message;
try
{
if (m_->state_.online ())
{
do_ptt (on);
do_post_ptt (on);
}
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
if (!message.isEmpty ())
{
offline (message);
}
}
void TransceiverBase::sync (bool force_signal) noexcept
{
QString message;
try
{
if (m_->state_.online ())
{
do_sync (force_signal);
}
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
if (!message.isEmpty ())
{
offline (message);
}
}
void TransceiverBase::update_rx_frequency (Frequency rx)
{
m_->state_.frequency (rx);
}
void TransceiverBase::update_other_frequency (Frequency tx)
{
m_->state_.tx_frequency (tx);
}
void TransceiverBase::update_split (bool state)
{
m_->state_.split (state);
}
void TransceiverBase::update_mode (MODE m)
{
m_->state_.mode (m);
}
void TransceiverBase::update_PTT (bool state)
{
auto prior = m_->state_.ptt ();
m_->state_.ptt (state);
if (state != prior)
{
// always signal PTT changes because some MainWindow logic
// depends on it
update_complete ();
}
}
void TransceiverBase::update_complete ()
{
// Use a signal to ensure that the calling function completes before
// the Transceiver::update signal is triggered.
Q_EMIT m_->updated ();
}
void TransceiverBase::offline (QString const& reason)
{
QString message;
try
{
if (m_->state_.online ())
{
m_->state_.online (false);
// ensure PTT isn't left set
do_ptt (false);
do_post_ptt (false);
}
do_stop ();
do_post_stop ();
}
catch (std::exception const& e)
{
message = e.what ();
}
catch (...)
{
message = unexpected;
}
Q_EMIT failure (reason + '\n' + message);
}
auto TransceiverBase::state () const -> TransceiverState const&
{
return m_->state_;
}