From 80728a8f9a625a57a664e9e492c1dff6b543e14e Mon Sep 17 00:00:00 2001 From: Bill Somerville Date: Fri, 27 Oct 2017 12:51:09 +0000 Subject: [PATCH] Merged from trunk: ------------------------------------------------------------------------ r8179 | k1jt | 2017-10-23 14:41:11 +0100 (Mon, 23 Oct 2017) | 2 lines Clarify some User Guide text about AP decoding. ------------------------------------------------------------------------ r8181 | k1jt | 2017-10-23 19:59:42 +0100 (Mon, 23 Oct 2017) | 2 lines Clarify some wording of command-line startup options for wsjtx. ------------------------------------------------------------------------ r8183 | k1jt | 2017-10-24 18:47:05 +0100 (Tue, 24 Oct 2017) | 2 lines Improve User Guide text on AP decoding. ------------------------------------------------------------------------ r8184 | k1jt | 2017-10-25 21:20:39 +0100 (Wed, 25 Oct 2017) | 2 lines Make the "Controls" label slightly wider. ------------------------------------------------------------------------ r8185 | k1jt | 2017-10-25 21:21:48 +0100 (Wed, 25 Oct 2017) | 2 lines Add a tip. ------------------------------------------------------------------------ r8186 | bsomervi | 2017-10-27 13:38:25 +0100 (Fri, 27 Oct 2017) | 5 lines Add a contextual pop up menu to the wide graph Initial button added is to set both Tx and Rx offset. Tidied up encapsulation issue in CPlotter class. ------------------------------------------------------------------------ Bumped RC number. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx-1.8@8187 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- Versions.cmake | 2 +- .../en/controls-functions-main-window.adoc | 4 ++ .../en/controls-functions-menus.adoc | 9 ++- .../en/controls-functions-messages.adoc | 2 +- doc/user_guide/en/decoder_notes.adoc | 52 +++++++------- plotter.cpp | 72 ++++++++++++------- plotter.h | 20 +++--- widegraph.cpp | 6 +- widegraph.ui | 2 +- 9 files changed, 101 insertions(+), 68 deletions(-) diff --git a/Versions.cmake b/Versions.cmake index 8c675a330..b6daef99c 100644 --- a/Versions.cmake +++ b/Versions.cmake @@ -2,5 +2,5 @@ set (WSJTX_VERSION_MAJOR 1) set (WSJTX_VERSION_MINOR 8) set (WSJTX_VERSION_PATCH 0) -set (WSJTX_RC 3) # release candidate number, comment out or zero for development versions +set (WSJTX_RC 4) # release candidate number, comment out or zero for development versions set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build diff --git a/doc/user_guide/en/controls-functions-main-window.adoc b/doc/user_guide/en/controls-functions-main-window.adoc index 5b3267098..6c21d9fa2 100644 --- a/doc/user_guide/en/controls-functions-main-window.adoc +++ b/doc/user_guide/en/controls-functions-main-window.adoc @@ -33,6 +33,10 @@ the original frequency. * *Erase* clears the right-hand decoded text window. Double-clicking *Erase* clears both text windows. +TIP: Right-clicking on either text window brings up a context menu +with several options (including *Erase*) which operate on that window +alone. + * *Clear Avg* is present only in modes that support message averaging. It provides a way to erase the accumulating information, thus preparing to start a new average. diff --git a/doc/user_guide/en/controls-functions-menus.adoc b/doc/user_guide/en/controls-functions-menus.adoc index 6c2a3b26f..dc43b0fa1 100644 --- a/doc/user_guide/en/controls-functions-menus.adoc +++ b/doc/user_guide/en/controls-functions-menus.adoc @@ -27,8 +27,13 @@ configuration. These settings will be restored whenever you select that configuration. As well as switching between configurations while running _WSJT-X_ you -can also start the application in any configuration by using the -`--config ` command line option (`-c` for short). +can also start the application from the command line in any desired +configuration. Use the command-line option +`--config `, or `-c` for short, as in these +examples for configurations `FT8` and `Echo`: + + wsjtx --config FT8 + wsjtx -c Echo [[VIEW_MENU]] ==== View Menu diff --git a/doc/user_guide/en/controls-functions-messages.adoc b/doc/user_guide/en/controls-functions-messages.adoc index cb4f0f8b4..c712feada 100644 --- a/doc/user_guide/en/controls-functions-messages.adoc +++ b/doc/user_guide/en/controls-functions-messages.adoc @@ -16,7 +16,7 @@ Tx sequence) by clicking on the circle under *Next*. * To change to a specified Tx message immediately during a transmission, click on a rectangular button under the *Now* label. Changing a Tx message in mid-stream will slightly reduce the chance of -a correct decode, but it is usually OK if done in the first 10-15 s of +a correct decode, but it is usually OK if done in the first 10-20% of a transmission. * All six Tx message fields are editable. You can modify an diff --git a/doc/user_guide/en/decoder_notes.adoc b/doc/user_guide/en/decoder_notes.adoc index 83e8a8b05..33f4df6ed 100644 --- a/doc/user_guide/en/decoder_notes.adoc +++ b/doc/user_guide/en/decoder_notes.adoc @@ -1,34 +1,26 @@ === AP Decoding -With the QRA64 decoder Nico Palermo, IV3NWV, introduced a technique -for decoding with the aid of information that naturally accumulates -during a minimal QSO. This _a priori_ (AP) information can be -used to increase the sensitivity of the decoder. +The _WSJT-X_ decoders for QRA64 and FT8 include optional procedures +that use naturally accumulating information during a minimal QSO. +This _a priori_ (AP) information increases sensitivity of the decoder +by up to 4 dB, at the cost of a slightly higher rate of false decodes. -When an operator decides to answer a CQ, he already knows his own -callsign and that of his potential QSO partner. He therefore knows -what to expect for at least 56 of the 72 message bits in a -standard-format response to his call. The _WSJT-X_ decoders for QRA64 -and FT8 can use these and similar AP bits to decode messages -containing them with higher sensitivity than otherwise possible. +For example: when you decide to answer a CQ, you already know your own +callsign and that of your potential QSO partner. The software +therefore "`knows`" what to expect for 57 of the 72 message bits (28 +bits for each of two callsigns, 1 bit for message type) in the next +received message. The decoder's task can thus be reduced to +determining the remaining 15 bits of the message and ensuring that the +resulting solution is reliable. -We have implemented AP decoding in slightly different ways in QRA64 -and FT8. To provide some explicit examples for users, we provide here -a brief description of the FT8 behavior. - -AP decoding attempts effectively set the AP bits to the hypothesized -values, as if they had been received correctly. The decoder then -proceeds to determine whether the remaining message and parity bits -are consistent with the hypothesized AP bits. If a codeword is found -that the decoder judges to have high (but not overwhelmingly high) -probability of being correct, a ? character is appended when the -decoded message is displayed. To avoid misleading spots of occasional -false decodes, messages so marked are not forwarded to {pskreporter}. - -Successful AP decodes are always labeled with an end-of-line indicator -of the form aP, where P is one of the single-digit AP decoding types -listed in Table 1. For example, an `a2` designator says that the -successful decode used MyCall as hypothetically known information. +AP decoding starts by setting AP bits to the hypothesized values, as +if they had been received correctly. We then determine whether the +remaining message and parity bits are consistent with the hypothesized +AP bits, with a specified level of confidence. Successful AP decodes +are labeled with an end-of-line indicator of the form `aP`, where `P` +is one of the single-digit AP decoding types listed in Table 1. For +example, `a2` indicates that the successful decode used MyCall as +hypothetically known information. [[AP_INFO_TABLE]] .AP information types @@ -43,6 +35,12 @@ successful decode used MyCall as hypothetically known information. |6 | MyCall DxCall RR73 |=============================================== +If a codeword is found that is judged to have high (but not +overwhelmingly high) probability of being correct, a `?` character is +appended when the decoded message is displayed. To avoid misleading +spots of occasional false decodes, messages so marked are not +forwarded to {pskreporter}. + Table 2 lists the six possible QSO states that are tracked by the _WSJT-X_ auto-sequencer, along with the type of AP decoding that would be attempted in each state. diff --git a/plotter.cpp b/plotter.cpp index e6635aa18..1c60d0277 100644 --- a/plotter.cpp +++ b/plotter.cpp @@ -10,6 +10,7 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor QFrame {parent}, + m_set_freq_action {new QAction {tr ("&Set Rx && Tx Offset"), this}}, m_bScaleOK {false}, m_bReference {false}, m_bReference0 {false}, @@ -42,6 +43,19 @@ CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor setAutoFillBackground(false); setAttribute(Qt::WA_OpaquePaintEvent, false); setAttribute(Qt::WA_NoSystemBackground, true); + + // contextual pop up menu + setContextMenuPolicy (Qt::CustomContextMenu); + connect (this, &QWidget::customContextMenuRequested, [this] (QPoint const& pos) { + QMenu menu {this}; + menu.addAction (m_set_freq_action); + auto const& connection = connect (m_set_freq_action, &QAction::triggered, [this, pos] () { + int newFreq = FreqfromX (pos.x ()) + .5; + emit setFreq1 (newFreq, newFreq); + }); + menu.exec (mapToGlobal (pos)); + disconnect (connection); + }); } CPlotter::~CPlotter() { } // Destructor @@ -629,35 +643,45 @@ void CPlotter::setRxFreq (int x) //setRxFreq int CPlotter::rxFreq() {return m_rxFreq;} //rxFreq -void CPlotter::mousePressEvent(QMouseEvent *event) //mousePressEvent +void CPlotter::mouseReleaseEvent (QMouseEvent * event) { - int x=event->x(); - if(x<0) x=0; - if(x>m_Size.width()) x=m_Size.width(); - bool ctrl = (event->modifiers() & Qt::ControlModifier); - bool shift = (event->modifiers() & Qt::ShiftModifier); - int newFreq = int(FreqfromX(x)+0.5); - int oldTxFreq = m_txFreq; - int oldRxFreq = m_rxFreq; - if (ctrl) { - emit setFreq1 (newFreq, newFreq); - } else if (shift) { - emit setFreq1 (oldRxFreq, newFreq); - } else { - emit setFreq1(newFreq,oldTxFreq); - } + if (Qt::LeftButton == event->button ()) { + int x=event->x(); + if(x<0) x=0; + if(x>m_Size.width()) x=m_Size.width(); + bool ctrl = (event->modifiers() & Qt::ControlModifier); + bool shift = (event->modifiers() & Qt::ShiftModifier); + int newFreq = int(FreqfromX(x)+0.5); + int oldTxFreq = m_txFreq; + int oldRxFreq = m_rxFreq; + if (ctrl) { + emit setFreq1 (newFreq, newFreq); + } else if (shift) { + emit setFreq1 (oldRxFreq, newFreq); + } else { + emit setFreq1(newFreq,oldTxFreq); + } - int n=1; - if(ctrl) n+=100; - emit freezeDecode1(n); + int n=1; + if(ctrl) n+=100; + emit freezeDecode1(n); + } + else { + event->ignore (); // let parent handle + } } -void CPlotter::mouseDoubleClickEvent(QMouseEvent *event) //mouse2click +void CPlotter::mouseDoubleClickEvent (QMouseEvent * event) { - bool ctrl = (event->modifiers() & Qt::ControlModifier); - int n=2; - if(ctrl) n+=100; - emit freezeDecode1(n); + if (Qt::LeftButton == event->button ()) { + bool ctrl = (event->modifiers() & Qt::ControlModifier); + int n=2; + if(ctrl) n+=100; + emit freezeDecode1(n); + } + else { + event->ignore (); // let parent handle + } } void CPlotter::setNsps(int ntrperiod, int nsps) //setNsps diff --git a/plotter.h b/plotter.h index 67e51c9fa..2986a1c77 100644 --- a/plotter.h +++ b/plotter.h @@ -23,9 +23,11 @@ extern bool g_single_decode; +class QAction; + class CPlotter : public QFrame { - Q_OBJECT; + Q_OBJECT public: explicit CPlotter(QWidget *parent = 0); @@ -33,7 +35,6 @@ public: QSize minimumSizeHint() const; QSize sizeHint() const; - bool m_bScaleOK; void draw(float swide[], bool bScroll, bool bRed); //Update the waterfall void SetRunningState(bool running); @@ -84,15 +85,17 @@ public: void drawRed(int ia, int ib, float swide[]); void setVHF(bool bVHF); void setRedFile(QString fRed); - + bool scaleOK () const {return m_bScaleOK;} signals: void freezeDecode1(int n); void setFreq1(int rxFreq, int txFreq); protected: //re-implemented widget event handlers - void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent* event); + void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent* event) override; + void mouseReleaseEvent (QMouseEvent * event) override; + void mouseDoubleClickEvent (QMouseEvent * event) override; private: @@ -100,6 +103,9 @@ private: int XfromFreq(float f); float FreqfromX(int x); + QAction * m_set_freq_action; + + bool m_bScaleOK; bool m_bCurrent; bool m_bCumulative; bool m_bLinearAvg; @@ -166,10 +172,6 @@ private: qint32 m_tol; char m_sutc[6]; - -private slots: - void mousePressEvent(QMouseEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); }; extern QVector g_ColorTbl; diff --git a/widegraph.cpp b/widegraph.cpp index 4bfa744f8..2ae25bc19 100644 --- a/widegraph.cpp +++ b/widegraph.cpp @@ -322,7 +322,7 @@ void WideGraph::on_spec2dComboBox_currentIndexChanged(const QString &arg1) if(arg1=="Reference") { ui->widePlot->setReference(true); } - if(ui->widePlot->m_bScaleOK) ui->widePlot->draw(swide,false,false); + if(ui->widePlot->scaleOK ()) ui->widePlot->draw(swide,false,false); } void WideGraph::on_fSplitSpinBox_valueChanged(int n) //fSplit @@ -454,7 +454,7 @@ void WideGraph::on_zeroSlider_valueChanged(int value) //Zero void WideGraph::on_gain2dSlider_valueChanged(int value) //Gain2 { ui->widePlot->setPlot2dGain(value); - if(ui->widePlot->m_bScaleOK) { + if(ui->widePlot->scaleOK ()) { ui->widePlot->draw(swide,false,false); if(m_mode=="QRA64") ui->widePlot->draw(swide,false,true); } @@ -463,7 +463,7 @@ void WideGraph::on_gain2dSlider_valueChanged(int value) //Gain2 void WideGraph::on_zero2dSlider_valueChanged(int value) //Zero2 { ui->widePlot->setPlot2dZero(value); - if(ui->widePlot->m_bScaleOK) { + if(ui->widePlot->scaleOK ()) { ui->widePlot->draw(swide,false,false); if(m_mode=="QRA64") ui->widePlot->draw(swide,false,true); } diff --git a/widegraph.ui b/widegraph.ui index e4ccf4099..f17a60904 100644 --- a/widegraph.ui +++ b/widegraph.ui @@ -60,7 +60,7 @@ 5 0 - 63 + 77 17