Merge tag 'wsjtx-2.0.0-rc6' into develop
WSJT-X v2.0.0 RC6 release
@ -271,6 +271,8 @@ set (wsjt_qt_CXXSRCS
|
|||||||
item_delegates/CallsignDelegate.cpp
|
item_delegates/CallsignDelegate.cpp
|
||||||
item_delegates/MaidenheadLocatorDelegate.cpp
|
item_delegates/MaidenheadLocatorDelegate.cpp
|
||||||
models/CabrilloLog.cpp
|
models/CabrilloLog.cpp
|
||||||
|
logbook/AD1CCty.cpp
|
||||||
|
logbook/WorkedBefore.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set (wsjt_qtmm_CXXSRCS
|
set (wsjt_qtmm_CXXSRCS
|
||||||
@ -288,8 +290,6 @@ set (jt9_CXXSRCS
|
|||||||
|
|
||||||
set (wsjtx_CXXSRCS
|
set (wsjtx_CXXSRCS
|
||||||
logbook/logbook.cpp
|
logbook/logbook.cpp
|
||||||
logbook/WorkedBefore.cpp
|
|
||||||
logbook/AD1CCty.cpp
|
|
||||||
psk_reporter.cpp
|
psk_reporter.cpp
|
||||||
Modulator.cpp
|
Modulator.cpp
|
||||||
Detector.cpp
|
Detector.cpp
|
||||||
@ -322,14 +322,12 @@ set (wsjtx_CXXSRCS
|
|||||||
|
|
||||||
set (wsjt_CXXSRCS
|
set (wsjt_CXXSRCS
|
||||||
lib/crc10.cpp
|
lib/crc10.cpp
|
||||||
lib/crc12.cpp
|
|
||||||
lib/crc13.cpp
|
lib/crc13.cpp
|
||||||
lib/crc14.cpp
|
lib/crc14.cpp
|
||||||
)
|
)
|
||||||
# deal with a GCC v6 UB error message
|
# deal with a GCC v6 UB error message
|
||||||
set_source_files_properties (
|
set_source_files_properties (
|
||||||
lib/crc10.cpp
|
lib/crc10.cpp
|
||||||
lib/crc12.cpp
|
|
||||||
lib/crc13.cpp
|
lib/crc13.cpp
|
||||||
lib/crc14.cpp
|
lib/crc14.cpp
|
||||||
PROPERTIES COMPILE_FLAGS -fpermissive)
|
PROPERTIES COMPILE_FLAGS -fpermissive)
|
||||||
@ -384,13 +382,11 @@ set (wsjt_FSRCS
|
|||||||
lib/ft8/baseline.f90
|
lib/ft8/baseline.f90
|
||||||
lib/bpdecode40.f90
|
lib/bpdecode40.f90
|
||||||
lib/bpdecode128_90.f90
|
lib/bpdecode128_90.f90
|
||||||
lib/ft8/bpdecode174.f90
|
|
||||||
lib/ft8/bpdecode174_91.f90
|
lib/ft8/bpdecode174_91.f90
|
||||||
lib/baddata.f90
|
lib/baddata.f90
|
||||||
lib/calibrate.f90
|
lib/calibrate.f90
|
||||||
lib/ccf2.f90
|
lib/ccf2.f90
|
||||||
lib/ccf65.f90
|
lib/ccf65.f90
|
||||||
lib/ft8/chkcrc12a.f90
|
|
||||||
lib/ft8/chkcrc13a.f90
|
lib/ft8/chkcrc13a.f90
|
||||||
lib/ft8/chkcrc14a.f90
|
lib/ft8/chkcrc14a.f90
|
||||||
lib/chkcall.f90
|
lib/chkcall.f90
|
||||||
@ -508,7 +504,6 @@ set (wsjt_FSRCS
|
|||||||
lib/msk144sim.f90
|
lib/msk144sim.f90
|
||||||
lib/mskrtd.f90
|
lib/mskrtd.f90
|
||||||
lib/77bit/my_hash.f90
|
lib/77bit/my_hash.f90
|
||||||
lib/ft8/osd174.f90
|
|
||||||
lib/wsprd/osdwspr.f90
|
lib/wsprd/osdwspr.f90
|
||||||
lib/ft8/osd174_91.f90
|
lib/ft8/osd174_91.f90
|
||||||
lib/pctile.f90
|
lib/pctile.f90
|
||||||
|
@ -182,6 +182,7 @@
|
|||||||
#include "validators/CallsignValidator.hpp"
|
#include "validators/CallsignValidator.hpp"
|
||||||
#include "LotWUsers.hpp"
|
#include "LotWUsers.hpp"
|
||||||
#include "models/DecodeHighlightingModel.hpp"
|
#include "models/DecodeHighlightingModel.hpp"
|
||||||
|
#include "logbook/logbook.h"
|
||||||
|
|
||||||
#include "ui_Configuration.h"
|
#include "ui_Configuration.h"
|
||||||
#include "moc_Configuration.cpp"
|
#include "moc_Configuration.cpp"
|
||||||
@ -199,16 +200,18 @@ namespace
|
|||||||
QRegularExpression RTTY_roundup_exchange_re {
|
QRegularExpression RTTY_roundup_exchange_re {
|
||||||
R"(
|
R"(
|
||||||
(
|
(
|
||||||
AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA # states
|
AL|AZ|AR|CA|CO|CT|DE|FL|GA # 48 contiguous states
|
||||||
|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD
|
|ID|IL|IN|IA|KS|KY|LA|ME|MD
|
||||||
|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ
|
|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ
|
||||||
|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC
|
|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC
|
||||||
|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY
|
|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY
|
||||||
|NB|NS|QC|ON|MB|SK|AB|BC|NWT|NF # VE provinces
|
|NB|NS|QC|ON|MB|SK|AB|BC|NWT|NF # VE provinces
|
||||||
|LB|NU|YT|PEI|DC
|
|LB|NU|YT|PEI
|
||||||
|
|DC # District of Columbia
|
||||||
|DX # anyone else
|
|DX # anyone else
|
||||||
)
|
)
|
||||||
)", QRegularExpression::CaseInsensitiveOption | QRegularExpression::ExtendedPatternSyntaxOption};
|
)", QRegularExpression::CaseInsensitiveOption | QRegularExpression::ExtendedPatternSyntaxOption};
|
||||||
|
|
||||||
QRegularExpression field_day_exchange_re {
|
QRegularExpression field_day_exchange_re {
|
||||||
R"(
|
R"(
|
||||||
(
|
(
|
||||||
@ -216,7 +219,7 @@ namespace
|
|||||||
|[0-2]\d
|
|[0-2]\d
|
||||||
|3[0-2]
|
|3[0-2]
|
||||||
)
|
)
|
||||||
[A-F]\ # class and space
|
[A-F]\ * # class and optional space
|
||||||
(
|
(
|
||||||
AB|AK|AL|AR|AZ|BC|CO|CT|DE|EB # ARRL/RAC section
|
AB|AK|AL|AR|AZ|BC|CO|CT|DE|EB # ARRL/RAC section
|
||||||
|EMA|ENY|EPA|EWA|GA|GTA|IA|ID
|
|EMA|ENY|EPA|EWA|GA|GTA|IA|ID
|
||||||
@ -395,6 +398,7 @@ public:
|
|||||||
, QNetworkAccessManager * network_manager
|
, QNetworkAccessManager * network_manager
|
||||||
, QDir const& temp_directory
|
, QDir const& temp_directory
|
||||||
, QSettings * settings
|
, QSettings * settings
|
||||||
|
, LogBook * logbook
|
||||||
, QWidget * parent);
|
, QWidget * parent);
|
||||||
~impl ();
|
~impl ();
|
||||||
|
|
||||||
@ -480,11 +484,14 @@ private:
|
|||||||
Q_SLOT void handle_transceiver_update (TransceiverState const&, unsigned sequence_number);
|
Q_SLOT void handle_transceiver_update (TransceiverState const&, unsigned sequence_number);
|
||||||
Q_SLOT void handle_transceiver_failure (QString const& reason);
|
Q_SLOT void handle_transceiver_failure (QString const& reason);
|
||||||
Q_SLOT void on_reset_highlighting_to_defaults_push_button_clicked (bool);
|
Q_SLOT void on_reset_highlighting_to_defaults_push_button_clicked (bool);
|
||||||
|
Q_SLOT void on_rescan_log_push_button_clicked (bool);
|
||||||
Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
|
Q_SLOT void on_LotW_CSV_fetch_push_button_clicked (bool);
|
||||||
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
|
Q_SLOT void on_cbx2ToneSpacing_clicked(bool);
|
||||||
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
|
Q_SLOT void on_cbx4ToneSpacing_clicked(bool);
|
||||||
Q_SLOT void on_prompt_to_log_check_box_clicked(bool);
|
Q_SLOT void on_prompt_to_log_check_box_clicked(bool);
|
||||||
Q_SLOT void on_cbAutoLog_clicked(bool);
|
Q_SLOT void on_cbAutoLog_clicked(bool);
|
||||||
|
Q_SLOT void on_Field_Day_Exchange_textEdited (QString const&);
|
||||||
|
Q_SLOT void on_RTTY_Exchange_textEdited (QString const&);
|
||||||
|
|
||||||
// typenames used as arguments must match registered type names :(
|
// typenames used as arguments must match registered type names :(
|
||||||
Q_SIGNAL void start_transceiver (unsigned seqeunce_number) const;
|
Q_SIGNAL void start_transceiver (unsigned seqeunce_number) const;
|
||||||
@ -502,6 +509,7 @@ private:
|
|||||||
|
|
||||||
QNetworkAccessManager * network_manager_;
|
QNetworkAccessManager * network_manager_;
|
||||||
QSettings * settings_;
|
QSettings * settings_;
|
||||||
|
LogBook * logbook_;
|
||||||
|
|
||||||
QDir doc_dir_;
|
QDir doc_dir_;
|
||||||
QDir data_dir_;
|
QDir data_dir_;
|
||||||
@ -638,8 +646,8 @@ private:
|
|||||||
|
|
||||||
// delegate to implementation class
|
// delegate to implementation class
|
||||||
Configuration::Configuration (QNetworkAccessManager * network_manager, QDir const& temp_directory,
|
Configuration::Configuration (QNetworkAccessManager * network_manager, QDir const& temp_directory,
|
||||||
QSettings * settings, QWidget * parent)
|
QSettings * settings, LogBook * logbook, QWidget * parent)
|
||||||
: m_ {this, network_manager, temp_directory, settings, parent}
|
: m_ {this, network_manager, temp_directory, settings, logbook, parent}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,13 +913,15 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network_manager
|
Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network_manager
|
||||||
, QDir const& temp_directory, QSettings * settings, QWidget * parent)
|
, QDir const& temp_directory, QSettings * settings, LogBook * logbook
|
||||||
|
, QWidget * parent)
|
||||||
: QDialog {parent}
|
: QDialog {parent}
|
||||||
, self_ {self}
|
, self_ {self}
|
||||||
, transceiver_thread_ {nullptr}
|
, transceiver_thread_ {nullptr}
|
||||||
, ui_ {new Ui::configuration_dialog}
|
, ui_ {new Ui::configuration_dialog}
|
||||||
, network_manager_ {network_manager}
|
, network_manager_ {network_manager}
|
||||||
, settings_ {settings}
|
, settings_ {settings}
|
||||||
|
, logbook_ {logbook}
|
||||||
, doc_dir_ {doc_path ()}
|
, doc_dir_ {doc_path ()}
|
||||||
, data_dir_ {data_path ()}
|
, data_dir_ {data_path ()}
|
||||||
, temp_dir_ {temp_directory}
|
, temp_dir_ {temp_directory}
|
||||||
@ -1005,8 +1015,8 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network
|
|||||||
ui_->callsign_line_edit->setValidator (new CallsignValidator {this});
|
ui_->callsign_line_edit->setValidator (new CallsignValidator {this});
|
||||||
ui_->grid_line_edit->setValidator (new MaidenheadLocatorValidator {this});
|
ui_->grid_line_edit->setValidator (new MaidenheadLocatorValidator {this});
|
||||||
ui_->add_macro_line_edit->setValidator (new QRegularExpressionValidator {message_alphabet, this});
|
ui_->add_macro_line_edit->setValidator (new QRegularExpressionValidator {message_alphabet, this});
|
||||||
ui_->Field_Day_Exchange->setValidator(new QRegularExpressionValidator {field_day_exchange_re});
|
ui_->Field_Day_Exchange->setValidator (new QRegularExpressionValidator {field_day_exchange_re, this});
|
||||||
ui_->RTTY_Exchange->setValidator(new QRegularExpressionValidator {RTTY_roundup_exchange_re});
|
ui_->RTTY_Exchange->setValidator (new QRegularExpressionValidator {RTTY_roundup_exchange_re, this});
|
||||||
|
|
||||||
ui_->udp_server_port_spin_box->setMinimum (1);
|
ui_->udp_server_port_spin_box->setMinimum (1);
|
||||||
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
ui_->udp_server_port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||||
@ -1436,7 +1446,9 @@ void Configuration::impl::read_settings ()
|
|||||||
|
|
||||||
stations_.station_list (settings_->value ("stations").value<StationList::Stations> ());
|
stations_.station_list (settings_->value ("stations").value<StationList::Stations> ());
|
||||||
|
|
||||||
decode_highlighing_model_.items (settings_->value ("DecodeHighlighting", QVariant::fromValue (DecodeHighlightingModel::default_items ())).value<DecodeHighlightingModel::HighlightItems> ());
|
auto highlight_items = settings_->value ("DecodeHighlighting", QVariant::fromValue (DecodeHighlightingModel::default_items ())).value<DecodeHighlightingModel::HighlightItems> ();
|
||||||
|
if (!highlight_items.size ()) highlight_items = DecodeHighlightingModel::default_items ();
|
||||||
|
decode_highlighing_model_.items (highlight_items);
|
||||||
highlight_by_mode_ = settings_->value("HighlightByMode", false).toBool ();
|
highlight_by_mode_ = settings_->value("HighlightByMode", false).toBool ();
|
||||||
LotW_days_since_upload_ = settings_->value ("LotWDaysSinceLastUpload", 365).toInt ();
|
LotW_days_since_upload_ = settings_->value ("LotWDaysSinceLastUpload", 365).toInt ();
|
||||||
lotw_users_.set_age_constraint (LotW_days_since_upload_);
|
lotw_users_.set_age_constraint (LotW_days_since_upload_);
|
||||||
@ -2126,6 +2138,11 @@ void Configuration::impl::on_reset_highlighting_to_defaults_push_button_clicked
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::impl::on_rescan_log_push_button_clicked (bool /*clicked*/)
|
||||||
|
{
|
||||||
|
if (logbook_) logbook_->rescan ();
|
||||||
|
}
|
||||||
|
|
||||||
void Configuration::impl::on_LotW_CSV_fetch_push_button_clicked (bool /*checked*/)
|
void Configuration::impl::on_LotW_CSV_fetch_push_button_clicked (bool /*checked*/)
|
||||||
{
|
{
|
||||||
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text (), true);
|
lotw_users_.load (ui_->LotW_CSV_URL_line_edit->text (), true);
|
||||||
@ -2496,6 +2513,22 @@ void Configuration::impl::on_cbx4ToneSpacing_clicked(bool b)
|
|||||||
if(b) ui_->cbx2ToneSpacing->setChecked(false);
|
if(b) ui_->cbx2ToneSpacing->setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::impl::on_Field_Day_Exchange_textEdited (QString const& exchange)
|
||||||
|
{
|
||||||
|
auto text = exchange.simplified ().toUpper ();
|
||||||
|
auto class_pos = text.indexOf (QRegularExpression {R"([A-H])"});
|
||||||
|
if (class_pos >= 0 && text.size () >= class_pos + 2 && text.at (class_pos + 1) != QChar {' '})
|
||||||
|
{
|
||||||
|
text.insert (class_pos + 1, QChar {' '});
|
||||||
|
}
|
||||||
|
ui_->Field_Day_Exchange->setText (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Configuration::impl::on_RTTY_Exchange_textEdited (QString const& exchange)
|
||||||
|
{
|
||||||
|
ui_->RTTY_Exchange->setText (exchange.toUpper ());
|
||||||
|
}
|
||||||
|
|
||||||
bool Configuration::impl::have_rig ()
|
bool Configuration::impl::have_rig ()
|
||||||
{
|
{
|
||||||
if (!open_rig ())
|
if (!open_rig ())
|
||||||
|
@ -24,6 +24,7 @@ class QStringListModel;
|
|||||||
class QHostAddress;
|
class QHostAddress;
|
||||||
class LotWUsers;
|
class LotWUsers;
|
||||||
class DecodeHighlightingModel;
|
class DecodeHighlightingModel;
|
||||||
|
class LogBook;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Class Configuration
|
// Class Configuration
|
||||||
@ -72,7 +73,7 @@ public:
|
|||||||
Q_ENUM (Type2MsgGen)
|
Q_ENUM (Type2MsgGen)
|
||||||
|
|
||||||
explicit Configuration (QNetworkAccessManager *, QDir const& temp_directory, QSettings * settings,
|
explicit Configuration (QNetworkAccessManager *, QDir const& temp_directory, QSettings * settings,
|
||||||
QWidget * parent = nullptr);
|
LogBook * logbook, QWidget * parent = nullptr);
|
||||||
~Configuration ();
|
~Configuration ();
|
||||||
|
|
||||||
void select_tab (int);
|
void select_tab (int);
|
||||||
|
328
Configuration.ui
@ -16,9 +16,6 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="configuration_tabs">
|
<widget class="QTabWidget" name="configuration_tabs">
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select tab to change configuration parameters.</string>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -2197,7 +2194,7 @@ Right click for insert and delete options.</string>
|
|||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Enable or disable using the check boxes and right-click an item to change the foreground color, background color, or reset the item to default values. Drag and drop the items to change their priority, higher in the list is higher in priority.</p></body></html></string>
|
<string><html><head/><body><p>Enable or disable using the check boxes and right-click an item to change or unset the foreground color, background color, or reset the item to default values. Drag and drop the items to change their priority, higher in the list is higher in priority.</p><p>Note that each foreground or background color may be either set or unset, unset means that it is not allocated for that item's type and lower priority items may apply.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeAdjustPolicy">
|
<property name="sizeAdjustPolicy">
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
@ -2233,8 +2230,8 @@ Right click for insert and delete options.</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||||
<item row="0" column="0">
|
<item>
|
||||||
<widget class="QCheckBox" name="highlight_by_mode_check_box">
|
<widget class="QCheckBox" name="highlight_by_mode_check_box">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Check to indicate new DXCC entities, grid squares, and callsigns per mode.</p></body></html></string>
|
<string><html><head/><body><p>Check to indicate new DXCC entities, grid squares, and callsigns per mode.</p></body></html></string>
|
||||||
@ -2244,6 +2241,29 @@ Right click for insert and delete options.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="rescan_log_push_button">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Click to scan the wsjtx_log.adi ADIF file again for worked before information</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Rescan ADIF Log</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -2436,7 +2456,140 @@ Right click for insert and delete options.</string>
|
|||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_15" columnstretch="1,2,1,0,0">
|
<layout class="QGridLayout" name="gridLayout_15" columnstretch="1,0,0,0">
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QRadioButton" name="rbHound">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Hound</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbNA_VHF_Contest">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>NA VHF Contest</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbFox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fox</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QRadioButton" name="rbEU_VHF_Contest">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>EU VHF Contest</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="2,1,1">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="rbRTTY_Roundup">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>ARRL RTTY Roundup</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">special_op_activity_button_group</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_10">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout_17">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="labRTTY">
|
||||||
|
<property name="text">
|
||||||
|
<string>RTTY RU Exch:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>RTTY_Exchange</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="RTTY_Exchange">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>70</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>NJ</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item row="0" column="1" rowspan="3">
|
<item row="0" column="1" rowspan="3">
|
||||||
<spacer name="horizontalSpacer_11">
|
<spacer name="horizontalSpacer_11">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -2483,7 +2636,7 @@ Right click for insert and delete options.</string>
|
|||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="labFD">
|
<widget class="QLabel" name="labFD">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Exch:</string>
|
<string>FD Exch:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<property name="buddy">
|
||||||
<cstring>Field_Day_Exchange</cstring>
|
<cstring>Field_Day_Exchange</cstring>
|
||||||
@ -2513,152 +2666,6 @@ Right click for insert and delete options.</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="3">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="2,1,1">
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="rbRTTY_Roundup">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>ARRL RTTY Roundup</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_10">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QFormLayout" name="formLayout_17">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="labRTTY">
|
|
||||||
<property name="text">
|
|
||||||
<string>Exch:</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>RTTY_Exchange</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="RTTY_Exchange">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>70</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>NJ</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbFox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Fox</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbEU_VHF_Contest">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>EU VHF Contest</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbNA_VHF_Contest">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>NA VHF Contest</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="4" rowspan="3">
|
|
||||||
<spacer name="horizontalSpacer_12">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3">
|
|
||||||
<widget class="QRadioButton" name="rbHound">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Hound</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">special_op_activity_button_group</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -2924,7 +2931,6 @@ 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>LotW_CSV_URL_line_edit</tabstop>
|
<tabstop>LotW_CSV_URL_line_edit</tabstop>
|
||||||
<tabstop>LotW_CSV_fetch_push_button</tabstop>
|
<tabstop>LotW_CSV_fetch_push_button</tabstop>
|
||||||
<tabstop>LotW_days_since_upload_spin_box</tabstop>
|
<tabstop>LotW_days_since_upload_spin_box</tabstop>
|
||||||
@ -3012,13 +3018,13 @@ Right click for insert and delete options.</string>
|
|||||||
</connection>
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="CAT_stop_bits_button_group"/>
|
|
||||||
<buttongroup name="TX_audio_source_button_group"/>
|
|
||||||
<buttongroup name="TX_mode_button_group"/>
|
|
||||||
<buttongroup name="split_mode_button_group"/>
|
|
||||||
<buttongroup name="CAT_handshake_button_group"/>
|
<buttongroup name="CAT_handshake_button_group"/>
|
||||||
<buttongroup name="special_op_activity_button_group"/>
|
<buttongroup name="split_mode_button_group"/>
|
||||||
<buttongroup name="PTT_method_button_group"/>
|
|
||||||
<buttongroup name="CAT_data_bits_button_group"/>
|
<buttongroup name="CAT_data_bits_button_group"/>
|
||||||
|
<buttongroup name="PTT_method_button_group"/>
|
||||||
|
<buttongroup name="TX_mode_button_group"/>
|
||||||
|
<buttongroup name="CAT_stop_bits_button_group"/>
|
||||||
|
<buttongroup name="special_op_activity_button_group"/>
|
||||||
|
<buttongroup name="TX_audio_source_button_group"/>
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
Notes on WSJT-X Installation for Mac OS X
|
Notes on WSJT-X Installation for Mac OS X
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
Updated 16 July 2017
|
Updated 21 October 2018
|
||||||
--------------------
|
-----------------------
|
||||||
|
|
||||||
If you have already downloaded a previous version of WSJT-X then I suggest
|
If you have already downloaded a previous version of WSJT-X then I suggest
|
||||||
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
|
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
|
||||||
@ -68,6 +68,12 @@ under the WSJT-X Menu and fill in various station details on the General panel.
|
|||||||
I recommend checking the 4 boxes under the Display heading and the first 4 boxes under
|
I recommend checking the 4 boxes under the Display heading and the first 4 boxes under
|
||||||
the Behaviour heading.
|
the Behaviour heading.
|
||||||
|
|
||||||
|
IMPORTANT: If you are using macOS 10.14 (Mojave) it is important to note that the default setting
|
||||||
|
for audio input is "block". In order to receive audio from WSJT-X you must visit
|
||||||
|
System Preferences > Security & Privacy > Privacy and, with WSJT-X launched, select "Microphone"
|
||||||
|
under Location Services and wsjtx should appear in the panel. Check the "Allow" box. You will
|
||||||
|
have to quit WSJT-X for this change to take effect.
|
||||||
|
|
||||||
Next visit the Audio panel and select the Audio Codec you use to communicate between
|
Next visit the Audio panel and select the Audio Codec you use to communicate between
|
||||||
WSJT-X and your rig. There are so many audio interfaces available that it is not
|
WSJT-X and your rig. There are so many audio interfaces available that it is not
|
||||||
possible to give detailed advice on selection. If you have difficulties contact me.
|
possible to give detailed advice on selection. If you have difficulties contact me.
|
||||||
@ -86,7 +92,7 @@ be located in the device driver directory /dev. You should install your driver
|
|||||||
and then re-launch WSJT-X. Return to the the Radio panel in Preferences and in
|
and then re-launch WSJT-X. Return to the the Radio panel in Preferences and in
|
||||||
the "Serial port" panel select your driver from the list that is presented. If
|
the "Serial port" panel select your driver from the list that is presented. If
|
||||||
for some reason your driver is not shown, then insert the full name
|
for some reason your driver is not shown, then insert the full name
|
||||||
of your driver in the Serial Port panel. Such as: /dev/tty.PL2303-00002226 or
|
of your driver in the Serial Port panel. Such as: /dev/cu.PL2303-00002226 or
|
||||||
whatever driver you have. The /dev/ prefix is mandatory. Set the relevant
|
whatever driver you have. The /dev/ prefix is mandatory. Set the relevant
|
||||||
communication parameters as required by your transceiver and click "Test CAT" to
|
communication parameters as required by your transceiver and click "Test CAT" to
|
||||||
check.
|
check.
|
||||||
|
@ -405,7 +405,7 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con
|
|||||||
, qint32 rx_df, qint32 tx_df, QString const& de_call
|
, qint32 rx_df, qint32 tx_df, QString const& de_call
|
||||||
, QString const& de_grid, QString const& dx_grid
|
, QString const& de_grid, QString const& dx_grid
|
||||||
, bool watchdog_timeout, QString const& sub_mode
|
, bool watchdog_timeout, QString const& sub_mode
|
||||||
, bool fast_mode)
|
, bool fast_mode, quint8 special_op_mode)
|
||||||
{
|
{
|
||||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||||
{
|
{
|
||||||
@ -414,7 +414,7 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con
|
|||||||
out << f << mode.toUtf8 () << dx_call.toUtf8 () << report.toUtf8 () << tx_mode.toUtf8 ()
|
out << f << mode.toUtf8 () << dx_call.toUtf8 () << report.toUtf8 () << tx_mode.toUtf8 ()
|
||||||
<< tx_enabled << transmitting << decoding << rx_df << tx_df << de_call.toUtf8 ()
|
<< tx_enabled << transmitting << decoding << rx_df << tx_df << de_call.toUtf8 ()
|
||||||
<< de_grid.toUtf8 () << dx_grid.toUtf8 () << watchdog_timeout << sub_mode.toUtf8 ()
|
<< de_grid.toUtf8 () << dx_grid.toUtf8 () << watchdog_timeout << sub_mode.toUtf8 ()
|
||||||
<< fast_mode;
|
<< fast_mode << special_op_mode;
|
||||||
m_->send_message (out, message);
|
m_->send_message (out, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,7 +462,8 @@ void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QStr
|
|||||||
, QString const& report_received, QString const& tx_power
|
, QString const& report_received, QString const& tx_power
|
||||||
, QString const& comments, QString const& name, QDateTime time_on
|
, QString const& comments, QString const& name, QDateTime time_on
|
||||||
, QString const& operator_call, QString const& my_call
|
, QString const& operator_call, QString const& my_call
|
||||||
, QString const& my_grid)
|
, QString const& my_grid, QString const& exchange_sent
|
||||||
|
, QString const& exchange_rcvd)
|
||||||
{
|
{
|
||||||
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
if (m_->server_port_ && !m_->server_string_.isEmpty ())
|
||||||
{
|
{
|
||||||
@ -470,7 +471,8 @@ void MessageClient::qso_logged (QDateTime time_off, QString const& dx_call, QStr
|
|||||||
NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_};
|
NetworkMessage::Builder out {&message, NetworkMessage::QSOLogged, m_->id_, m_->schema_};
|
||||||
out << time_off << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
|
out << time_off << dx_call.toUtf8 () << dx_grid.toUtf8 () << dial_frequency << mode.toUtf8 ()
|
||||||
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 ()
|
<< report_sent.toUtf8 () << report_received.toUtf8 () << tx_power.toUtf8 () << comments.toUtf8 ()
|
||||||
<< name.toUtf8 () << time_on << operator_call.toUtf8 () << my_call.toUtf8 () << my_grid.toUtf8 ();
|
<< name.toUtf8 () << time_on << operator_call.toUtf8 () << my_call.toUtf8 () << my_grid.toUtf8 ()
|
||||||
|
<< exchange_sent.toUtf8 () << exchange_rcvd.toUtf8 ();
|
||||||
m_->send_message (out, message);
|
m_->send_message (out, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public:
|
|||||||
, QString const& tx_mode, bool tx_enabled, bool transmitting, bool decoding
|
, QString const& tx_mode, bool tx_enabled, bool transmitting, bool decoding
|
||||||
, qint32 rx_df, qint32 tx_df, QString const& de_call, QString const& de_grid
|
, qint32 rx_df, qint32 tx_df, QString const& de_call, QString const& de_grid
|
||||||
, QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode
|
, QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode
|
||||||
, bool fast_mode);
|
, bool fast_mode, quint8 special_op_mode);
|
||||||
Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
|
||||||
, QString const& mode, QString const& message, bool low_confidence
|
, QString const& mode, QString const& message, bool low_confidence
|
||||||
, bool off_air);
|
, bool off_air);
|
||||||
@ -64,7 +64,8 @@ public:
|
|||||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||||
, QString const& my_call, QString const& my_grid);
|
, QString const& my_call, QString const& my_grid
|
||||||
|
, QString const& exchange_sent, QString const& exchange_rcvd);
|
||||||
|
|
||||||
// ADIF_record argument should be valid ADIF excluding any <EOR> end
|
// ADIF_record argument should be valid ADIF excluding any <EOR> end
|
||||||
// of record marker
|
// of record marker
|
||||||
|
@ -216,9 +216,10 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
|||||||
bool watchdog_timeout {false};
|
bool watchdog_timeout {false};
|
||||||
QByteArray sub_mode;
|
QByteArray sub_mode;
|
||||||
bool fast_mode {false};
|
bool fast_mode {false};
|
||||||
|
quint8 special_op_mode {0};
|
||||||
in >> f >> mode >> dx_call >> report >> tx_mode >> tx_enabled >> transmitting >> decoding
|
in >> f >> mode >> dx_call >> report >> tx_mode >> tx_enabled >> transmitting >> decoding
|
||||||
>> rx_df >> tx_df >> de_call >> de_grid >> dx_grid >> watchdog_timeout >> sub_mode
|
>> rx_df >> tx_df >> de_call >> de_grid >> dx_grid >> watchdog_timeout >> sub_mode
|
||||||
>> fast_mode;
|
>> fast_mode >> special_op_mode;
|
||||||
if (check_status (in) != Fail)
|
if (check_status (in) != Fail)
|
||||||
{
|
{
|
||||||
Q_EMIT self_->status_update (id, f, QString::fromUtf8 (mode), QString::fromUtf8 (dx_call)
|
Q_EMIT self_->status_update (id, f, QString::fromUtf8 (mode), QString::fromUtf8 (dx_call)
|
||||||
@ -226,7 +227,8 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
|||||||
, tx_enabled, transmitting, decoding, rx_df, tx_df
|
, tx_enabled, transmitting, decoding, rx_df, tx_df
|
||||||
, QString::fromUtf8 (de_call), QString::fromUtf8 (de_grid)
|
, QString::fromUtf8 (de_call), QString::fromUtf8 (de_grid)
|
||||||
, QString::fromUtf8 (dx_grid), watchdog_timeout
|
, QString::fromUtf8 (dx_grid), watchdog_timeout
|
||||||
, QString::fromUtf8 (sub_mode), fast_mode);
|
, QString::fromUtf8 (sub_mode), fast_mode
|
||||||
|
, special_op_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -294,8 +296,11 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
|||||||
QByteArray operator_call;
|
QByteArray operator_call;
|
||||||
QByteArray my_call;
|
QByteArray my_call;
|
||||||
QByteArray my_grid;
|
QByteArray my_grid;
|
||||||
|
QByteArray exchange_sent;
|
||||||
|
QByteArray exchange_rcvd;
|
||||||
in >> time_off >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received
|
in >> time_off >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received
|
||||||
>> tx_power >> comments >> name >> time_on >> operator_call >> my_call >> my_grid;
|
>> tx_power >> comments >> name >> time_on >> operator_call >> my_call >> my_grid
|
||||||
|
>> exchange_sent >> exchange_rcvd;
|
||||||
if (check_status (in) != Fail)
|
if (check_status (in) != Fail)
|
||||||
{
|
{
|
||||||
Q_EMIT self_->qso_logged (id, time_off, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid)
|
Q_EMIT self_->qso_logged (id, time_off, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid)
|
||||||
@ -303,7 +308,8 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
|
|||||||
, QString::fromUtf8 (report_received), QString::fromUtf8 (tx_power)
|
, QString::fromUtf8 (report_received), QString::fromUtf8 (tx_power)
|
||||||
, QString::fromUtf8 (comments), QString::fromUtf8 (name), time_on
|
, QString::fromUtf8 (comments), QString::fromUtf8 (name), time_on
|
||||||
, QString::fromUtf8 (operator_call), QString::fromUtf8 (my_call)
|
, QString::fromUtf8 (operator_call), QString::fromUtf8 (my_call)
|
||||||
, QString::fromUtf8 (my_grid));
|
, QString::fromUtf8 (my_grid), QString::fromUtf8 (exchange_sent)
|
||||||
|
, QString::fromUtf8 (exchange_rcvd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -76,7 +76,8 @@ public:
|
|||||||
, QString const& report, QString const& tx_mode, bool tx_enabled
|
, QString const& report, QString const& tx_mode, bool tx_enabled
|
||||||
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
||||||
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
||||||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
|
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode
|
||||||
|
, quint8 special_op_mode);
|
||||||
Q_SIGNAL void client_closed (QString const& id);
|
Q_SIGNAL void client_closed (QString const& id);
|
||||||
Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time
|
Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time
|
||||||
, quint32 delta_frequency, QString const& mode, QString const& message
|
, quint32 delta_frequency, QString const& mode, QString const& message
|
||||||
@ -88,7 +89,8 @@ public:
|
|||||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||||
, QString const& my_call, QString const& my_grid);
|
, QString const& my_call, QString const& my_grid
|
||||||
|
, QString const& exchange_sent, QString const& exchange_rcvd);
|
||||||
Q_SIGNAL void clear_decodes (QString const& id);
|
Q_SIGNAL void clear_decodes (QString const& id);
|
||||||
Q_SIGNAL void logged_ADIF (QString const& id, QByteArray const& ADIF);
|
Q_SIGNAL void logged_ADIF (QString const& id, QByteArray const& ADIF);
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@
|
|||||||
* Tx Watchdog bool
|
* Tx Watchdog bool
|
||||||
* Sub-mode utf8
|
* Sub-mode utf8
|
||||||
* Fast mode bool
|
* Fast mode bool
|
||||||
|
* Special operation mode quint8
|
||||||
*
|
*
|
||||||
* WSJT-X sends this status message when various internal state
|
* WSJT-X sends this status message when various internal state
|
||||||
* changes to allow the server to track the relevant state of each
|
* changes to allow the server to track the relevant state of each
|
||||||
@ -142,10 +143,22 @@
|
|||||||
* At the start and end of decoding,
|
* At the start and end of decoding,
|
||||||
* When the Rx DF changes,
|
* When the Rx DF changes,
|
||||||
* When the Tx DF changes,
|
* When the Tx DF changes,
|
||||||
* When the DE call or grid changes (currently when settings are exited),
|
* When settings are exited,
|
||||||
* When the DX call or grid changes,
|
* When the DX call or grid changes,
|
||||||
* When the Tx watchdog is set or reset.
|
* When the Tx watchdog is set or reset.
|
||||||
*
|
*
|
||||||
|
* The Special operation mode is an enumeration that indicates the
|
||||||
|
* setting selected in the WSJT-X "Settings->Advanced->Special
|
||||||
|
* operating activity" panel. The values are as follows:
|
||||||
|
*
|
||||||
|
* 0 -> NONE
|
||||||
|
* 1 -> NA VHF
|
||||||
|
* 2 -> EU VHF
|
||||||
|
* 3 -> FIELD DAY
|
||||||
|
* 4 -> RTTY RU
|
||||||
|
* 5 -> FOX
|
||||||
|
* 6 -> HOUND
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* Decode Out 2 quint32
|
* Decode Out 2 quint32
|
||||||
* Id (unique key) utf8
|
* Id (unique key) utf8
|
||||||
@ -240,6 +253,8 @@
|
|||||||
* Operator call utf8
|
* Operator call utf8
|
||||||
* My call utf8
|
* My call utf8
|
||||||
* My grid utf8
|
* My grid utf8
|
||||||
|
* Exchange sent utf8
|
||||||
|
* Exchange received utf8
|
||||||
*
|
*
|
||||||
* The QSO logged message is sent to the server(s) when the
|
* The QSO logged message is sent to the server(s) when the
|
||||||
* WSJT-X user accepts the "Log QSO" dialog by clicking the "OK"
|
* WSJT-X user accepts the "Log QSO" dialog by clicking the "OK"
|
||||||
|
@ -136,12 +136,12 @@ namespace Radio
|
|||||||
// the full call if no valid prefix (or prefix as a suffix) is specified
|
// the full call if no valid prefix (or prefix as a suffix) is specified
|
||||||
QString effective_prefix (QString callsign)
|
QString effective_prefix (QString callsign)
|
||||||
{
|
{
|
||||||
auto prefix = callsign.toUpper ();
|
auto prefix = callsign;
|
||||||
auto slash_pos = callsign.indexOf ('/');
|
auto slash_pos = callsign.indexOf ('/');
|
||||||
if (slash_pos >= 0)
|
if (slash_pos >= 0)
|
||||||
{
|
{
|
||||||
auto right_size = callsign.size () - slash_pos - 1;
|
auto right_size = callsign.size () - slash_pos - 1;
|
||||||
if (right_size >= slash_pos) // naive call is longer than
|
if (right_size >= slash_pos) // native call is longer than
|
||||||
// prefix/suffix algorithm
|
// prefix/suffix algorithm
|
||||||
{
|
{
|
||||||
prefix = callsign.left (slash_pos);
|
prefix = callsign.left (slash_pos);
|
||||||
@ -157,6 +157,6 @@ namespace Radio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return prefix;
|
return prefix.toUpper ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,64 @@
|
|||||||
|
|
||||||
Copyright 2001 - 2018 by Joe Taylor, K1JT.
|
Copyright 2001 - 2018 by Joe Taylor, K1JT.
|
||||||
|
|
||||||
|
Release: WSJT-X 2.0
|
||||||
|
December 10, 2018
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
WSJT-X 2.0 is a major update that introduces new protocols for FT8 and
|
||||||
|
MSK144. The new protocols become the world-wide standards on December
|
||||||
|
10, 2018.
|
||||||
|
|
||||||
|
WSJT-X 2.0 cannot communicate in these modes with other stations using
|
||||||
|
WSJT-X v1.9.1 or earlier.
|
||||||
|
|
||||||
|
Please help by urging everyone to upgrade no later than January 1, 2019.
|
||||||
|
|
||||||
|
New features since WSJT-X v1.9.1:
|
||||||
|
|
||||||
|
1. Compound and nonstandard callsigns are automatically recognized and
|
||||||
|
handled using new message formats.
|
||||||
|
|
||||||
|
2. The new FT8 protocol provides optimized message formats for North
|
||||||
|
American VHF contests, European VHF contests, ARRL Field Day, and ARRL
|
||||||
|
RTTY Roundup. Similarly, the new MSK144 protocol provides optimized
|
||||||
|
message formats for North American VHF and European VHF contests.
|
||||||
|
Full support is provided for "/R" and "/P" calls in the relevant
|
||||||
|
contests.
|
||||||
|
|
||||||
|
3. The new protocols provide nearly equal (or better) sensitivity
|
||||||
|
compared to the old ones, and lower false decode rates.
|
||||||
|
|
||||||
|
4. New logging features are provided for contesting and for "Fox"
|
||||||
|
(DXpedition) mode. Logging is optionally integrated with N1MM Logger+
|
||||||
|
and WriteLog.
|
||||||
|
|
||||||
|
5. Color highlighting of decoded messages provides worked-before
|
||||||
|
status for callsigns, grid locators, DXCC entities, continents, CQ
|
||||||
|
Zones, and ITU zones on a “by band” and “by mode” basis, and for
|
||||||
|
stations that have uploaded their logs to Logbook of the World (LoTW)
|
||||||
|
within a specified time interval.
|
||||||
|
|
||||||
|
6. The WSPR decoder now achieves decodes down to S/N = -31 dB. For
|
||||||
|
the particular benefit of LF/MF users, an option "No own call decodes"
|
||||||
|
has been added.
|
||||||
|
|
||||||
|
7. The UDP messages sent to companion programs have been expanded and
|
||||||
|
improved.
|
||||||
|
|
||||||
|
Some details of changes since WSJT-X-rc5 include the following:
|
||||||
|
|
||||||
|
- Initial load of ADIF log in background
|
||||||
|
- Correct the UTC displayed in Fox/Contest log
|
||||||
|
- Faster entry and correct scrolling for Fox/Contest log
|
||||||
|
- Add contest exchanges and contest type to UDP logged QSO message
|
||||||
|
- Fix a bug that suppressed decodes with negative DT.
|
||||||
|
- AK and HI are DXCCs, not states, for RTTY Roundup
|
||||||
|
- Fix improper truncation of some non-FT8 messages in ALL.TXT
|
||||||
|
- Various minor bug fixes and code cleanup
|
||||||
|
- Update the WSJT-X User Guide to v2.0 (more to come...)
|
||||||
|
- Update cty.dat
|
||||||
|
|
||||||
Release: WSJT-X 2.0-rc5
|
Release: WSJT-X 2.0-rc5
|
||||||
November 26, 2018
|
November 26, 2018
|
||||||
-----------------------
|
-----------------------
|
||||||
@ -36,6 +94,14 @@ Changes from WSJT-X 2.0-rc4 include the following:
|
|||||||
- Fix a bug causing false AP decodes in JT65 VHF+ operation
|
- Fix a bug causing false AP decodes in JT65 VHF+ operation
|
||||||
- Fix a bug that could switch unexpectedly from JT65 to JT9 mode
|
- Fix a bug that could switch unexpectedly from JT65 to JT9 mode
|
||||||
|
|
||||||
|
PLEASE NOTE: As far as WSJT-X 2.0 (RC4, RC5, and GA releases) are
|
||||||
|
concerned, signals using the old FT8 protocol are undecodable
|
||||||
|
interference. This means that regenerated replicas cannot be
|
||||||
|
subtracted from received data, and consequently second- and third-pass
|
||||||
|
decodes may be impeded. Full performance of the 77-bit decoder will
|
||||||
|
not be realized until most signals on a crowded band are using the
|
||||||
|
new FT8 protocol.
|
||||||
|
|
||||||
|
|
||||||
Release: WSJT-X 2.0-rc4
|
Release: WSJT-X 2.0-rc4
|
||||||
November 12, 2018
|
November 12, 2018
|
||||||
|
@ -72,7 +72,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
BeaconsModel::BeaconsModel (QObject * parent)
|
BeaconsModel::BeaconsModel (QObject * parent)
|
||||||
: QStandardItemModel {0, sizeof (headings) / sizeof (headings[0]), parent}
|
: QStandardItemModel {0, sizeof headings / sizeof headings[0], parent}
|
||||||
{
|
{
|
||||||
int column {0};
|
int column {0};
|
||||||
for (auto const& heading : headings)
|
for (auto const& heading : headings)
|
||||||
|
@ -244,15 +244,29 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
|
|||||||
, QString const& report, QString const& tx_mode, bool tx_enabled
|
, QString const& report, QString const& tx_mode, bool tx_enabled
|
||||||
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
||||||
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
||||||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode)
|
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode
|
||||||
|
, quint8 special_op_mode)
|
||||||
{
|
{
|
||||||
if (id == id_)
|
if (id == id_)
|
||||||
{
|
{
|
||||||
fast_mode_ = fast_mode;
|
fast_mode_ = fast_mode;
|
||||||
decodes_proxy_model_.de_call (de_call);
|
decodes_proxy_model_.de_call (de_call);
|
||||||
decodes_proxy_model_.rx_df (rx_df);
|
decodes_proxy_model_.rx_df (rx_df);
|
||||||
de_label_->setText (de_call.size () >= 0 ? QString {"DE: %1%2"}.arg (de_call)
|
QString special;
|
||||||
.arg (de_grid.size () ? '(' + de_grid + ')' : QString {}) : QString {});
|
switch (special_op_mode)
|
||||||
|
{
|
||||||
|
case 1: special = "[NA VHF]"; break;
|
||||||
|
case 2: special = "[EU VHF]"; break;
|
||||||
|
case 3: special = "[FD]"; break;
|
||||||
|
case 4: special = "[RTTY RU]"; break;
|
||||||
|
case 5: special = "[Fox]"; break;
|
||||||
|
case 6: special = "[Hound]"; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
de_label_->setText (de_call.size () >= 0 ? QString {"DE: %1%2%3"}.arg (de_call)
|
||||||
|
.arg (de_grid.size () ? '(' + de_grid + ')' : QString {})
|
||||||
|
.arg (special)
|
||||||
|
: QString {});
|
||||||
mode_label_->setText (QString {"Mode: %1%2%3%4"}
|
mode_label_->setText (QString {"Mode: %1%2%3%4"}
|
||||||
.arg (mode)
|
.arg (mode)
|
||||||
.arg (sub_mode)
|
.arg (sub_mode)
|
||||||
|
@ -32,7 +32,8 @@ public:
|
|||||||
, QString const& report, QString const& tx_mode, bool tx_enabled
|
, QString const& report, QString const& tx_mode, bool tx_enabled
|
||||||
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
, bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df
|
||||||
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
, QString const& de_call, QString const& de_grid, QString const& dx_grid
|
||||||
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
|
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode
|
||||||
|
, quint8 special_op_mode);
|
||||||
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr
|
||||||
, float delta_time, quint32 delta_frequency, QString const& mode
|
, float delta_time, quint32 delta_frequency, QString const& mode
|
||||||
, QString const& message, bool low_confidence, bool off_air);
|
, QString const& message, bool low_confidence, bool off_air);
|
||||||
|
@ -75,7 +75,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecodesModel::DecodesModel (QObject * parent)
|
DecodesModel::DecodesModel (QObject * parent)
|
||||||
: QStandardItemModel {0, sizeof (headings) / sizeof (headings[0]), parent}
|
: QStandardItemModel {0, sizeof headings / sizeof headings[0], parent}
|
||||||
{
|
{
|
||||||
int column {0};
|
int column {0};
|
||||||
for (auto const& heading : headings)
|
for (auto const& heading : headings)
|
||||||
|
@ -25,12 +25,14 @@ namespace
|
|||||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Operator"),
|
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Operator"),
|
||||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Call"),
|
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Call"),
|
||||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Grid"),
|
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "My Grid"),
|
||||||
|
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Exchange Sent"),
|
||||||
|
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Exchange Rcvd"),
|
||||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Comments"),
|
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Comments"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
||||||
: log_ {new QStandardItemModel {0, 14, this}}
|
: log_ {new QStandardItemModel {0, sizeof headings / sizeof headings[0], this}}
|
||||||
, decodes_model_ {new DecodesModel {this}}
|
, decodes_model_ {new DecodesModel {this}}
|
||||||
, beacons_model_ {new BeaconsModel {this}}
|
, beacons_model_ {new BeaconsModel {this}}
|
||||||
, server_ {new MessageServer {this}}
|
, server_ {new MessageServer {this}}
|
||||||
@ -209,7 +211,8 @@ void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time
|
|||||||
, QString const& report_sent, QString const& report_received
|
, QString const& report_sent, QString const& report_received
|
||||||
, QString const& tx_power, QString const& comments
|
, QString const& tx_power, QString const& comments
|
||||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||||
, QString const& my_call, QString const& my_grid)
|
, QString const& my_call, QString const& my_grid
|
||||||
|
, QString const& exchange_sent, QString const& exchange_rcvd)
|
||||||
{
|
{
|
||||||
QList<QStandardItem *> row;
|
QList<QStandardItem *> row;
|
||||||
row << new QStandardItem {time_on.toString ("dd-MMM-yyyy hh:mm:ss")}
|
row << new QStandardItem {time_on.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||||
@ -225,6 +228,8 @@ void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime time
|
|||||||
<< new QStandardItem {operator_call}
|
<< new QStandardItem {operator_call}
|
||||||
<< new QStandardItem {my_call}
|
<< new QStandardItem {my_call}
|
||||||
<< new QStandardItem {my_grid}
|
<< new QStandardItem {my_grid}
|
||||||
|
<< new QStandardItem {exchange_sent}
|
||||||
|
<< new QStandardItem {exchange_rcvd}
|
||||||
<< new QStandardItem {comments};
|
<< new QStandardItem {comments};
|
||||||
log_->appendRow (row);
|
log_->appendRow (row);
|
||||||
log_table_view_->resizeColumnsToContents ();
|
log_table_view_->resizeColumnsToContents ();
|
||||||
|
@ -32,7 +32,8 @@ public:
|
|||||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||||
, QString const& name, QDateTime time_on, QString const& operator_call
|
, QString const& name, QDateTime time_on, QString const& operator_call
|
||||||
, QString const& my_call, QString const& my_grid);
|
, QString const& my_call, QString const& my_grid
|
||||||
|
, QString const& exchange_sent, QString const& exchange_rcvd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add_client (QString const& id, QString const& version, QString const& revision);
|
void add_client (QString const& id, QString const& version, QString const& revision);
|
||||||
|
@ -50,7 +50,8 @@ public:
|
|||||||
, QString const& /*report*/, QString const& /*tx_mode*/, bool /*tx_enabled*/
|
, QString const& /*report*/, QString const& /*tx_mode*/, bool /*tx_enabled*/
|
||||||
, bool /*transmitting*/, bool /*decoding*/, qint32 /*rx_df*/, qint32 /*tx_df*/
|
, bool /*transmitting*/, bool /*decoding*/, qint32 /*rx_df*/, qint32 /*tx_df*/
|
||||||
, QString const& /*de_call*/, QString const& /*de_grid*/, QString const& /*dx_grid*/
|
, QString const& /*de_call*/, QString const& /*de_grid*/, QString const& /*dx_grid*/
|
||||||
, bool /* watchdog_timeout */, QString const& sub_mode, bool /*fast_mode*/)
|
, bool /* watchdog_timeout */, QString const& sub_mode, bool /*fast_mode*/
|
||||||
|
, quint8 /*special_op_mode*/)
|
||||||
{
|
{
|
||||||
if (id == id_)
|
if (id == id_)
|
||||||
{
|
{
|
||||||
@ -99,7 +100,8 @@ public:
|
|||||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||||
, QString const& report_received, QString const& tx_power
|
, QString const& report_received, QString const& tx_power
|
||||||
, QString const& comments, QString const& name, QDateTime time_on
|
, QString const& comments, QString const& name, QDateTime time_on
|
||||||
, QString const& operator_call, QString const& my_call, QString const& my_grid)
|
, QString const& operator_call, QString const& my_call, QString const& my_grid
|
||||||
|
, QString const& exchange_sent, QString const& exchange_rcvd)
|
||||||
{
|
{
|
||||||
if (client_id == id_)
|
if (client_id == id_)
|
||||||
{
|
{
|
||||||
@ -107,7 +109,8 @@ public:
|
|||||||
<< "freq:" << dial_frequency << "mode:" << mode << "rpt_sent:" << report_sent
|
<< "freq:" << dial_frequency << "mode:" << mode << "rpt_sent:" << report_sent
|
||||||
<< "rpt_rcvd:" << report_received << "Tx_pwr:" << tx_power << "comments:" << comments
|
<< "rpt_rcvd:" << report_received << "Tx_pwr:" << tx_power << "comments:" << comments
|
||||||
<< "name:" << name << "operator_call:" << operator_call << "my_call:" << my_call
|
<< "name:" << name << "operator_call:" << operator_call << "my_call:" << my_call
|
||||||
<< "my_grid:" << my_grid;
|
<< "my_grid:" << my_grid << "exchange_sent:" << exchange_sent
|
||||||
|
<< "exchange_rcvd:" << exchange_rcvd;
|
||||||
std::cout << QByteArray {80, '-'}.data () << '\n';
|
std::cout << QByteArray {80, '-'}.data () << '\n';
|
||||||
std::cout << tr ("%1: Logged %2 grid: %3 power: %4 sent: %5 recd: %6 freq: %7 time_off: %8 op: %9 my_call: %10 my_grid: %11")
|
std::cout << tr ("%1: Logged %2 grid: %3 power: %4 sent: %5 recd: %6 freq: %7 time_off: %8 op: %9 my_call: %10 my_grid: %11")
|
||||||
.arg (id_).arg (dx_call).arg (dx_grid).arg (tx_power).arg (report_sent).arg (report_received)
|
.arg (id_).arg (dx_call).arg (dx_grid).arg (tx_power).arg (report_sent).arg (report_received)
|
||||||
|
@ -12,14 +12,14 @@ Example:
|
|||||||
[displayed text] PSK Reporter
|
[displayed text] PSK Reporter
|
||||||
|
|
||||||
Perform searches from the doc root directory: doc
|
Perform searches from the doc root directory: doc
|
||||||
Search: grep -rl --exclude-dir="*\.svn" {pskreporter} .
|
Search: grep -rl --exclude-dir="*\.git" {pskreporter} .
|
||||||
grep -rl --exclude-dir="*\.svn" PSK Reporter .
|
grep -rl --exclude-dir="*\.git" PSK Reporter .
|
||||||
grep -rl --exclude-dir="*\.svn" {devsvn} .
|
grep -rl --exclude-dir="*\.git" {devrepo} .
|
||||||
grep -rl --exclude-dir="*\.svn" {kvasd} .
|
grep -rl --exclude-dir="*\.git" {kvasd} .
|
||||||
grep -rl --exclude-dir="*\.svn" {ntpsetup} .
|
grep -rl --exclude-dir="*\.git" {ntpsetup} .
|
||||||
|
|
||||||
Include links.adoc: grep -rl --exclude-dir="*\.svn" pskreporter .
|
Include links.adoc: grep -rl --exclude-dir="*\.git" pskreporter .
|
||||||
Exclude links.adoc: grep -rl --exclude-dir="*\.svn" {pskreporter} .
|
Exclude links.adoc: grep -rl --exclude-dir="*\.git" {pskreporter} .
|
||||||
|
|
||||||
Note(s):
|
Note(s):
|
||||||
a). Don't forget a space then "." at the end.
|
a). Don't forget a space then "." at the end.
|
||||||
@ -54,8 +54,8 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||||||
:raspbian: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_armhf.deb[wsjtx_{VERSION}_armhf.deb]
|
:raspbian: http://physics.princeton.edu/pulsar/K1JT/wsjtx_{VERSION}_armhf.deb[wsjtx_{VERSION}_armhf.deb]
|
||||||
:debian: http://www.debian.org/[Debian]
|
:debian: http://www.debian.org/[Debian]
|
||||||
:dev_guide: http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/wsjt-dev-guide.html[Dev-Guide]
|
:dev_guide: http://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/wsjt-dev-guide.html[Dev-Guide]
|
||||||
:devsvn1: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[Devel-SVN]
|
:devsvn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[Devel-SVN]
|
||||||
:devsvn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[SourceForge]
|
:devrepo: https://sourceforge.net/p/wsjt/wsjtx/ci/master/tree/[SourceForge]
|
||||||
:dimension4: http://www.thinkman.com/dimension4/[Thinking Man Software]
|
:dimension4: http://www.thinkman.com/dimension4/[Thinking Man Software]
|
||||||
:download: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[Download Page]
|
:download: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[Download Page]
|
||||||
:dxatlas: http://www.dxatlas.com/[Afreet Software, Inc.]
|
:dxatlas: http://www.dxatlas.com/[Afreet Software, Inc.]
|
||||||
@ -67,7 +67,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||||||
:fmt_group: https://groups.yahoo.com/neo/groups/FMT-nuts/info[FMT Group]
|
:fmt_group: https://groups.yahoo.com/neo/groups/FMT-nuts/info[FMT Group]
|
||||||
:fmt_k5cm: http://www.k5cm.com/[FMT Event Info]
|
:fmt_k5cm: http://www.k5cm.com/[FMT Event Info]
|
||||||
:fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup]
|
:fmt_wspr: http://www.physics.princeton.edu/pulsar/K1JT/FMT_User.pdf[Accurate Frequency Measurements with your WSPR Setup]
|
||||||
:ft8_tips: http://www.physics.princeton.edu/pulsar/K1JT/FT8_Operating_Tips.pdf[here]
|
:ft8_tips: http://www.g4ifb.com/FT8_Hinson_tips_for_HF_DXers.pdf[FT8 Operating Guide]
|
||||||
:ft8_DXped: http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf[FT8 DXpedition Mode]
|
:ft8_DXped: http://physics.princeton.edu/pulsar/k1jt/FT8_DXpedition_Mode.pdf[FT8 DXpedition Mode]
|
||||||
:gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License]
|
:gnu_gpl: http://www.gnu.org/licenses/gpl-3.0.txt[GNU General Public License]
|
||||||
:homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page]
|
:homepage: http://physics.princeton.edu/pulsar/K1JT/[WSJT Home Page]
|
||||||
@ -79,7 +79,9 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||||||
:log4om: http://www.log4om.com[Log4OM]
|
:log4om: http://www.log4om.com[Log4OM]
|
||||||
:lunarEchoes: http://physics.princeton.edu/pulsar/K1JT/LunarEchoes_QEX.pdf[QEX]
|
:lunarEchoes: http://physics.princeton.edu/pulsar/K1JT/LunarEchoes_QEX.pdf[QEX]
|
||||||
:msk144: http://physics.princeton.edu/pulsar/k1jt/MSK144_Protocol_QEX.pdf[QEX]
|
:msk144: http://physics.princeton.edu/pulsar/k1jt/MSK144_Protocol_QEX.pdf[QEX]
|
||||||
|
:msvcpp_redist: https://www.microsoft.com/en-ph/download/details.aspx?id=40784[Microsoft VC++ 2013 Redistributable]
|
||||||
:msys_url: http://sourceforge.net/projects/mingwbuilds/files/external-binary-packages/[MSYS Download]
|
:msys_url: http://sourceforge.net/projects/mingwbuilds/files/external-binary-packages/[MSYS Download]
|
||||||
|
:n1mm_logger: https://n1mm.hamdocs.com/tiki-index.php[N1MM Logger+]
|
||||||
:ntpsetup: http://www.satsignal.eu/ntp/setup.html[Network Time Protocol Setup]
|
:ntpsetup: http://www.satsignal.eu/ntp/setup.html[Network Time Protocol Setup]
|
||||||
:osx_instructions: http://physics.princeton.edu/pulsar/K1JT/OSX_Readme[Mac OS X Install Instructions]
|
:osx_instructions: http://physics.princeton.edu/pulsar/K1JT/OSX_Readme[Mac OS X Install Instructions]
|
||||||
:ppa: http://en.wikipedia.org/wiki/Personal_Package_Archive[PPA]
|
:ppa: http://en.wikipedia.org/wiki/Personal_Package_Archive[PPA]
|
||||||
@ -88,6 +90,9 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||||||
:sourceforge: https://sourceforge.net/user/registration[SourceForge]
|
:sourceforge: https://sourceforge.net/user/registration[SourceForge]
|
||||||
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
|
:sourceforge-jtsdk: https://sourceforge.net/projects/jtsdk[SourceForge JTSDK]
|
||||||
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
|
:ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice]
|
||||||
|
:win_openssl_packages: https://slproweb.com/products/Win32OpenSSL.html[Windows OpenSSL Packages]
|
||||||
|
:win32_openssl: https://slproweb.com/download/Win32OpenSSL_Light-1_0_2q.exe[Win32 OpenSSL Lite Package]
|
||||||
|
:writelog: https://writelog.com/[Writelog]
|
||||||
:wsjt_yahoo_group: https://groups.yahoo.com/neo/groups/wsjtgroup/info[WSJT Group]
|
:wsjt_yahoo_group: https://groups.yahoo.com/neo/groups/wsjtgroup/info[WSJT Group]
|
||||||
:wsjtx: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X]
|
:wsjtx: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X]
|
||||||
:wspr0_guide: http://www.physics.princeton.edu/pulsar/K1JT/WSPR0_Instructions.TXT[WSPR0 Guide]
|
:wspr0_guide: http://www.physics.princeton.edu/pulsar/K1JT/WSPR0_Instructions.TXT[WSPR0 Guide]
|
||||||
@ -111,9 +116,9 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes.
|
|||||||
:svn: http://subversion.apache.org/packages.html#windows[Subversion]
|
:svn: http://subversion.apache.org/packages.html#windows[Subversion]
|
||||||
:win32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-win32.exe[wsjtx-{VERSION}-win32.exe]
|
:win32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-win32.exe[wsjtx-{VERSION}-win32.exe]
|
||||||
:wsjt-devel: https://lists.sourceforge.net/lists/listinfo/wsjt-devel[here]
|
:wsjt-devel: https://lists.sourceforge.net/lists/listinfo/wsjt-devel[here]
|
||||||
:wsjt_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/[WSJT Source Repository]
|
:wsjt_repo: https://sourceforge.net/p/wsjt/wsjt_orig/ci/master/tree/[WSJT Source Repository]
|
||||||
:wspr_code: http://physics.princeton.edu/pulsar/K1JT/WSPRcode.exe[WSPRcode.exe]
|
:wspr_code: http://physics.princeton.edu/pulsar/K1JT/WSPRcode.exe[WSPRcode.exe]
|
||||||
:wspr_svn: http://sourceforge.net/p/wsjt/wsjt/HEAD/tree/branches/wspr/[WSPR Source Repository]
|
:wspr_svn: https://sourceforge.net/p/wsjt/wspr/ci/master/tree/[WSPR Source Repository]
|
||||||
|
|
||||||
// MAIL-TO links
|
// MAIL-TO links
|
||||||
:alex_efros: mailto:powerman@powerman.name[Alex Efros]
|
:alex_efros: mailto:powerman@powerman.name[Alex Efros]
|
||||||
|
@ -36,6 +36,8 @@ inserted automatically. Typical reports for the various modes fall in
|
|||||||
the range –30 to +20 dB. Remember that JT65 reports saturate at an
|
the range –30 to +20 dB. Remember that JT65 reports saturate at an
|
||||||
upper limit of -1 dB.
|
upper limit of -1 dB.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
TIP: Consider reducing power if your QSO partner reports your
|
TIP: Consider reducing power if your QSO partner reports your
|
||||||
signal above -5 dB in one of the _WSJT-X_ slow modes. These are
|
signal above -5 dB in one of the _WSJT-X_ slow modes. These are
|
||||||
supposed to be weak signal modes!
|
supposed to be weak signal modes!
|
||||||
|
@ -28,6 +28,8 @@ if the rig is detected to be in *Split* mode. The circle becomes red
|
|||||||
if you have requested CAT control but communication with the radio has
|
if you have requested CAT control but communication with the radio has
|
||||||
been lost.
|
been lost.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
TIP: Many Icom rigs cannot be queried for split status, current VFO or
|
TIP: Many Icom rigs cannot be queried for split status, current VFO or
|
||||||
split transmit frequency. When using _WSJT-X_ with such radios you
|
split transmit frequency. When using _WSJT-X_ with such radios you
|
||||||
should not change the current VFO, split status or dial frequency
|
should not change the current VFO, split status or dial frequency
|
||||||
|
@ -36,6 +36,8 @@ the original frequency.
|
|||||||
* *Erase* clears the right-hand decoded text window.
|
* *Erase* clears the right-hand decoded text window.
|
||||||
Double-clicking *Erase* clears both text windows.
|
Double-clicking *Erase* clears both text windows.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
TIP: Right-clicking on either text window brings up a context menu
|
TIP: Right-clicking on either text window brings up a context menu
|
||||||
with several options (including *Erase*) which operate on that window
|
with several options (including *Erase*) which operate on that window
|
||||||
alone.
|
alone.
|
||||||
|
@ -56,6 +56,8 @@ spaces) in the *Free Msg* box.
|
|||||||
pre-stored macro. Pressing *Enter* on a modified message here
|
pre-stored macro. Pressing *Enter* on a modified message here
|
||||||
automatically adds that message to the table of stored macros.
|
automatically adds that message to the table of stored macros.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
TIP: During a transmission the actual message being sent always
|
TIP: During a transmission the actual message being sent always
|
||||||
appears in the first box of the status bar (bottom left of the main
|
appears in the first box of the status bar (bottom left of the main
|
||||||
screen).
|
screen).
|
||||||
|
@ -21,3 +21,5 @@ the elapsed fraction of a Tx or Rx sequence. Finally, if the Watchdog
|
|||||||
lower right-hand corner displays the number of minutes remaining
|
lower right-hand corner displays the number of minutes remaining
|
||||||
before timeout.
|
before timeout.
|
||||||
|
|
||||||
|
TIP: Temporary status messages may occasionally be displayed here for
|
||||||
|
a few seconds when background processing completes.
|
@ -37,3 +37,11 @@ current band, as well as other options.
|
|||||||
logging applications Aether, MacLoggerDX, RUMlog or RUMlogNG. It
|
logging applications Aether, MacLoggerDX, RUMlog or RUMlogNG. It
|
||||||
checks QSO and QSL status of the call and DXCC entity, as well as many
|
checks QSO and QSL status of the call and DXCC entity, as well as many
|
||||||
other features.
|
other features.
|
||||||
|
|
||||||
|
* {n1mm_logger} is a free full feature contest logging application. It
|
||||||
|
is only available for Windows. _WSJT-X_ can send logged QSO
|
||||||
|
information to it via a network connection.
|
||||||
|
|
||||||
|
* {writelog} is a non-free full feature contest logging
|
||||||
|
application. It is only available for Windows. _WSJT-X_ can send
|
||||||
|
logged QSO information to it via a network connection.
|
@ -8,9 +8,9 @@ false decodes.
|
|||||||
|
|
||||||
For example: when you decide to answer a CQ, you already know your own
|
For example: when you decide to answer a CQ, you already know your own
|
||||||
callsign and that of your potential QSO partner. The software
|
callsign and that of your potential QSO partner. The software
|
||||||
therefore "`knows`" what to expect for 57 of the 72 message bits (28
|
therefore "`knows`" what might be expected for at least 57 message
|
||||||
bits for each of two callsigns, 1 bit for message type) in the next
|
bits (28 for each of two callsigns, 1 or more for message type) in the
|
||||||
received message. The decoder's task can thus be reduced to
|
next received message. The decoder's task can thus be reduced to
|
||||||
determining the remaining 15 bits of the message and ensuring that the
|
determining the remaining 15 bits of the message and ensuring that the
|
||||||
resulting solution is reliable.
|
resulting solution is reliable.
|
||||||
|
|
||||||
|
@ -47,7 +47,27 @@ location for each instance of _WSJT-X_.
|
|||||||
wsjtx --rig-name=TS2000
|
wsjtx --rig-name=TS2000
|
||||||
wsjtx --rig-name=FT847
|
wsjtx --rig-name=FT847
|
||||||
|
|
||||||
Rig control through _OmniRig_ seems to fail when I click *Test CAT*. What can I do about it?::
|
I am getting a "Network Error - SSL/TLS support not installed" message. What should I do?::
|
||||||
|
|
||||||
|
You need to install suitable _OpenSSL_ libraries - see <<OPENSSL,Instructions to install _OpenSSL_>>.
|
||||||
|
|
||||||
|
I occasionally get Rig Control Errors if I adjust my Icom rig's VFO. What's wrong?::
|
||||||
|
|
||||||
|
By default most Icom transceivers have *CI-V Tranceive Mode" enabled,
|
||||||
|
this will cause unsolicited CAT traffic from the rig that disrupts CAT
|
||||||
|
control by a PC. Disable this option in the rig's menu.
|
||||||
|
|
||||||
|
I want to control my transceiver with another application as well as _WSJT-X_, is that possible?::
|
||||||
|
|
||||||
|
This only possible to do reliably via some kind of rig control server,
|
||||||
|
that server must be able to accept both _WSJT-X_ and the other
|
||||||
|
application(s) as clients. Using a dumb serial port splitter like the
|
||||||
|
VSPE tool is not supported, it may work but it is not reliable due to
|
||||||
|
unmanaged CAT control collisions. Applications like the _Hamlib Rig
|
||||||
|
Control Server (rigctld)_, _{omnirig}_, and _{dxlsuite} Commander_ are
|
||||||
|
potentially suitable and _WSJT-X_ can act as a client to them all.
|
||||||
|
|
||||||
|
Rig control through _OmniRig_ seems to fail when I click *Test CAT*. What can I do about it?::
|
||||||
|
|
||||||
_Omni-Rig_ apparently has a bug that appears when you click *Test
|
_Omni-Rig_ apparently has a bug that appears when you click *Test
|
||||||
CAT*. Forget using *Test CAT* and just click *OK*. _Omni-Rig_ then
|
CAT*. Forget using *Test CAT* and just click *OK*. _Omni-Rig_ then
|
||||||
|
BIN
doc/user_guide/en/images/LoTW_TLS_error.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 4.3 KiB |
@ -1,10 +1,10 @@
|
|||||||
// Status=review
|
// Status=review
|
||||||
|
|
||||||
Source code for _WSJT-X_ is available from a public repository at
|
Source code for _WSJT-X_ is available from a public repository at
|
||||||
{devsvn}. To compile the program you will need to install at least the
|
{devrepo}. To compile the program you will need to install at least the
|
||||||
following packages:
|
following packages:
|
||||||
|
|
||||||
- Subversion 1.8 or later
|
- Git
|
||||||
- Qt 5.2 or later
|
- Qt 5.2 or later
|
||||||
- g++ 4.8 or later
|
- g++ 4.8 or later
|
||||||
- gfortran 4.8 or later
|
- gfortran 4.8 or later
|
||||||
@ -14,13 +14,15 @@ following packages:
|
|||||||
Source code for _WSJT-X_ v{VERSION} can be downloaded with the command:
|
Source code for _WSJT-X_ v{VERSION} can be downloaded with the command:
|
||||||
|
|
||||||
=====
|
=====
|
||||||
svn co svn://svn.code.sf.net/p/wsjt/wsjt/tags/wsjtx-{VERSION}
|
git clone git://git.code.sf.net/p/wsjt/wsjtx
|
||||||
|
cd wsjtx
|
||||||
|
git checkout wsjtx-{VERSION}
|
||||||
=====
|
=====
|
||||||
|
|
||||||
and for the current development branch,
|
and for the current development branch,
|
||||||
|
|
||||||
=====
|
=====
|
||||||
svn co svn://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx
|
git clone git://git.code.sf.net/p/wsjt/wsjtx
|
||||||
=====
|
=====
|
||||||
|
|
||||||
If you are interested in contributing to the development and
|
If you are interested in contributing to the development and
|
||||||
|
@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
Debian, Ubuntu, and other Debian-based systems including Raspbian:
|
Debian, Ubuntu, and other Debian-based systems including Raspbian:
|
||||||
|
|
||||||
|
NOTE: The project team release binary installer packages for Linux
|
||||||
|
when a new _WSJT-X_ release is announced, note that these are built to
|
||||||
|
target one contemporary version of a Linux distribution. Although
|
||||||
|
these may work on newer Linux versions or even different
|
||||||
|
distributions, it is unlikely that they will work on older
|
||||||
|
versions. Check the notes provided with the release for details of the
|
||||||
|
targeted Linux distributions and versions. If the binary package is
|
||||||
|
not compatible with your Linux distribution or version you must build
|
||||||
|
the application from sources.
|
||||||
|
|
||||||
* 32-bit: {debian32}
|
* 32-bit: {debian32}
|
||||||
- To install:
|
- To install:
|
||||||
+
|
+
|
||||||
@ -33,9 +43,9 @@ sudo dpkg -P wsjtx
|
|||||||
You may also need to execute the following command in a terminal:
|
You may also need to execute the following command in a terminal:
|
||||||
|
|
||||||
[example]
|
[example]
|
||||||
sudo apt install libqt5multimedia5-plugins libqt5serialport5 libfftw3-single3
|
sudo apt install libqt5multimedia5-plugins libqt5serialport5 libqt5sql5-sqlite libfftw3-single3
|
||||||
|
|
||||||
Fedora, Red Hat, and other rpm-based systems:
|
Fedora, CentOS, Red Hat, and other rpm-based systems:
|
||||||
|
|
||||||
* 32-bit: {fedora32}
|
* 32-bit: {fedora32}
|
||||||
- To install:
|
- To install:
|
||||||
|
@ -6,7 +6,7 @@ installation notes.
|
|||||||
|
|
||||||
If you have already installed a previous version, you can retain it by
|
If you have already installed a previous version, you can retain it by
|
||||||
changing its name in the *Applications* folder (say, from _WSJT-X_ to
|
changing its name in the *Applications* folder (say, from _WSJT-X_ to
|
||||||
_WSJT-X_1.8_). You can then proceed to the installation phase.
|
_WSJT-X_1.9_). You can then proceed to the installation phase.
|
||||||
|
|
||||||
Take note also of the following:
|
Take note also of the following:
|
||||||
|
|
||||||
|
@ -3,32 +3,70 @@
|
|||||||
Download and execute the package file {win32}, following these
|
Download and execute the package file {win32}, following these
|
||||||
instructions:
|
instructions:
|
||||||
|
|
||||||
- Install _WSJT-X_ into its own directory, for example `C:\WSJTX` or
|
* Install _WSJT-X_ into its own directory, for example `C:\WSJTX` or `
|
||||||
`C:\WSJT\WSJTX`, rather than the conventional location
|
C:\WSJT\WSJTX`, rather than the conventional location `C:\Program
|
||||||
`C:\Program Files\WSJTX`.
|
Files (x86)\WSJTX`.
|
||||||
|
|
||||||
- All program files relating to _WSJT-X_ will be stored in the chosen
|
* All program files relating to _WSJT-X_ will be stored in the chosen
|
||||||
installation directory and its subdirectories.
|
installation directory and its subdirectories.
|
||||||
|
|
||||||
|
* Logs and other writeable files will normally be found in the
|
||||||
|
directory +
|
||||||
|
|
||||||
- Logs and other writeable files will normally be found in the
|
|
||||||
directory +
|
|
||||||
`C:\Users\<username>\AppData\Local\WSJT-X`.
|
`C:\Users\<username>\AppData\Local\WSJT-X`.
|
||||||
|
|
||||||
TIP: Your computer may be configured so that this directory is
|
TIP: Your computer may be configured so that this directory is
|
||||||
"`invisible`". It's there, however, and accessible. An alternative
|
"`invisible`". It's there, however, and accessible. An
|
||||||
(shortcut) directory name is `%LOCALAPPDATA%\WSJT-X\`.
|
alternative (shortcut) directory name is
|
||||||
|
`"%LocalAppData%\WSJT-X\"`.
|
||||||
|
|
||||||
- The built-in Windows facility for time synchronization is usually
|
* The built-in Windows facility for time synchronization is usually
|
||||||
not adequate. We recommend the program _Meinberg NTP_ (see {ntpsetup}
|
not adequate. We recommend the program _Meinberg NTP_ (see
|
||||||
for downloading and installation instructions) or _Dimension 4_ from
|
{ntpsetup} for downloading and installation instructions) or
|
||||||
{dimension4}.
|
_Dimension 4_ from {dimension4}. Recent versions of Windows 10 are
|
||||||
|
now shipped with a more capable Internet time synchronization
|
||||||
|
service that is suitable if configured appropriately.
|
||||||
|
|
||||||
- _WSJT-X_ expects your sound card to do its raw sampling at 48000 Hz.
|
[[OPENSSL]]
|
||||||
To ensure that this will be so when running under recent versions of
|
|
||||||
Windows, open the system's *Sound* control panel and select in turn the
|
|
||||||
*Recording* and *Playback* tabs. Click on *Properties*, then
|
|
||||||
*Advanced*, and select *16 bit, 48000 Hz (DVD Quality)*.
|
|
||||||
|
|
||||||
- You can uninstall _WSJT-X_ by clicking its *Uninstall* link in the
|
* image:LoTW_TLS_error.png[_WSJT-X_ LoTW download TLS error, role="right"]
|
||||||
Windows *Start* menu, or by using *Uninstall a Program* on the
|
From this version onward _WSJT-X_ requires the _OpenSSL_ libraries
|
||||||
Windows Control Panel.
|
to be installed. Suitable libraries may already be installed on your
|
||||||
|
system, if they are not you will see this error shortly after
|
||||||
|
startup. To fix this you need to install the _OpenSSL_ libraries.
|
||||||
|
|
||||||
|
** You can download a suitable _OpenSSL_ package for from
|
||||||
|
{win_openssl_packages}, you need the latest *Win32 v1.0.2 Lite*
|
||||||
|
version (Note it is the Win32 package even if you are using a
|
||||||
|
64-bit Windows operating system) which at the time of writing was
|
||||||
|
{win32_openssl}.
|
||||||
|
|
||||||
|
** Install the package and accept the default options, including the
|
||||||
|
option to copy the _OpenSSL_ DLLs to the Windows system directory
|
||||||
|
(this is important). +
|
||||||
|
|
||||||
|
NOTE: If you still get the same network error after installing the
|
||||||
|
_OpenSSL_ libraries then you also need to install the
|
||||||
|
{msvcpp_redist} component. From the download page select
|
||||||
|
`vcredist_x86.exe` and run it to install.
|
||||||
|
|
||||||
|
TIP: If you cannot install the _OpenSSL_ libraries or do not have an
|
||||||
|
Internet connection on the computer used to run
|
||||||
|
_WSJT-X_ {VERSION_MAJOR}.{VERSION_MINOR}, you can download
|
||||||
|
the _LoTW_ file manually. Go to
|
||||||
|
https://lotw.arrl.org/lotw-user-activity.csv in a web browser,
|
||||||
|
download the file, then move it to the _WSJT-X_ log files
|
||||||
|
directory. This directory can be opened by selecting
|
||||||
|
*File | Open log directory*.
|
||||||
|
|
||||||
|
* _WSJT-X_ expects your sound card to do its raw sampling at 48000 Hz.
|
||||||
|
To ensure that this will be so when running under recent versions of
|
||||||
|
Windows, open the system's *Sound* control panel and select in turn
|
||||||
|
the *Recording* and *Playback* tabs. Click on *Properties*, then
|
||||||
|
*Advanced*, and select *16 bit, 48000 Hz (DVD Quality)*. Switch of
|
||||||
|
all audio enhancement features for these devices.
|
||||||
|
|
||||||
|
* You can uninstall _WSJT-X_ by clicking its *Uninstall* link in the
|
||||||
|
Windows *Start* menu, or by using *Uninstall a Program* on the
|
||||||
|
Windows Control Panel Programs and Features option or in Settings
|
||||||
|
Apps on Windows 10.
|
||||||
|
@ -7,29 +7,30 @@ K1**JT**,`" while the suffix "`-X`" indicates that _WSJT-X_ started as
|
|||||||
an extended and experimental branch of the program
|
an extended and experimental branch of the program
|
||||||
_WSJT_.
|
_WSJT_.
|
||||||
|
|
||||||
_WSJT-X_ Version 1.9 offers nine different protocols or modes: *FT8*,
|
_WSJT-X_ Version {VERSION_MAJOR}.{VERSION_MINOR} offers nine different
|
||||||
*JT4*, *JT9*, *JT65*, *QRA64*, *ISCAT*, *MSK144*, *WSPR*, and *Echo*.
|
protocols or modes: *FT8*, *JT4*, *JT9*, *JT65*, *QRA64*, *ISCAT*,
|
||||||
The first five are designed for making reliable QSOs under extreme
|
*MSK144*, *WSPR*, and *Echo*. The first five are designed for making
|
||||||
weak-signal conditions. They use nearly identical message structure
|
reliable QSOs under extreme weak-signal conditions. They use nearly
|
||||||
and source encoding. JT65 and QRA64 were designed for EME
|
identical message structure and source encoding. JT65 and QRA64 were
|
||||||
("`moonbounce`") on the VHF/UHF bands and have also proven very
|
designed for EME ("`moonbounce`") on the VHF/UHF bands and have also
|
||||||
effective for worldwide QRP communication on the HF bands. QRA64 has
|
proven very effective for worldwide QRP communication on the HF bands.
|
||||||
a number of advantages over JT65, including better performance on the
|
QRA64 has a number of advantages over JT65, including better
|
||||||
very weakest signals. We imagine that over time it may replace JT65
|
performance on the very weakest signals. We imagine that over time it
|
||||||
for EME use. JT9 was originally designed for the LF, MF, and lower HF
|
may replace JT65 for EME use. JT9 was originally designed for the LF,
|
||||||
bands. Its submode JT9A is 2 dB more sensitive than JT65 while using
|
MF, and lower HF bands. Its submode JT9A is 2 dB more sensitive than
|
||||||
less than 10% of the bandwidth. JT4 offers a wide variety of tone
|
JT65 while using less than 10% of the bandwidth. JT4 offers a wide
|
||||||
spacings and has proven highly effective for EME on microwave bands up
|
variety of tone spacings and has proven highly effective for EME on
|
||||||
to 24 GHz. These four "`slow`" modes use one-minute timed sequences
|
microwave bands up to 24 GHz. These four "`slow`" modes use
|
||||||
of alternating transmission and reception, so a minimal QSO takes four
|
one-minute timed sequences of alternating transmission and reception,
|
||||||
to six minutes — two or three transmissions by each station, one
|
so a minimal QSO takes four to six minutes — two or three
|
||||||
sending in odd UTC minutes and the other even. FT8 is operationally
|
transmissions by each station, one sending in odd UTC minutes and the
|
||||||
similar but four times faster (15-second T/R sequences) and less
|
other even. FT8 is operationally similar but four times faster
|
||||||
sensitive by a few dB. On the HF bands, world-wide QSOs are possible
|
(15-second T/R sequences) and less sensitive by a few dB. On the HF
|
||||||
with any of these modes using power levels of a few watts (or even
|
bands, world-wide QSOs are possible with any of these modes using
|
||||||
milliwatts) and compromise antennas. On VHF bands and higher, QSOs
|
power levels of a few watts (or even milliwatts) and compromise
|
||||||
are possible (by EME and other propagation types) at signal levels 10
|
antennas. On VHF bands and higher, QSOs are possible (by EME and
|
||||||
to 15 dB below those required for CW.
|
other propagation types) at signal levels 10 to 15 dB below those
|
||||||
|
required for CW.
|
||||||
|
|
||||||
*ISCAT*, *MSK144*, and optionally submodes *JT9E-H* are "`fast`"
|
*ISCAT*, *MSK144*, and optionally submodes *JT9E-H* are "`fast`"
|
||||||
protocols designed to take advantage of brief signal enhancements from
|
protocols designed to take advantage of brief signal enhancements from
|
||||||
@ -47,7 +48,7 @@ format with hashed callsigns.
|
|||||||
potential propagation paths using low-power transmissions. WSPR
|
potential propagation paths using low-power transmissions. WSPR
|
||||||
messages normally carry the transmitting station’s callsign, grid
|
messages normally carry the transmitting station’s callsign, grid
|
||||||
locator, and transmitter power in dBm, and they can be decoded at
|
locator, and transmitter power in dBm, and they can be decoded at
|
||||||
signal-to-noise ratios as low as -28 dB in a 2500 Hz bandwidth. WSPR
|
signal-to-noise ratios as low as -31 dB in a 2500 Hz bandwidth. WSPR
|
||||||
users with internet access can automatically upload reception
|
users with internet access can automatically upload reception
|
||||||
reports to a central database called {wsprnet} that provides a mapping
|
reports to a central database called {wsprnet} that provides a mapping
|
||||||
facility, archival storage, and many other features.
|
facility, archival storage, and many other features.
|
||||||
|
@ -18,17 +18,8 @@ this option is checked _WSJT-X_ appends some additional information to
|
|||||||
all CQ messages displayed in the _Band Activity_ window. The name of
|
all CQ messages displayed in the _Band Activity_ window. The name of
|
||||||
the DXCC entity is shown, abbreviated if necessary. Your "`worked
|
the DXCC entity is shown, abbreviated if necessary. Your "`worked
|
||||||
before`" status for this callsign (according to log file
|
before`" status for this callsign (according to log file
|
||||||
`wsjtx_log.adi`) is flagged with a single character and a change of
|
`wsjtx_log.adi`) is indicated by highlighting colors, if that option
|
||||||
background color, as follows:
|
has been selected.
|
||||||
|
|
||||||
[horizontal]
|
|
||||||
!:: Default color bright purple: New DXCC entity
|
|
||||||
~:: Light pink: You have already worked this DXCC entity but not
|
|
||||||
this station
|
|
||||||
:: Green: You have previously worked the calling station
|
|
||||||
|
|
||||||
In this respect the program does not distinguish between modes, but it
|
|
||||||
does differentiate between bands.
|
|
||||||
|
|
||||||
_WSJT-X_ includes a built-in `cty.dat` file containing DXCC prefix
|
_WSJT-X_ includes a built-in `cty.dat` file containing DXCC prefix
|
||||||
information. Updated files can be downloaded from the {cty_dat} web
|
information. Updated files can be downloaded from the {cty_dat} web
|
||||||
@ -45,3 +36,5 @@ before status* off and then on again will cause _WSJT-X_ to re-read
|
|||||||
the log file. Very large log files may cause _WSJT-X_ to slow down
|
the log file. Very large log files may cause _WSJT-X_ to slow down
|
||||||
when searching for calls.
|
when searching for calls.
|
||||||
|
|
||||||
|
Additional features are provided for *Contest* and *Fox* logging.
|
||||||
|
(more to come, here ...)
|
||||||
|
@ -19,7 +19,10 @@ one callsign) followed by the transmitting station’s grid locator, a
|
|||||||
signal report, R plus a signal report, or the final acknowledgements
|
signal report, R plus a signal report, or the final acknowledgements
|
||||||
RRR or 73. These messages are compressed and encoded in a highly
|
RRR or 73. These messages are compressed and encoded in a highly
|
||||||
efficient and reliable way. In uncompressed form (as displayed
|
efficient and reliable way. In uncompressed form (as displayed
|
||||||
on-screen) they may contain as many as 22 characters.
|
on-screen) they may contain as many as 22 characters. Some operators
|
||||||
|
prefer ro send RR73 rather than RRR. This is workable because RR73 is
|
||||||
|
encoded as a valid grid locator, one unlikely ever to be occupied by
|
||||||
|
an amateur station.
|
||||||
|
|
||||||
*Signal reports* are specified as signal-to-noise ratio (S/N) in dB,
|
*Signal reports* are specified as signal-to-noise ratio (S/N) in dB,
|
||||||
using a standard reference noise bandwidth of 2500 Hz. Thus, in the
|
using a standard reference noise bandwidth of 2500 Hz. Thus, in the
|
||||||
@ -76,36 +79,92 @@ NOTE: When *Auto-Seq* is enabled the program de-activates *Enable Tx*
|
|||||||
at the end of each QSO. It is not intended that _WSJT-X_ should make
|
at the end of each QSO. It is not intended that _WSJT-X_ should make
|
||||||
fully automated QSOs.
|
fully automated QSOs.
|
||||||
|
|
||||||
=== VHF Contest Mode
|
=== Contest Messages
|
||||||
|
|
||||||
A special *NA VHF Contest* mode can be activated for FT8 and MSK144.
|
The new FT8 and MSK144 protocols support special messages optimized
|
||||||
To use it you must activate *File | Settings | General | Enable
|
for *NA VHF* and *EU VHF* contests. FT8 also supports messages for
|
||||||
VHF/UHF/Microwave features* and then check the box *NA VHF Contest* on
|
*ARRL Field Day* and the *ARRL RTTY Roundup*. The decoders recognize
|
||||||
the main window. This mode is configured especially for contests in
|
and decode these messages at any time. Configure the program to
|
||||||
which four-character grid locators are the required exchange. When
|
automatically generate the required message types by selecting a
|
||||||
*NA VHF Contest* mode is active, the standard QSO sequence looks like
|
supported operating activity on the *Settings | Advanced* tab. Model
|
||||||
this:
|
QSOs then proceed as follows, for each event type:
|
||||||
|
|
||||||
|
*NA VHF Contest*
|
||||||
|
|
||||||
CQ K1ABC FN42
|
CQ K1ABC FN42
|
||||||
K1ABC W9XYZ EN37
|
K1ABC W9XYZ EN37
|
||||||
W9XYZ K1ABC R FN42
|
W9XYZ K1ABC R FN42
|
||||||
K1ABC W9XYZ RRR
|
K1ABC W9XYZ RRR
|
||||||
W9XYZ K1ABC 73
|
W9XYZ K1ABC 73
|
||||||
|
|
||||||
In contest circumstances K1ABC might choose to call CQ again rather
|
Either callsign (or both) may have /R appended. You can use RR73 in
|
||||||
than sending 73 for his third transmission.
|
place of RRR, and the final 73 is optional.
|
||||||
|
|
||||||
IMPORTANT: Do not use VHF Contest Mode on an HF band or in conditions
|
|
||||||
where worldwide propagation is available. See
|
*EU VHF Contest*
|
||||||
<<PROTOCOL_OVERVIEW,Protocol Specifications>> for further details.
|
|
||||||
|
CQ TEST G4ABC IO91
|
||||||
|
G4ABC PA9XYZ JO22
|
||||||
|
PA9XYZ 570123 IO91NP
|
||||||
|
G4ABC R 580071 JO22DB
|
||||||
|
PA9XYZ G4ABC RR73
|
||||||
|
|
||||||
|
Either callsign (or both) may have /P appended.
|
||||||
|
|
||||||
|
*ARRL Field Day*
|
||||||
|
|
||||||
|
CQ FD K1ABC FN42
|
||||||
|
K1ABC W9XYZ 6A WI
|
||||||
|
W9XYZ K1ABC R 2B EMA
|
||||||
|
K1ABC W9XYZ RR73
|
||||||
|
|
||||||
|
*ARRL RTTY Roundup*
|
||||||
|
|
||||||
|
CQ RU K1ABC FN42
|
||||||
|
K1ABC W9XYZ 579 WI
|
||||||
|
W9XYZ K1ABC R 589 MA
|
||||||
|
K1ABC W9XYZ RR73
|
||||||
|
|
||||||
[[COMP-CALL]]
|
[[COMP-CALL]]
|
||||||
=== Compound Callsigns
|
=== Compound Callsigns
|
||||||
|
|
||||||
Compound callsigns such as xx/K1ABC or K1ABC/x are handled in
|
*FT8 and MSK144*
|
||||||
one of two possible ways:
|
|
||||||
|
|
||||||
.Messages containing Type 1 compound callsigns
|
Compound callsigns like xx/K1ABC or K1ABC/x and nonstandard callsigns
|
||||||
|
like YW18FIFA are supported for normal QSOs but not for the special
|
||||||
|
contest-style messages. Model QSOs look something like this:
|
||||||
|
|
||||||
|
CQ PJ4/K1ABC
|
||||||
|
<PJ4/K1ABC> W9XYZ
|
||||||
|
W9XYZ <PJ4/K1ABC> +03
|
||||||
|
<PJ4/K1ABC> W9XYZ R-08
|
||||||
|
<W9XYZ> PJ4/K1ABC RRR
|
||||||
|
PJ4/K1ABC <W9XYZ> 73
|
||||||
|
|
||||||
|
The compound or nonstandard callsigns are automatically recognized and
|
||||||
|
handled using special message formats. One such callsign and one
|
||||||
|
standard callsign may appear in most messages, provided that one of
|
||||||
|
them is enclosed in < > angle brackets. If the message includes a
|
||||||
|
grid locator or numerical signal report, the brackets must enclose the
|
||||||
|
compound or nonstandard callsign; otherwise the brackets may be around
|
||||||
|
either call.
|
||||||
|
|
||||||
|
Angle brackets imply that the enclosed callsign is not transmitted in
|
||||||
|
full, but rather as a hash code using a smaller number of bits.
|
||||||
|
Receiving stations will display the full nonstandard callsign if it
|
||||||
|
has been received in full in the recent past. Otherwise it will be
|
||||||
|
displayed as < . . . >. These restrictions are honored automatically
|
||||||
|
by the algorithm that generates default messages for minimal QSOs.
|
||||||
|
Except for the special cases involving /P or /R used in VHF
|
||||||
|
contesting, _WSJT-X {VERSION_MAJOR}.{VERSION_MINOR}_ offers no support
|
||||||
|
for two nonstandard callsigns to work each other.
|
||||||
|
|
||||||
|
*JT4, JT9, JT65, and QRA64*
|
||||||
|
|
||||||
|
In the 72-bit modes, compound callsigns are handled in one of two
|
||||||
|
possible ways:
|
||||||
|
|
||||||
|
.Type 1 compound callsigns
|
||||||
|
|
||||||
A list of about 350 of the most common prefixes and suffixes can be
|
A list of about 350 of the most common prefixes and suffixes can be
|
||||||
displayed from the *Help* menu. A single compound callsign involving
|
displayed from the *Help* menu. A single compound callsign involving
|
||||||
@ -139,7 +198,7 @@ Notice that the full compound callsign is sent and received in the
|
|||||||
first two transmissions. After that, the operators omit the add-on
|
first two transmissions. After that, the operators omit the add-on
|
||||||
prefix or suffix and use the standard structured messages.
|
prefix or suffix and use the standard structured messages.
|
||||||
|
|
||||||
.Type 2 Compound-Callsign Messages
|
.Type 2 Compound callsigns
|
||||||
|
|
||||||
Prefixes and suffixes _not_ found in the displayable short list are
|
Prefixes and suffixes _not_ found in the displayable short list are
|
||||||
handled by using *Type 2* compound callsigns. In this case the
|
handled by using *Type 2* compound callsigns. In this case the
|
||||||
|
@ -20,6 +20,8 @@ tab, delete any default frequencies for *FreqCal* mode that are not
|
|||||||
relevant for your location. You may want to replace some of them with
|
relevant for your location. You may want to replace some of them with
|
||||||
reliably known frequencies receivable at your location.
|
reliably known frequencies receivable at your location.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
TIP: We find major-city AM broadcast stations generally serve well as
|
TIP: We find major-city AM broadcast stations generally serve well as
|
||||||
frequency calibrators at the low frequency end of the spectrum. In
|
frequency calibrators at the low frequency end of the spectrum. In
|
||||||
North America we also use the standard time-and-frequency broadcasts
|
North America we also use the standard time-and-frequency broadcasts
|
||||||
|
@ -1,33 +1,41 @@
|
|||||||
=== New in Version 1.9
|
=== New in Version {VERSION}
|
||||||
|
|
||||||
For quick reference, here's a short list of features and capabilities
|
For quick reference, here's a short list of features and capabilities
|
||||||
added to _WSJT-X_ since Version 1.8.0:
|
added to _WSJT-X_ since Version 1.9.1:
|
||||||
|
|
||||||
- New *FT8 DXpedition Mode* to facilitate high QSO rates in pileup
|
- New FT8 and MSK144 protocols with 77-bit payloads permit these enhancements:
|
||||||
situations
|
|
||||||
|
|
||||||
- Decoding improvements for JT65 mode, including _a priori_ (AP)
|
* Optimized contest messages for NA VHF, EU VHF, Field Day, RTTY Roundup
|
||||||
decoding when VHF/UHF/Microwave features are enabled
|
|
||||||
|
|
||||||
- Optional Auto-Sequencing in JT4, JT9, and JT65 when VHF/UHF/Microwave features are enabled
|
* Full support for "/R" and "/P" calls in relevant contests
|
||||||
|
|
||||||
- Better suppression of low-confidence false decodes generated by AP
|
* New logging features for contesting
|
||||||
decoding in FT8 mode
|
|
||||||
|
|
||||||
- Improved decoding performance for WSPR mode, especially effective at LF and MF
|
* Integration with {n1mm_logger} and {writelog} for contesting
|
||||||
|
|
||||||
- Minor adjustments to auto-sequencing behavior
|
* Improved support for compound and nonstandard callsigns
|
||||||
|
|
||||||
- More flexible Doppler control features for EME
|
* Nearly equal (or better) sensitivity compared to old protocols
|
||||||
|
|
||||||
- Improved waterfall sensitivity for very weak signals
|
* Lower false decode rates
|
||||||
|
|
||||||
- Automatic real-time forwarding of logged information to _N1MM Logger+_
|
- Improved color highlighting of received messages
|
||||||
|
|
||||||
|
- Improved WSPR sensitivity
|
||||||
|
|
||||||
- Expanded and improved UDP messages sent to companion programs
|
- Expanded and improved UDP messages sent to companion programs
|
||||||
|
|
||||||
- Bug fixes and other minor tweaks to user interface
|
- Bug fixes and other minor tweaks to user interface
|
||||||
|
|
||||||
|
IMPORTANT: Note that for FT8 and MSK144 there is no backward
|
||||||
|
compatibility with WSJT-X 1.9.1 and earlier. Everyone using these
|
||||||
|
modes should upgrade to WSJT-X 2.0 by January 1, 2019.
|
||||||
|
|
||||||
|
IMPORTANT: _WSJT-X_ Version 2.0 drops support for Apple Mac OS X 10.9
|
||||||
|
(Mavericks). It is possible to build from source for this operating
|
||||||
|
system version but the DMG installer package requires 10.10 or later.
|
||||||
|
|
||||||
|
|
||||||
=== Documentation Conventions
|
=== Documentation Conventions
|
||||||
|
|
||||||
In this manual the following icons call attention to particular types
|
In this manual the following icons call attention to particular types
|
||||||
@ -45,12 +53,12 @@ consequences.
|
|||||||
=== How You Can Contribute
|
=== How You Can Contribute
|
||||||
|
|
||||||
_WSJT-X_ is part of an open-source project released under the
|
_WSJT-X_ is part of an open-source project released under the
|
||||||
{gnu_gpl} (GPL). If you have programming or documentation skills or
|
{gnu_gpl} (GPLv3). If you have programming or documentation skills or
|
||||||
would like to contribute to the project in other ways, please make
|
would like to contribute to the project in other ways, please make
|
||||||
your interests known to the development team. The project's
|
your interests known to the development team. The project's
|
||||||
source-code repository can be found at {devsvn}, and most
|
source-code repository can be found at {devrepo}, and communication
|
||||||
communication among the developers takes place on the email reflector
|
among the developers takes place on the email reflector {devmail}.
|
||||||
{devmail}. Bug reports and suggestions for new features, improvements
|
Bug reports and suggestions for new features, improvements to the
|
||||||
to the _WSJT-X_ User Guide, etc., may also be sent to the
|
_WSJT-X_ User Guide, etc., may also be sent to the {wsjt_yahoo_group}
|
||||||
{wsjt_yahoo_group} email reflector. You must join the relevant group
|
email reflector. You must join the relevant group before posting to
|
||||||
before posting to either email list.
|
either email list.
|
||||||
|
@ -2,18 +2,20 @@
|
|||||||
=== Overview
|
=== Overview
|
||||||
|
|
||||||
All QSO modes except ISCAT use structured messages that compress
|
All QSO modes except ISCAT use structured messages that compress
|
||||||
user-readable information into fixed-length packets of 72 bits. Each
|
user-readable information into fixed-length packets. JT4, JT9, JT65,
|
||||||
message consists of two 28-bit fields normally used for callsigns and
|
and QRA64 use 72-bit payloads. Standard messages consist of two
|
||||||
a 15-bit field for a grid locator, report, acknowledgment, or 73. An
|
28-bit fields normally used for callsigns and a 15-bit field for a
|
||||||
additional bit flags a message containing arbitrary alphanumeric text,
|
grid locator, report, acknowledgment, or 73. An additional bit flags
|
||||||
up to 13 characters. Special cases allow other information such as
|
a message containing arbitrary free text, up to 13 characters.
|
||||||
add-on callsign prefixes (e.g., ZA/K1ABC) or suffixes (e.g., K1ABC/P)
|
Special cases allow other information such as add-on callsign prefixes
|
||||||
to be encoded. The basic aim is to compress the most common messages
|
(e.g., ZA/K1ABC) or suffixes (e.g., K1ABC/P) to be encoded. The basic
|
||||||
used for minimally valid QSOs into a fixed 72-bit length. The
|
aim is to compress the most common messages used for minimally valid
|
||||||
information payload in FT8 includes 3 additional bits (75 bits total).
|
QSOs into a fixed 72-bit length.
|
||||||
One of the added bits is used to flag special messages used by the
|
|
||||||
DXpedition station in FT8 DXpedition Mode. Uses for the remaining two
|
The information payload for FT8 and MSK144 contains 77 bits. The 5
|
||||||
bits are yet to be defined.
|
additional bits are used to flag special message types used for FT8
|
||||||
|
DXpedition Mode, contesting, nonstandard callsigns, and a few other
|
||||||
|
special types.
|
||||||
|
|
||||||
A standard amateur callsign consists of a one- or two-character
|
A standard amateur callsign consists of a one- or two-character
|
||||||
prefix, at least one of which must be a letter, followed by a digit
|
prefix, at least one of which must be a letter, followed by a digit
|
||||||
@ -42,22 +44,16 @@ additional information is sent in place of the grid locator or by
|
|||||||
encoding additional information into some of the 6 million available
|
encoding additional information into some of the 6 million available
|
||||||
slots mentioned above.
|
slots mentioned above.
|
||||||
|
|
||||||
As a convenience for sending directed CQ messages, the compression
|
As a convenience for sending directed CQ messages, the 72-bit
|
||||||
algorithm supports messages starting with `CQ AA` through `CQ ZZ`.
|
compression algorithm supports messages starting with `CQ AA` through
|
||||||
These message fragments are encoded internally as if they were the
|
`CQ ZZ`. These message fragments are encoded internally as if they
|
||||||
callsigns `E9AA` through `E9ZZ`. Upon reception they are converted
|
were the callsigns `E9AA` through `E9ZZ`. Upon reception they are
|
||||||
back to the form `CQ AA` through `CQ ZZ`, for display to the user.
|
converted back to the form `CQ AA` through `CQ ZZ`, for display to the
|
||||||
|
user.
|
||||||
|
|
||||||
The FT8 and MSK144 modes support a special feature allowing convenient
|
The new FT8 and MSK144 protocols use a different lossless compression
|
||||||
transmission and acknowledgment of four-character grid locators, the
|
algorithm with features to generate and recognize the special messages
|
||||||
required exchanges in most North American VHF contests. With this
|
used for contesting and the like. (More to come, here ...)
|
||||||
Contest Mode enabled, _WSJT-X_ supports messages of the form `W9XYZ
|
|
||||||
K1ABC R FN42` by converting the grid locator to that of its
|
|
||||||
diametrically opposite point on Earth. The receiving program
|
|
||||||
recognizes a locator implying a distance greater than 10,000 km, does
|
|
||||||
the reverse transformation, and inserts the implied "`R`". Obviously,
|
|
||||||
this mode should not be used on the HF bands or under other
|
|
||||||
circumstances where world-wide propagation is possible.
|
|
||||||
|
|
||||||
To be useful on channels with low signal-to-noise ratio, this kind of
|
To be useful on channels with low signal-to-noise ratio, this kind of
|
||||||
lossless message compression requires use of a strong forward error
|
lossless message compression requires use of a strong forward error
|
||||||
@ -75,9 +71,9 @@ _WSJT-X_ modes have continuous phase and constant envelope.
|
|||||||
==== FT8
|
==== FT8
|
||||||
|
|
||||||
Forward error correction (FEC) in FT8 uses a low-density parity check
|
Forward error correction (FEC) in FT8 uses a low-density parity check
|
||||||
(LDPC) code with 75 information bits, a 12-bit cyclic redundancy check
|
(LDPC) code with 77 information bits, a 14-bit cyclic redundancy check
|
||||||
(CRC), and 87 parity bits making a 174-bit codeword. It is thus
|
(CRC), and 83 parity bits making a 174-bit codeword. It is thus
|
||||||
called an LDPC (174,87) code. Synchronization uses 7×7 Costas arrays
|
called an LDPC (174,91) code. Synchronization uses 7×7 Costas arrays
|
||||||
at the beginning, middle, and end of each transmission. Modulation is
|
at the beginning, middle, and end of each transmission. Modulation is
|
||||||
8-tone frequency-shift keying (8-FSK) at 12000/1920 = 6.25 baud. Each
|
8-tone frequency-shift keying (8-FSK) at 12000/1920 = 6.25 baud. Each
|
||||||
transmitted symbol carries three bits, so the total number of channel
|
transmitted symbol carries three bits, so the total number of channel
|
||||||
@ -231,7 +227,7 @@ which the probability of decoding is 50% or higher.
|
|||||||
|===============================================================================
|
|===============================================================================
|
||||||
|Mode |FEC Type |(n,k) | Q|Modulation type|Keying rate (Baud)|Bandwidth (Hz)
|
|Mode |FEC Type |(n,k) | Q|Modulation type|Keying rate (Baud)|Bandwidth (Hz)
|
||||||
|Sync Energy|Tx Duration (s)|S/N Threshold (dB)
|
|Sync Energy|Tx Duration (s)|S/N Threshold (dB)
|
||||||
|FT8 |LDPC, r=1/2|(174,87)| 8| 8-FSK| 6.25 | 50.0 | 0.27| 12.6 | -21
|
|FT8 |LDPC, r=1/2|(174,91)| 8| 8-FSK| 6.25 | 50.0 | 0.27| 12.6 | -21
|
||||||
|JT4A |K=32, r=1/2|(206,72)| 2| 4-FSK| 4.375| 17.5 | 0.50| 47.1 | -23
|
|JT4A |K=32, r=1/2|(206,72)| 2| 4-FSK| 4.375| 17.5 | 0.50| 47.1 | -23
|
||||||
|JT9A |K=32, r=1/2|(206,72)| 8| 9-FSK| 1.736| 15.6 | 0.19| 49.0 | -27
|
|JT9A |K=32, r=1/2|(206,72)| 8| 9-FSK| 1.736| 15.6 | 0.19| 49.0 | -27
|
||||||
|JT65A |Reed Solomon|(63,12) |64|65-FSK| 2.692| 177.6 | 0.50| 46.8 | -25
|
|JT65A |Reed Solomon|(63,12) |64|65-FSK| 2.692| 177.6 | 0.50| 46.8 | -25
|
||||||
@ -329,13 +325,13 @@ For details see Table 4, below.
|
|||||||
|
|
||||||
==== MSK144
|
==== MSK144
|
||||||
|
|
||||||
Standard MSK144 messages are structured in the same way as those in
|
Standard MSK144 messages are structured in the same way as in FT8,
|
||||||
the slow modes, with 72 bits of user information. Forward error
|
with 77 bits of user information. Forward error correction is
|
||||||
correction is implemented by first augmenting the 72 message bits with
|
implemented by first augmenting the 77 message bits with a 13-bit
|
||||||
an 8-bit cyclic redundancy check (CRC) calculated from the message
|
cyclic redundancy check (CRC) calculated from the message bits. The
|
||||||
bits. The CRC is used to detect and eliminate most false decodes at
|
CRC is used to detect and eliminate most false decodes at the
|
||||||
the receiver. The resulting 80-bit augmented message is mapped to a
|
receiver. The resulting 90-bit augmented message is mapped to a
|
||||||
128-bit codeword using a (128,80) binary low-density-parity-check
|
128-bit codeword using a (128,90) binary low-density-parity-check
|
||||||
(LDPC) code designed by K9AN specifically for this purpose. Two 8-bit
|
(LDPC) code designed by K9AN specifically for this purpose. Two 8-bit
|
||||||
synchronizing sequences are added to make a message frame 144 bits
|
synchronizing sequences are added to make a message frame 144 bits
|
||||||
long. Modulation is Offset Quadrature Phase-Shift Keying (OQPSK) at
|
long. Modulation is Offset Quadrature Phase-Shift Keying (OQPSK) at
|
||||||
@ -379,6 +375,6 @@ and your QSO partner ± 200 Hz.
|
|||||||
|JT9F |K=32, r=1/2|(206,72)| 8| 9-FSK| 50.0 | 450 | 0.19| 1.700
|
|JT9F |K=32, r=1/2|(206,72)| 8| 9-FSK| 50.0 | 450 | 0.19| 1.700
|
||||||
|JT9G |K=32, r=1/2|(206,72)| 8| 9-FSK|100.0 | 900 | 0.19| 0.850
|
|JT9G |K=32, r=1/2|(206,72)| 8| 9-FSK|100.0 | 900 | 0.19| 0.850
|
||||||
|JT9H |K=32, r=1/2|(206,72)| 8| 9-FSK|200.0 | 1800 | 0.19| 0.425
|
|JT9H |K=32, r=1/2|(206,72)| 8| 9-FSK|200.0 | 1800 | 0.19| 0.425
|
||||||
|MSK144 |LDPC |(128,80)| 2| OQPSK| 2000 | 2400 | 0.11| 0.072
|
|MSK144 |LDPC |(128,90)| 2| OQPSK| 2000 | 2400 | 0.11| 0.072
|
||||||
|MSK144 Sh|LDPC |(32,16) | 2| OQPSK| 2000 | 2400 | 0.20| 0.020
|
|MSK144 Sh|LDPC |(32,16) | 2| OQPSK| 2000 | 2400 | 0.20| 0.020
|
||||||
|=====================================================================
|
|=====================================================================
|
||||||
|
@ -27,6 +27,8 @@ receiver's effective noise bandwidth.
|
|||||||
a larger delay between execution of a command to enable PTT and onset
|
a larger delay between execution of a command to enable PTT and onset
|
||||||
of Tx audio.
|
of Tx audio.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
IMPORTANT: For the health of your T/R relays and external
|
IMPORTANT: For the health of your T/R relays and external
|
||||||
preamplifier, we strongly recommend using a hardware sequencer and
|
preamplifier, we strongly recommend using a hardware sequencer and
|
||||||
testing to make sure that sequencing is correct.
|
testing to make sure that sequencing is correct.
|
||||||
@ -36,9 +38,16 @@ with twice or four times the normal tone spacing. This feature is
|
|||||||
intended for use with specialized LF/MF transmitters that divide
|
intended for use with specialized LF/MF transmitters that divide
|
||||||
generated frequencies by 2 or 4 as part of the transmission process.
|
generated frequencies by 2 or 4 as part of the transmission process.
|
||||||
|
|
||||||
_FT8 DXpedition Mode_
|
_Special Operating Activity: Generation of FT8 and MSk144 messages_
|
||||||
|
|
||||||
|
- Check this box and select the type of activity to enable
|
||||||
|
auto-generation of special message formats for contesting and
|
||||||
|
DXpeditions. For *ARRL Field Day*, enter your operating Class and
|
||||||
|
ARRL/RAC section; for *ARRL RTTY Roundup*, enter your state or province.
|
||||||
|
Use “DX” for section or state if you are not in the US or Canada. In
|
||||||
|
the RTTY Roundup, Stations in Alaska and Hawaii should enter “DX”.
|
||||||
|
|
||||||
- Check *Fox* if you are a DXpedition station operating in FT8
|
- Check *Fox* if you are a DXpedition station operating in FT8
|
||||||
DXpedition Mode. Check *Hound* if you wish to make QSOs with such a
|
DXpedition Mode. Check *Hound* if you wish to make QSOs with such a
|
||||||
Fox. Be sure to read the operating instructions for {ft8_DXped}.
|
Fox. Be sure to read the operating instructions for {ft8_DXped}.
|
||||||
|
|
||||||
|
@ -4,18 +4,21 @@ image::settings-audio.png[align="center",alt="_WSJT-X_ Audio Configuration Scree
|
|||||||
|
|
||||||
Select the *Audio* tab to configure your sound system.
|
Select the *Audio* tab to configure your sound system.
|
||||||
|
|
||||||
- _Soundcard_: Select the audio devices to be used for *Input* and
|
* _Soundcard_: Select the audio devices to be used for *Input* and
|
||||||
*Output*. Usually the *Mono* settings will suffice, but in special
|
*Output*. Usually the *Mono* settings will suffice, but in special
|
||||||
cases you can choose *Left*, *Right*, or *Both* stereo channels.
|
cases you can choose *Left*, *Right*, or *Both* stereo channels.
|
||||||
|
|
||||||
- Be sure that your audio device is configured to sample at 48000 Hz,
|
** Be sure that your audio device is configured to sample at 48000 Hz,
|
||||||
16 bits.
|
16 bits.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
IMPORTANT: If you select the audio output device that is also your
|
IMPORTANT: If you select the audio output device that is also your
|
||||||
computer's default audio device, be sure to turn off all system sounds
|
computer's default audio device, be sure to turn off all system sounds
|
||||||
to prevent inadvertently transmitting them over the air.
|
to prevent inadvertently transmitting them over the air.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
NOTE: Windows Vista and later may configure audio devices using
|
NOTE: Windows Vista and later may configure audio devices using
|
||||||
the Texas Instruments PCM2900 series CODEC for microphone input rather
|
the Texas Instruments PCM2900 series CODEC for microphone input rather
|
||||||
line input. (This chip is used in many radios with built-in USB
|
line input. (This chip is used in many radios with built-in USB
|
||||||
@ -23,18 +26,20 @@ CODECs, as well as various other audio interfaces.) If you are using
|
|||||||
such a device, be sure to set the mic level in the Recording Device
|
such a device, be sure to set the mic level in the Recording Device
|
||||||
Properties to 0 dB.
|
Properties to 0 dB.
|
||||||
|
|
||||||
- _Save Directory_: _WSJT-X_ can save its received audio sequences as
|
+
|
||||||
|
|
||||||
|
* _Save Directory_: _WSJT-X_ can save its received audio sequences as
|
||||||
`.wav` files. A default directory for these files is provided; you
|
`.wav` files. A default directory for these files is provided; you
|
||||||
can select another location if desired.
|
can select another location if desired.
|
||||||
|
|
||||||
- _AzEl Directory_: A file named `azel.dat` will appear in the
|
* _AzEl Directory_: A file named `azel.dat` will appear in the
|
||||||
specified directory. The file contains information usable by another
|
specified directory. The file contains information usable by another
|
||||||
program for automatic tracking of the Sun or Moon, as well as
|
program for automatic tracking of the Sun or Moon, as well as
|
||||||
calculated Doppler shift for the specified EME path. The file is
|
calculated Doppler shift for the specified EME path. The file is
|
||||||
updated once per second whenever the <<ASTRODATA,Astronomical Data>>
|
updated once per second whenever the <<ASTRODATA,Astronomical Data>>
|
||||||
window is displayed.
|
window is displayed.
|
||||||
|
|
||||||
- _Remember power settings by band_: Checking either of these will
|
* _Remember power settings by band_: Checking either of these will
|
||||||
cause _WSJT-X_ to remember the *Pwr* slider setting for that operation
|
cause _WSJT-X_ to remember the *Pwr* slider setting for that operation
|
||||||
on a band-by-band basis. For example, when *Tune* is checked here and
|
on a band-by-band basis. For example, when *Tune* is checked here and
|
||||||
you click the *Tune* button on the main window, the power slider will
|
you click the *Tune* button on the main window, the power slider will
|
||||||
|
@ -1,5 +1,47 @@
|
|||||||
image::colors.png[align="center",alt="Colors Screen"]
|
image::colors.png[align="center",alt="Colors Screen"]
|
||||||
|
|
||||||
_WSJT-X_ uses colors to highlight decoded messages containing
|
.Decode Highlighting
|
||||||
information of particular interest. Click on one of the buttons to
|
|
||||||
select your preferred colors for any message category.
|
* _WSJT-X_ uses colors to highlight decoded CQ messages of particular
|
||||||
|
interest. Check the box *Show DXCC, grid, and worked-before status*
|
||||||
|
on the *Settings | General* tab, and any boxes of interest to you on
|
||||||
|
the *Colors* tab. You can drag any line up or down to raise or
|
||||||
|
lower its logical priority. Right-click any line to set a new
|
||||||
|
foreground or background color. Foreground and background colors
|
||||||
|
are applied separately, and careful choices of foreground,
|
||||||
|
background, and priority can provide two indications of
|
||||||
|
worked-before status.
|
||||||
|
|
||||||
|
* Press the *Reset Highlighting* button to reset all of the color
|
||||||
|
settings to default values.
|
||||||
|
|
||||||
|
* Check *Highlight by Mode* if you wish worked before status to be per
|
||||||
|
<<INTRO,mode>>.
|
||||||
|
|
||||||
|
* Worked before status is calculated from your _WSJT-X_ ADIF
|
||||||
|
<<LOGGING, Logging>> file, you may replace ADIF log file with one
|
||||||
|
exported from your station logging application, *Rescan ADIF Log*
|
||||||
|
rebuilds the _WSJT-X_ worked before indexes using the current ADIF
|
||||||
|
log file.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
TIP: The _WSJT-X_ ADIF file records must contain the "CALL" field.
|
||||||
|
The "BAND", and "MODE", and "GRIDSQUARE" fields are optional
|
||||||
|
depending on your DXing objectives. DXCC entity, continent, CQ,
|
||||||
|
and ITU Zone data for call prefixes and certain well known
|
||||||
|
overrides are derived from the cty.dat database which is bundled
|
||||||
|
with _WSJT-X_ (See <<LOGGING,Logging>> for details).
|
||||||
|
|
||||||
|
.Logbook of The World User Validation
|
||||||
|
|
||||||
|
Stations who are known to have uploaded their logs to the ARRL LoTW
|
||||||
|
QSL matching service can be highlighted. The data used to determine
|
||||||
|
this is available on line.
|
||||||
|
|
||||||
|
* *Fetch Now* will download a fresh dataset from the *Users CSV file
|
||||||
|
URL*. The LoTW team normally update this data weekly.
|
||||||
|
|
||||||
|
* Adjust *Age of of last upload less than* to set the period within
|
||||||
|
which a station must have uploaded their log to LoTW to trigger
|
||||||
|
highlighting.
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
image::settings-frequencies.png[align="center",alt="Frequency Screen"]
|
image::settings-frequencies.png[align="center",alt="Frequency Screen"]
|
||||||
|
|
||||||
_Working Frequencies_: By default the *Working Frequencies* table
|
_Working Frequencies_: By default the *Working Frequencies* table
|
||||||
contains a list of frequencies conventionally used for modes JT4, JT9,
|
contains a list of frequencies conventionally used for modes FT8, JT4,
|
||||||
JT65, MSK144, WSPR, and Echo. Conventions may change with time or
|
JT9, JT65, MSK144, WSPR, and Echo. Conventions may change with time
|
||||||
by user preference; you can modify the frequency table as desired.
|
or by user preference; you can modify the frequency table as desired.
|
||||||
|
|
||||||
- To change an existing entry, double-click to edit it, type a desired
|
- To change an existing entry, double-click to edit it, type a desired
|
||||||
frequency in MHz or select from the drop down list of options, then
|
frequency in MHz or select from the drop down list of options, then
|
||||||
|
@ -17,6 +17,6 @@ NOTE: If you are using a callsign with an add-on prefix or
|
|||||||
suffix, or wish to work a station using such a call, be sure to read
|
suffix, or wish to work a station using such a call, be sure to read
|
||||||
the section <<COMP-CALL,Compound Callsigns>>.
|
the section <<COMP-CALL,Compound Callsigns>>.
|
||||||
|
|
||||||
NOTE: Enabling VHF/UHF/Microwave features necessarily disables the
|
NOTE: Checking *Enable VHF/UHF/Microwave features* necessarily
|
||||||
wideband multi-decode capability of JT65. In most circumstances you
|
disables the wideband multi-decode capability of JT65. In most
|
||||||
should turn this feature off when operating at HF.
|
circumstances you should turn this feature off when operating at HF.
|
||||||
|
@ -6,66 +6,91 @@ _WSJT-X_ offers CAT (Computer Aided Transceiver) control of relevant
|
|||||||
features of most modern transceivers. To configure the program for
|
features of most modern transceivers. To configure the program for
|
||||||
your radio, select the *Radio* tab.
|
your radio, select the *Radio* tab.
|
||||||
|
|
||||||
- Select your radio type from the drop-down list labeled *Rig*, or
|
* Select your radio type from the drop-down list labeled *Rig*, or
|
||||||
*None* if you do not wish to use CAT control.
|
*None* if you do not wish to use CAT control.
|
||||||
|
|
||||||
- Alternatively, if you have configured your station for control by
|
** Alternatively, if you have configured your station for control by
|
||||||
*DX Lab Suite Commander*, *Ham Radio Deluxe*, *Hamlib NET rigctl*, or
|
*DX Lab Suite Commander*, *Flrig*, *Ham Radio Deluxe*, *Hamlib NET
|
||||||
*Omni-Rig*, you may select one of those program names from the *Rig*
|
rigctl*, or *Omni-Rig*, you may select one of those program names
|
||||||
list. In these cases the entry field immediately under _CAT Control_
|
from the *Rig* list. In these cases the entry field immediately
|
||||||
will be relabeled as *Network Server*. Leave this field blank to
|
under _CAT Control_ will be relabeled as *Network Server*. Leave
|
||||||
access the default instance of your control program, running on the
|
this field blank to access the default instance of your control
|
||||||
same computer. If the control program runs on a different computer
|
program, running on the same computer. If the control program runs
|
||||||
and/or port, specify it here. Hover the mouse pointer over the entry
|
on a different computer and/or port, specify it here. Hover the
|
||||||
field to see the required formatting details.
|
mouse pointer over the entry field to see the required formatting
|
||||||
|
details.
|
||||||
|
|
||||||
- Select *Omni-Rig Rig 1* or *Omni-Rig Rig 2* to connect to an
|
** Select *Omni-Rig Rig 1* or *Omni-Rig Rig 2* to connect to an
|
||||||
_Omni-Rig_ server running on the same computer. Note that _Omni-Rig_
|
_Omni-Rig_ server installed on the same computer. _Omni-Rig_ will
|
||||||
is available only under Windows.
|
be started automatically by _WSJT-X_.
|
||||||
|
|
||||||
- Set *Poll Interval* to the desired interval for _WSJT-X_ to query
|
+
|
||||||
your radio. For most radios a small number (say, 1 – 3 s) is
|
|
||||||
suitable.
|
|
||||||
|
|
||||||
- _CAT Control_: To have _WSJT-X_ control the radio directly rather
|
NOTE: _Omni-Rig_ is available only under Windows.
|
||||||
than though another program, make the following settings:
|
|
||||||
|
|
||||||
* Select the *Serial Port* used to communicate with your radio.
|
* Set *Poll Interval* to the desired interval for _WSJT-X_ to query
|
||||||
|
your radio. For most radios a small number (say, 1 – 3 s) is
|
||||||
|
suitable.
|
||||||
|
|
||||||
* _Serial Port Parameters_: Set values for *Baud Rate*, *Data Bits*,
|
* _CAT Control_: To have _WSJT-X_ control the radio directly rather
|
||||||
*Stop Bits*, and *Handshake* method. Consult your radio's user guide
|
than though another program, make the following settings:
|
||||||
for the proper parameter values.
|
|
||||||
|
|
||||||
* _Force Control Lines_: A few station setups require the CAT serial
|
** Select the *Serial Port* or *Network Server* including the service
|
||||||
port’s *RTS* and/or *DTR* control lines to be forced high or
|
port number used to communicate with your radio.
|
||||||
low. Check these boxes only if you are sure they are needed (for
|
|
||||||
example, to power the radio serial interface).
|
|
||||||
|
|
||||||
- _PTT Method_: select *VOX*, *CAT*, *DTR*, or *RTS* as the desired
|
+
|
||||||
method for T/R switching. If your choice is *DTR* or *RTS*, select
|
|
||||||
the desired serial port (which may be the same one as used for
|
|
||||||
CAT control).
|
|
||||||
|
|
||||||
- _Transmit Audio Source_: some radios permit you to choose the
|
NOTE: A special value of *USB* is available for custom USB devices
|
||||||
connector that will accept Tx audio. If this choice is enabled,
|
like those used by some SDR kits. This is not the same a virtual
|
||||||
select *Rear/Data* or *Front/Mic*.
|
serial port provided by USB connected transcivers and CAT
|
||||||
|
interfaces, for those use the COM or serial port name that
|
||||||
|
refers to them.
|
||||||
|
|
||||||
- _Mode_: _WSJT-X_ uses upper sideband mode for both transmitting and
|
** _Serial Port Parameters_: Set values for *Baud Rate*, *Data Bits*,
|
||||||
receiving. Select *USB*, or choose *Data/Pkt* if your radio offers
|
*Stop Bits*, and *Handshake* method. Consult your radio's user
|
||||||
such an option and uses it to enable the rear-panel audio line input.
|
*guide for the proper parameter values.
|
||||||
Some radios also offer wider and/or flatter passbands when set to
|
|
||||||
*Data/Pkt* mode. Select *None* if you do not want _WSJT-X_ to change
|
|
||||||
the radio's Mode setting.
|
|
||||||
|
|
||||||
- _Split Operation_: Significant advantages result from using *Split*
|
+
|
||||||
mode (separate VFOs for Rx and Tx) if your radio supports it. If it
|
|
||||||
does not, _WSJT-X_ can emulate such behavior. Either method will
|
NOTE: CAT interfaces that require handshaking will be non-responsive
|
||||||
result in a cleaner transmitted signal, by keeping the Tx audio always
|
until the correct *Handshake* setting is applied.
|
||||||
in the range 1500 to 2000 Hz so that audio harmonics cannot pass
|
|
||||||
through the Tx sideband filter. Select *Rig* to use the radio's Split
|
** _Force Control Lines_: A few station setups require the CAT serial
|
||||||
mode, or *Fake It* to have _WSJT-X_ adjust the VFO frequency as
|
port’s *RTS* and/or *DTR* control lines to be forced high or
|
||||||
needed, when T/R switching occurs. Choose *None* if you do not
|
low. Check these boxes *only* if you are sure they are needed (for
|
||||||
wish to use split operation.
|
example, to power the radio serial interface).
|
||||||
|
|
||||||
|
* _PTT Method_: select *VOX*, *CAT*, *DTR*, or *RTS* as the desired
|
||||||
|
method for T/R switching. If your choice is *DTR* or *RTS*, select
|
||||||
|
the desired serial port (which may be the same one as used for CAT
|
||||||
|
control).
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
NOTE: When using a proxy application for rig control, *CAT* is usually
|
||||||
|
the correct option for _PTT Method_ assuming the proxy
|
||||||
|
application is capable of keying your transceiver idependently.
|
||||||
|
|
||||||
|
* _Transmit Audio Source_: some radios permit you to choose the
|
||||||
|
connector that will accept Tx audio. If this choice is enabled,
|
||||||
|
select *Rear/Data* or *Front/Mic*.
|
||||||
|
|
||||||
|
* _Mode_: _WSJT-X_ uses upper sideband mode for both transmitting and
|
||||||
|
receiving. Select *USB*, or choose *Data/Pkt* if your radio offers
|
||||||
|
such an option and uses it to enable the rear-panel audio line
|
||||||
|
input. Some radios also offer wider and/or flatter passbands when
|
||||||
|
set to *Data/Pkt* mode. Select *None* if you do not want _WSJT-X_
|
||||||
|
to change the radio's Mode setting.
|
||||||
|
|
||||||
|
* _Split Operation_: Significant advantages result from using *Split*
|
||||||
|
mode (separate VFOs for Rx and Tx) if your radio supports it. If it
|
||||||
|
does not, _WSJT-X_ can emulate such behavior. Either method will
|
||||||
|
result in a cleaner transmitted signal, by keeping the Tx audio
|
||||||
|
always in the range 1500 to 2000 Hz so that audio harmonics cannot
|
||||||
|
pass through the Tx sideband filter. Select *Rig* to use the
|
||||||
|
radio's Split mode, or *Fake It* to have _WSJT-X_ adjust the VFO
|
||||||
|
frequency as needed, when T/R switching occurs. Choose *None* if
|
||||||
|
you do not wish to use split operation.
|
||||||
|
|
||||||
When all required settings have been made, click *Test CAT* to test
|
When all required settings have been made, click *Test CAT* to test
|
||||||
communication between _WSJT-X_ and your radio. The button should turn
|
communication between _WSJT-X_ and your radio. The button should turn
|
||||||
|
@ -2,53 +2,63 @@
|
|||||||
.Receiver Noise Level
|
.Receiver Noise Level
|
||||||
|
|
||||||
- If it is not already highlighted in green, click the *Monitor*
|
- If it is not already highlighted in green, click the *Monitor*
|
||||||
button to start normal receive operation.
|
button to start normal receive operation.
|
||||||
|
|
||||||
- Be sure your transceiver is set to *USB* (or *USB Data*) mode.
|
- Be sure your transceiver is set to *USB* (or *USB Data*) mode.
|
||||||
|
|
||||||
- Use the receiver gain controls and/or the computer's audio mixer
|
- Use the receiver gain controls and/or the computer's audio mixer
|
||||||
controls to set the background noise level (scale at lower left of
|
controls to set the background noise level (scale at lower left of
|
||||||
main window) to around 30 dB when no signals are present. It is
|
main window) to around 30 dB when no signals are present. It is
|
||||||
usually best to turn AGC off or reduce the RF gain control to minimize
|
usually best to turn AGC off or reduce the RF gain control to
|
||||||
AGC action.
|
minimize AGC action.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
TIP: The PC audio mixer normally has two sliders, one for each
|
||||||
|
application attached which should be set to maximum (0dB FS) as
|
||||||
|
it cannot help with distortion from overly high or low input
|
||||||
|
levels from your receiver and another *Master* level which is
|
||||||
|
analogue attenuator on the sound card before the Analogue to
|
||||||
|
Digital Converter (ADC). The *Master* level can be used to adjust
|
||||||
|
the signal level received by _WSJT-X_.
|
||||||
|
|
||||||
.Bandwidth and Frequency Setting
|
.Bandwidth and Frequency Setting
|
||||||
|
|
||||||
- If your transceiver offers more than one bandwidth setting in USB
|
- If your transceiver offers more than one bandwidth setting in USB
|
||||||
mode, it may be advantageous to choose the widest one possible, up to
|
mode, it may be advantageous to choose the widest one possible, up
|
||||||
about 5 kHz. This choice has the desirable effect of allowing the
|
to about 5 kHz. This choice has the desirable effect of allowing
|
||||||
*Wide Graph* (waterfall and 2D spectrum) to display the conventional
|
the *Wide Graph* (waterfall and 2D spectrum) to display the
|
||||||
JT65 and JT9 sub-bands simultaneously on most HF bands. Further
|
conventional JT65 and JT9 sub-bands simultaneously on most HF bands.
|
||||||
details are provided in the <<TUTORIAL,Basic Operating Tutorial>>. A
|
Further details are provided in the <<TUTORIAL,Basic Operating
|
||||||
wider displayed bandwidth may also be helpful at VHF and above, where
|
Tutorial>>. A wider displayed bandwidth may also be helpful at VHF
|
||||||
FT8, JT4, JT65, and QRA64 signals may be found over much wider ranges
|
and above, where FT8, JT4, JT65, and QRA64 signals may be found over
|
||||||
of frequencies.
|
much wider ranges of frequencies.
|
||||||
|
|
||||||
- If you have only a standard SSB filter you won’t be able to display
|
- If you have only a standard SSB filter you won’t be able to display
|
||||||
more than about 2.7 kHz bandwidth. Depending on the exact dial
|
more than about 2.7 kHz bandwidth. Depending on the exact dial
|
||||||
frequency setting, on HF bands you can display the full sub-band
|
frequency setting, on HF bands you can display the full sub-band
|
||||||
generally used for one mode.
|
generally used for one mode.
|
||||||
|
|
||||||
- Of course, you might prefer to concentrate on one mode at a time,
|
- Of course, you might prefer to concentrate on one mode at a time,
|
||||||
setting your dial frequency to (say) 14.074 for FT8, 14.076 for JT65,
|
setting your dial frequency to (say) 14.074 for FT8, 14.076 for
|
||||||
or 14.078 for JT9. Present conventions have the nominal JT9 dial
|
JT65, or 14.078 for JT9. Present conventions have the nominal JT9
|
||||||
frequency 2 kHz higher than the JT65 dial frequency on most bands, and
|
dial frequency 2 kHz higher than the JT65 dial frequency on most
|
||||||
the FT8 frequency 2 kHz lower.
|
bands, and the FT8 frequency 2 kHz lower.
|
||||||
|
|
||||||
.Transmitter Audio Level
|
.Transmitter Audio Level
|
||||||
|
|
||||||
* Click the *Tune* button on the main screen to switch the
|
* Click the *Tune* button on the main screen to switch the radio into
|
||||||
radio into transmit mode and generate a steady audio tone.
|
transmit mode and generate a steady audio tone.
|
||||||
|
|
||||||
* Listen to the generated audio tone using your radio’s *Monitor*
|
* Listen to the generated audio tone using your radio’s *Monitor*
|
||||||
facility. The transmitted tone should be perfectly smooth, with no
|
facility. The transmitted tone should be perfectly smooth, with no
|
||||||
clicks or glitches. Make sure that this is true even when you
|
clicks or glitches. Make sure that this is true even when you
|
||||||
simultaneously use the computer to do other tasks such as email, web
|
simultaneously use the computer to do other tasks such as email, web
|
||||||
browsing, etc.
|
browsing, etc..
|
||||||
|
|
||||||
* Adjust the *Pwr* slider (at right edge of main window) downward from
|
* Adjust the *Pwr* slider (at right edge of main window) downward from
|
||||||
its maximum until the RF output from your transmitter falls slightly.
|
its maximum until the RF output from your transmitter falls
|
||||||
This is generally a good level for audio drive.
|
slightly. This is generally a good level for audio drive.
|
||||||
|
|
||||||
* Toggle the *Tune* button once more or click *Halt Tx* to stop your
|
* Toggle the *Tune* button once more or click *Halt Tx* to stop your
|
||||||
test transmission.
|
test transmission.
|
||||||
|
@ -64,6 +64,8 @@ so that a transmission will start automatically at the proper time.
|
|||||||
*Shift* key to move only the Tx frequency or the *Ctrl* key to move
|
*Shift* key to move only the Tx frequency or the *Ctrl* key to move
|
||||||
both Rx and Tx frequencies.
|
both Rx and Tx frequencies.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
NOTE: You can prevent your Tx frequency from being changed by checking the
|
NOTE: You can prevent your Tx frequency from being changed by checking the
|
||||||
box *Hold Tx Freq*.
|
box *Hold Tx Freq*.
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ image::decodes.png[align="center"]
|
|||||||
earlier, in <<TUT_EX1,Example 1>>. _WSJT-X_ automatically determines
|
earlier, in <<TUT_EX1,Example 1>>. _WSJT-X_ automatically determines
|
||||||
the mode of each JT9 or JT65 message.
|
the mode of each JT9 or JT65 message.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
TIP: When you double-click on a signal in the waterfall it will be
|
TIP: When you double-click on a signal in the waterfall it will be
|
||||||
properly decoded even if on the "`wrong`" side of the *JT65 nnnn JT9*
|
properly decoded even if on the "`wrong`" side of the *JT65 nnnn JT9*
|
||||||
marker. The Tx mode automatically switches to that of the decoded
|
marker. The Tx mode automatically switches to that of the decoded
|
||||||
|
@ -43,16 +43,17 @@ frequency to that of the selected message and leaving Tx frequency
|
|||||||
unchanged. To change both Rx and Tx frequencies, hold *Ctrl* down
|
unchanged. To change both Rx and Tx frequencies, hold *Ctrl* down
|
||||||
when double-clicking.
|
when double-clicking.
|
||||||
|
|
||||||
NOTE: To avoid QRM from competing callers, it is frequently desirable
|
TIP: To avoid QRM from competing callers, it is frequently desirable
|
||||||
to answer a CQ on a different frequency from that of the CQing
|
to answer a CQ on a different frequency from that of the CQing
|
||||||
station. The same is true when you tail-end another QSO. Choose a Tx
|
station. The same is true when you tail-end another QSO. Choose a Tx
|
||||||
frequency that appears to be not in use.
|
frequency that appears to be not in use. You might want to check the
|
||||||
|
box *Hold Tx Freq*.
|
||||||
|
|
||||||
NOTE: Keyboard shortcuts *Shift+F11* and *Shift+F12* provide an easy
|
TIP: Keyboard shortcuts *Shift+F11* and *Shift+F12* provide an easy
|
||||||
way to move your Tx frequency down or up in 60 Hz steps.
|
way to move your Tx frequency down or up in 60 Hz steps.
|
||||||
|
|
||||||
NOTE: Further helpful tips on FT8 operating procedures are available
|
TIP: An online {ft8_tips} by ZL2IFB offers many helpful tips on
|
||||||
{ft8_tips}. Thanks to ZL2IFB!
|
operating procedures.
|
||||||
|
|
||||||
.FT8 DXpedition Mode:
|
.FT8 DXpedition Mode:
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
- Set the audio frequencies to *Tx 1224 Hz* and *Rx 1224 Hz*.
|
- Set the audio frequencies to *Tx 1224 Hz* and *Rx 1224 Hz*.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
TIP: Sliders and spinner controls respond to *Arrow* key presses
|
TIP: Sliders and spinner controls respond to *Arrow* key presses
|
||||||
and *Page Up/Down* key presses, with the *Page* keys moving the
|
and *Page Up/Down* key presses, with the *Page* keys moving the
|
||||||
controls in larger steps. You can also type numbers directly into
|
controls in larger steps. You can also type numbers directly into
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
_WSJT-X_ v1.9 suppports a number of features designed for use
|
_WSJT-X_ v{VERSION_MAJOR}.{VERSION_MINOR} suppports a number of
|
||||||
on the VHF and higher bands. These features include:
|
features designed for use on the VHF and higher bands. These features
|
||||||
|
include:
|
||||||
|
|
||||||
- *FT8*, a mode designed for making fast QSOs with weak, fading
|
- *FT8*, a mode designed for making fast QSOs with weak, fading
|
||||||
signals
|
signals
|
||||||
@ -276,6 +277,8 @@ this number is well below 100% you may increase the decoding depth
|
|||||||
from *Fast* to *Normal* or *Deep*, and increase *F Tol* from 100 to
|
from *Fast* to *Normal* or *Deep*, and increase *F Tol* from 100 to
|
||||||
200 Hz.
|
200 Hz.
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
NOTE: Most modern multi-core computers can easily handle the optimum
|
NOTE: Most modern multi-core computers can easily handle the optimum
|
||||||
parameters *Deep* and *F Tol 200*. Older and slower machines may not
|
parameters *Deep* and *F Tol 200*. Older and slower machines may not
|
||||||
be able to keep up at these settings; at the *Fast* and *Normal*
|
be able to keep up at these settings; at the *Fast* and *Normal*
|
||||||
@ -303,6 +306,7 @@ enclosed in <> angle brackets, as in the following model QSO
|
|||||||
<W9XYZ K1ABC> RRR
|
<W9XYZ K1ABC> RRR
|
||||||
<K1ABC W9XYZ> 73
|
<K1ABC W9XYZ> 73
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
NOTE: There is little or no advantage to using MSK144 *Sh*
|
NOTE: There is little or no advantage to using MSK144 *Sh*
|
||||||
messages at 50 or 70 MHz. At these frequencies, most pings are long
|
messages at 50 or 70 MHz. At these frequencies, most pings are long
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// This is a comment line, anything with // is ignored at process time.
|
// This is a comment line, anything with // is ignored at process time.
|
||||||
= _WSJT-X_ User Guide
|
= _WSJT-X {VERSION_MAJOR}.{VERSION_MINOR}_ User Guide
|
||||||
Joseph H Taylor, Jr, K1JT
|
Joseph H Taylor, Jr, K1JT
|
||||||
:revnumber: {VERSION}
|
:revnumber: {VERSION}
|
||||||
// For web-pages, adding :badges: is ok, but is a security issue for
|
// For web-pages, adding :badges: is ok, but is a security issue for
|
||||||
@ -113,9 +113,12 @@ include::transceiver-setup.adoc[]
|
|||||||
This section introduces the basic user controls and program behavior
|
This section introduces the basic user controls and program behavior
|
||||||
of _WSJT-X_, with particular emphasis on the JT9, JT65, and FT8 modes.
|
of _WSJT-X_, with particular emphasis on the JT9, JT65, and FT8 modes.
|
||||||
We suggest that new users should go through the full HF-oriented
|
We suggest that new users should go through the full HF-oriented
|
||||||
tutorial, preferably while at your radio. Subsequent sections cover
|
tutorial, preferably while at your radio. Note that as of late 2018,
|
||||||
additional details on <<MAKE_QSOS,Making QSOs>>, <<WSPR,WSPR mode>>
|
digital usage on the HF bands has mostly moved from JT65 and JT9 to FT8. So
|
||||||
and <<VHF_AND_UP,VHF+ Features>>.
|
you may wish to pay particular attention to *FT8*, in Section 6.6.
|
||||||
|
|
||||||
|
Subsequent sections cover additional details on <<MAKE_QSOS,Making
|
||||||
|
QSOs>>, <<WSPR,WSPR mode>> and <<VHF_AND_UP,VHF+ Features>>.
|
||||||
|
|
||||||
[[TUT_MAIN]]
|
[[TUT_MAIN]]
|
||||||
=== Main Window Settings
|
=== Main Window Settings
|
||||||
|
@ -11,6 +11,8 @@ desired size.
|
|||||||
|
|
||||||
- Select an active WSPR frequency (for example, 10.1387 or 14.0956 MHz).
|
- Select an active WSPR frequency (for example, 10.1387 or 14.0956 MHz).
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
IMPORTANT: If you will transmit in the 60 m band, be sure to choose a
|
IMPORTANT: If you will transmit in the 60 m band, be sure to choose a
|
||||||
frequency that conforms with your local regulations.
|
frequency that conforms with your local regulations.
|
||||||
|
|
||||||
|
@ -28,3 +28,4 @@ void CallsignDelegate::setModelData (QWidget * editor, QAbstractItemModel * mode
|
|||||||
{
|
{
|
||||||
model->setData (index, static_cast<QLineEdit *> (editor)->text (), Qt::EditRole);
|
model->setData (index, static_cast<QLineEdit *> (editor)->text (), Qt::EditRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#ifndef DATE_TIME_AS_SECS_SINCE_EPOCH_DELEGATE_HPP_
|
#ifndef DATE_TIME_AS_SECS_SINCE_EPOCH_DELEGATE_HPP_
|
||||||
#define DATE_TIME_AS_SECS_SINCE_EPOCH_DELEGATE_HPP_
|
#define DATE_TIME_AS_SECS_SINCE_EPOCH_DELEGATE_HPP_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QLocale>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QDateTimeEdit>
|
#include <QDateTimeEdit>
|
||||||
@ -33,12 +35,17 @@ public:
|
|||||||
|
|
||||||
QString displayText (QVariant const& value, QLocale const& locale) const override
|
QString displayText (QVariant const& value, QLocale const& locale) const override
|
||||||
{
|
{
|
||||||
return locale.toString (to_date_time (value), QLocale::ShortFormat);
|
return locale.toString (to_date_time (value), locale.dateFormat (QLocale::ShortFormat) + " hh:mm:ss");
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget * createEditor (QWidget * parent, QStyleOptionViewItem const& /*option*/, QModelIndex const& /*index*/) const override
|
QWidget * createEditor (QWidget * parent, QStyleOptionViewItem const& /*option*/, QModelIndex const& /*index*/) const override
|
||||||
{
|
{
|
||||||
return new QDateTimeEdit {parent};
|
std::unique_ptr<QDateTimeEdit> editor {new QDateTimeEdit {parent}};
|
||||||
|
editor->setDisplayFormat (parent->locale ().dateFormat (QLocale::ShortFormat) + " hh:mm:ss");
|
||||||
|
editor->setTimeSpec (Qt::UTC); // needed because it ignores time
|
||||||
|
// spec of the QDateTime that it is
|
||||||
|
// set from
|
||||||
|
return editor.release ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEditorData (QWidget * editor, QModelIndex const& index) const override
|
void setEditorData (QWidget * editor, QModelIndex const& index) const override
|
||||||
|
16
lib/crc.f90
@ -34,22 +34,6 @@ module crc
|
|||||||
integer (c_int), value :: length
|
integer (c_int), value :: length
|
||||||
end function crc13_check
|
end function crc13_check
|
||||||
|
|
||||||
function crc12 (data, length) bind (C, name="crc12")
|
|
||||||
use, intrinsic :: iso_c_binding, only: c_short, c_ptr, c_int
|
|
||||||
implicit none
|
|
||||||
integer (c_short) :: crc12
|
|
||||||
type (c_ptr), value :: data
|
|
||||||
integer (c_int), value :: length
|
|
||||||
end function crc12
|
|
||||||
|
|
||||||
function crc12_check (data, length) bind (C, name="crc12_check")
|
|
||||||
use, intrinsic :: iso_c_binding, only: c_bool, c_ptr, c_int
|
|
||||||
implicit none
|
|
||||||
logical (c_bool) :: crc12_check
|
|
||||||
type (c_ptr), value :: data
|
|
||||||
integer (c_int), value :: length
|
|
||||||
end function crc12_check
|
|
||||||
|
|
||||||
function crc10 (data, length) bind (C, name="crc10")
|
function crc10 (data, length) bind (C, name="crc10")
|
||||||
use, intrinsic :: iso_c_binding, only: c_short, c_ptr, c_int
|
use, intrinsic :: iso_c_binding, only: c_short, c_ptr, c_int
|
||||||
implicit none
|
implicit none
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
#include <boost/crc.hpp>
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
short crc12 (unsigned char const * data, int length);
|
|
||||||
bool crc12_check (unsigned char const * data, int length);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define POLY 0xc06
|
|
||||||
|
|
||||||
#ifdef BOOST_NO_CXX11_CONSTEXPR
|
|
||||||
#define TRUNCATED_POLYNOMIAL POLY
|
|
||||||
#else
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
unsigned long constexpr TRUNCATED_POLYNOMIAL = POLY;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// assumes CRC is last 16 bits of the data and is set to zero
|
|
||||||
// caller should assign the returned CRC into the message in big endian byte order
|
|
||||||
short crc12 (unsigned char const * data, int length)
|
|
||||||
{
|
|
||||||
return boost::augmented_crc<12, TRUNCATED_POLYNOMIAL> (data, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool crc12_check (unsigned char const * data, int length)
|
|
||||||
{
|
|
||||||
return !boost::augmented_crc<12, TRUNCATED_POLYNOMIAL> (data, length);
|
|
||||||
}
|
|
@ -470,8 +470,8 @@ contains
|
|||||||
real, intent(in) :: dt
|
real, intent(in) :: dt
|
||||||
real, intent(in) :: freq
|
real, intent(in) :: freq
|
||||||
character(len=37), intent(in) :: decoded
|
character(len=37), intent(in) :: decoded
|
||||||
character c1*12,c2*12,g2*4,w*4,ctmp*12
|
character c1*12,c2*12,g2*4,w*4
|
||||||
integer i0,i1,i2,i3,i4,i5,i6,n30,nwrap
|
integer i0,i1,i2,i3,i4,i5,n30,nwrap
|
||||||
integer, intent(in) :: nap
|
integer, intent(in) :: nap
|
||||||
real, intent(in) :: qual
|
real, intent(in) :: qual
|
||||||
character*2 annot
|
character*2 annot
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
subroutine fmtmsg(msg,iz)
|
subroutine fmtmsg(msg,iz)
|
||||||
|
|
||||||
character*22 msg
|
character*(*) msg
|
||||||
|
|
||||||
! Convert all letters to upper case
|
! Convert all letters to upper case
|
||||||
iz=22
|
iz=len(msg)
|
||||||
do i=1,22
|
do i=1,iz
|
||||||
if(msg(i:i).ge.'a' .and. msg(i:i).le.'z') &
|
if(msg(i:i).ge.'a' .and. msg(i:i).le.'z') &
|
||||||
msg(i:i)= char(ichar(msg(i:i))+ichar('A')-ichar('a'))
|
msg(i:i)= char(ichar(msg(i:i))+ichar('A')-ichar('a'))
|
||||||
if(msg(i:i).ne.' ') iz=i
|
if(msg(i:i).ne.' ') iz=i
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
do iter=1,5 !Collapse multiple blanks into one
|
do iter=1,37 !Collapse multiple blanks into one
|
||||||
ib2=index(msg(1:iz),' ')
|
ib2=index(msg(1:iz),' ')
|
||||||
if(ib2.lt.1) go to 100
|
if(ib2.lt.1) go to 100
|
||||||
msg=msg(1:ib2)//msg(ib2+2:)
|
msg=msg(1:ib2)//msg(ib2+2:)
|
||||||
|
@ -1,401 +0,0 @@
|
|||||||
subroutine bpdecode174(llr,apmask,maxiterations,decoded,cw,nharderror,iter)
|
|
||||||
!
|
|
||||||
! A log-domain belief propagation decoder for the (174,87) code.
|
|
||||||
!
|
|
||||||
integer, parameter:: N=174, K=87, M=N-K
|
|
||||||
integer*1 codeword(N),cw(N),apmask(N)
|
|
||||||
integer colorder(N)
|
|
||||||
integer*1 decoded(K)
|
|
||||||
integer Nm(7,M) ! 5, 6, or 7 bits per check
|
|
||||||
integer Mn(3,N) ! 3 checks per bit
|
|
||||||
integer synd(M)
|
|
||||||
real tov(3,N)
|
|
||||||
real toc(7,M)
|
|
||||||
real tanhtoc(7,M)
|
|
||||||
real zn(N)
|
|
||||||
real llr(N)
|
|
||||||
real Tmn
|
|
||||||
integer nrw(M)
|
|
||||||
|
|
||||||
data colorder/ &
|
|
||||||
0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,&
|
|
||||||
17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,&
|
|
||||||
36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,&
|
|
||||||
56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,&
|
|
||||||
73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,&
|
|
||||||
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,&
|
|
||||||
120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,&
|
|
||||||
140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,&
|
|
||||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173/
|
|
||||||
|
|
||||||
data Mn/ &
|
|
||||||
1, 25, 69, &
|
|
||||||
2, 5, 73, &
|
|
||||||
3, 32, 68, &
|
|
||||||
4, 51, 61, &
|
|
||||||
6, 63, 70, &
|
|
||||||
7, 33, 79, &
|
|
||||||
8, 50, 86, &
|
|
||||||
9, 37, 43, &
|
|
||||||
10, 41, 65, &
|
|
||||||
11, 14, 64, &
|
|
||||||
12, 75, 77, &
|
|
||||||
13, 23, 81, &
|
|
||||||
15, 16, 82, &
|
|
||||||
17, 56, 66, &
|
|
||||||
18, 53, 60, &
|
|
||||||
19, 31, 52, &
|
|
||||||
20, 67, 84, &
|
|
||||||
21, 29, 72, &
|
|
||||||
22, 24, 44, &
|
|
||||||
26, 35, 76, &
|
|
||||||
27, 36, 38, &
|
|
||||||
28, 40, 42, &
|
|
||||||
30, 54, 55, &
|
|
||||||
34, 49, 87, &
|
|
||||||
39, 57, 58, &
|
|
||||||
45, 74, 83, &
|
|
||||||
46, 62, 80, &
|
|
||||||
47, 48, 85, &
|
|
||||||
59, 71, 78, &
|
|
||||||
1, 50, 53, &
|
|
||||||
2, 47, 84, &
|
|
||||||
3, 25, 79, &
|
|
||||||
4, 6, 14, &
|
|
||||||
5, 7, 80, &
|
|
||||||
8, 34, 55, &
|
|
||||||
9, 36, 69, &
|
|
||||||
10, 43, 83, &
|
|
||||||
11, 23, 74, &
|
|
||||||
12, 17, 44, &
|
|
||||||
13, 57, 76, &
|
|
||||||
15, 27, 56, &
|
|
||||||
16, 28, 29, &
|
|
||||||
18, 19, 59, &
|
|
||||||
20, 40, 63, &
|
|
||||||
21, 35, 52, &
|
|
||||||
22, 54, 64, &
|
|
||||||
24, 62, 78, &
|
|
||||||
26, 32, 77, &
|
|
||||||
30, 72, 85, &
|
|
||||||
31, 65, 87, &
|
|
||||||
33, 39, 51, &
|
|
||||||
37, 48, 75, &
|
|
||||||
38, 70, 71, &
|
|
||||||
41, 42, 68, &
|
|
||||||
45, 67, 86, &
|
|
||||||
46, 81, 82, &
|
|
||||||
49, 66, 73, &
|
|
||||||
58, 60, 66, &
|
|
||||||
61, 65, 85, &
|
|
||||||
1, 14, 21, &
|
|
||||||
2, 13, 59, &
|
|
||||||
3, 67, 82, &
|
|
||||||
4, 32, 73, &
|
|
||||||
5, 36, 54, &
|
|
||||||
6, 43, 46, &
|
|
||||||
7, 28, 75, &
|
|
||||||
8, 33, 71, &
|
|
||||||
9, 49, 76, &
|
|
||||||
10, 58, 64, &
|
|
||||||
11, 48, 68, &
|
|
||||||
12, 19, 45, &
|
|
||||||
15, 50, 61, &
|
|
||||||
16, 22, 26, &
|
|
||||||
17, 72, 80, &
|
|
||||||
18, 40, 55, &
|
|
||||||
20, 35, 51, &
|
|
||||||
23, 25, 34, &
|
|
||||||
24, 63, 87, &
|
|
||||||
27, 39, 74, &
|
|
||||||
29, 78, 83, &
|
|
||||||
30, 70, 77, &
|
|
||||||
31, 69, 84, &
|
|
||||||
22, 37, 86, &
|
|
||||||
38, 41, 81, &
|
|
||||||
42, 44, 57, &
|
|
||||||
47, 53, 62, &
|
|
||||||
52, 56, 79, &
|
|
||||||
60, 75, 81, &
|
|
||||||
1, 39, 77, &
|
|
||||||
2, 16, 41, &
|
|
||||||
3, 31, 54, &
|
|
||||||
4, 36, 78, &
|
|
||||||
5, 45, 65, &
|
|
||||||
6, 57, 85, &
|
|
||||||
7, 14, 49, &
|
|
||||||
8, 21, 46, &
|
|
||||||
9, 15, 72, &
|
|
||||||
10, 20, 62, &
|
|
||||||
11, 17, 71, &
|
|
||||||
12, 34, 47, &
|
|
||||||
13, 68, 86, &
|
|
||||||
18, 23, 43, &
|
|
||||||
19, 64, 73, &
|
|
||||||
24, 48, 79, &
|
|
||||||
25, 70, 83, &
|
|
||||||
26, 80, 87, &
|
|
||||||
27, 32, 40, &
|
|
||||||
28, 56, 69, &
|
|
||||||
29, 63, 66, &
|
|
||||||
30, 42, 50, &
|
|
||||||
33, 37, 82, &
|
|
||||||
35, 60, 74, &
|
|
||||||
38, 55, 84, &
|
|
||||||
44, 52, 61, &
|
|
||||||
51, 53, 72, &
|
|
||||||
58, 59, 67, &
|
|
||||||
47, 56, 76, &
|
|
||||||
1, 19, 37, &
|
|
||||||
2, 61, 75, &
|
|
||||||
3, 8, 66, &
|
|
||||||
4, 60, 84, &
|
|
||||||
5, 34, 39, &
|
|
||||||
6, 26, 53, &
|
|
||||||
7, 32, 57, &
|
|
||||||
9, 52, 67, &
|
|
||||||
10, 12, 15, &
|
|
||||||
11, 51, 69, &
|
|
||||||
13, 14, 65, &
|
|
||||||
16, 31, 43, &
|
|
||||||
17, 20, 36, &
|
|
||||||
18, 80, 86, &
|
|
||||||
21, 48, 59, &
|
|
||||||
22, 40, 46, &
|
|
||||||
23, 33, 62, &
|
|
||||||
24, 30, 74, &
|
|
||||||
25, 42, 64, &
|
|
||||||
27, 49, 85, &
|
|
||||||
28, 38, 73, &
|
|
||||||
29, 44, 81, &
|
|
||||||
35, 68, 70, &
|
|
||||||
41, 63, 76, &
|
|
||||||
45, 49, 71, &
|
|
||||||
50, 58, 87, &
|
|
||||||
48, 54, 83, &
|
|
||||||
13, 55, 79, &
|
|
||||||
77, 78, 82, &
|
|
||||||
1, 2, 24, &
|
|
||||||
3, 6, 75, &
|
|
||||||
4, 56, 87, &
|
|
||||||
5, 44, 53, &
|
|
||||||
7, 50, 83, &
|
|
||||||
8, 10, 28, &
|
|
||||||
9, 55, 62, &
|
|
||||||
11, 29, 67, &
|
|
||||||
12, 33, 40, &
|
|
||||||
14, 16, 20, &
|
|
||||||
15, 35, 73, &
|
|
||||||
17, 31, 39, &
|
|
||||||
18, 36, 57, &
|
|
||||||
19, 46, 76, &
|
|
||||||
21, 42, 84, &
|
|
||||||
22, 34, 59, &
|
|
||||||
23, 26, 61, &
|
|
||||||
25, 60, 65, &
|
|
||||||
27, 64, 80, &
|
|
||||||
30, 37, 66, &
|
|
||||||
32, 45, 72, &
|
|
||||||
38, 51, 86, &
|
|
||||||
41, 77, 79, &
|
|
||||||
43, 56, 68, &
|
|
||||||
47, 74, 82, &
|
|
||||||
40, 52, 78, &
|
|
||||||
54, 61, 71, &
|
|
||||||
46, 58, 69/
|
|
||||||
|
|
||||||
data Nm/ &
|
|
||||||
1, 30, 60, 89, 118, 147, 0, &
|
|
||||||
2, 31, 61, 90, 119, 147, 0, &
|
|
||||||
3, 32, 62, 91, 120, 148, 0, &
|
|
||||||
4, 33, 63, 92, 121, 149, 0, &
|
|
||||||
2, 34, 64, 93, 122, 150, 0, &
|
|
||||||
5, 33, 65, 94, 123, 148, 0, &
|
|
||||||
6, 34, 66, 95, 124, 151, 0, &
|
|
||||||
7, 35, 67, 96, 120, 152, 0, &
|
|
||||||
8, 36, 68, 97, 125, 153, 0, &
|
|
||||||
9, 37, 69, 98, 126, 152, 0, &
|
|
||||||
10, 38, 70, 99, 127, 154, 0, &
|
|
||||||
11, 39, 71, 100, 126, 155, 0, &
|
|
||||||
12, 40, 61, 101, 128, 145, 0, &
|
|
||||||
10, 33, 60, 95, 128, 156, 0, &
|
|
||||||
13, 41, 72, 97, 126, 157, 0, &
|
|
||||||
13, 42, 73, 90, 129, 156, 0, &
|
|
||||||
14, 39, 74, 99, 130, 158, 0, &
|
|
||||||
15, 43, 75, 102, 131, 159, 0, &
|
|
||||||
16, 43, 71, 103, 118, 160, 0, &
|
|
||||||
17, 44, 76, 98, 130, 156, 0, &
|
|
||||||
18, 45, 60, 96, 132, 161, 0, &
|
|
||||||
19, 46, 73, 83, 133, 162, 0, &
|
|
||||||
12, 38, 77, 102, 134, 163, 0, &
|
|
||||||
19, 47, 78, 104, 135, 147, 0, &
|
|
||||||
1, 32, 77, 105, 136, 164, 0, &
|
|
||||||
20, 48, 73, 106, 123, 163, 0, &
|
|
||||||
21, 41, 79, 107, 137, 165, 0, &
|
|
||||||
22, 42, 66, 108, 138, 152, 0, &
|
|
||||||
18, 42, 80, 109, 139, 154, 0, &
|
|
||||||
23, 49, 81, 110, 135, 166, 0, &
|
|
||||||
16, 50, 82, 91, 129, 158, 0, &
|
|
||||||
3, 48, 63, 107, 124, 167, 0, &
|
|
||||||
6, 51, 67, 111, 134, 155, 0, &
|
|
||||||
24, 35, 77, 100, 122, 162, 0, &
|
|
||||||
20, 45, 76, 112, 140, 157, 0, &
|
|
||||||
21, 36, 64, 92, 130, 159, 0, &
|
|
||||||
8, 52, 83, 111, 118, 166, 0, &
|
|
||||||
21, 53, 84, 113, 138, 168, 0, &
|
|
||||||
25, 51, 79, 89, 122, 158, 0, &
|
|
||||||
22, 44, 75, 107, 133, 155, 172, &
|
|
||||||
9, 54, 84, 90, 141, 169, 0, &
|
|
||||||
22, 54, 85, 110, 136, 161, 0, &
|
|
||||||
8, 37, 65, 102, 129, 170, 0, &
|
|
||||||
19, 39, 85, 114, 139, 150, 0, &
|
|
||||||
26, 55, 71, 93, 142, 167, 0, &
|
|
||||||
27, 56, 65, 96, 133, 160, 174, &
|
|
||||||
28, 31, 86, 100, 117, 171, 0, &
|
|
||||||
28, 52, 70, 104, 132, 144, 0, &
|
|
||||||
24, 57, 68, 95, 137, 142, 0, &
|
|
||||||
7, 30, 72, 110, 143, 151, 0, &
|
|
||||||
4, 51, 76, 115, 127, 168, 0, &
|
|
||||||
16, 45, 87, 114, 125, 172, 0, &
|
|
||||||
15, 30, 86, 115, 123, 150, 0, &
|
|
||||||
23, 46, 64, 91, 144, 173, 0, &
|
|
||||||
23, 35, 75, 113, 145, 153, 0, &
|
|
||||||
14, 41, 87, 108, 117, 149, 170, &
|
|
||||||
25, 40, 85, 94, 124, 159, 0, &
|
|
||||||
25, 58, 69, 116, 143, 174, 0, &
|
|
||||||
29, 43, 61, 116, 132, 162, 0, &
|
|
||||||
15, 58, 88, 112, 121, 164, 0, &
|
|
||||||
4, 59, 72, 114, 119, 163, 173, &
|
|
||||||
27, 47, 86, 98, 134, 153, 0, &
|
|
||||||
5, 44, 78, 109, 141, 0, 0, &
|
|
||||||
10, 46, 69, 103, 136, 165, 0, &
|
|
||||||
9, 50, 59, 93, 128, 164, 0, &
|
|
||||||
14, 57, 58, 109, 120, 166, 0, &
|
|
||||||
17, 55, 62, 116, 125, 154, 0, &
|
|
||||||
3, 54, 70, 101, 140, 170, 0, &
|
|
||||||
1, 36, 82, 108, 127, 174, 0, &
|
|
||||||
5, 53, 81, 105, 140, 0, 0, &
|
|
||||||
29, 53, 67, 99, 142, 173, 0, &
|
|
||||||
18, 49, 74, 97, 115, 167, 0, &
|
|
||||||
2, 57, 63, 103, 138, 157, 0, &
|
|
||||||
26, 38, 79, 112, 135, 171, 0, &
|
|
||||||
11, 52, 66, 88, 119, 148, 0, &
|
|
||||||
20, 40, 68, 117, 141, 160, 0, &
|
|
||||||
11, 48, 81, 89, 146, 169, 0, &
|
|
||||||
29, 47, 80, 92, 146, 172, 0, &
|
|
||||||
6, 32, 87, 104, 145, 169, 0, &
|
|
||||||
27, 34, 74, 106, 131, 165, 0, &
|
|
||||||
12, 56, 84, 88, 139, 0, 0, &
|
|
||||||
13, 56, 62, 111, 146, 171, 0, &
|
|
||||||
26, 37, 80, 105, 144, 151, 0, &
|
|
||||||
17, 31, 82, 113, 121, 161, 0, &
|
|
||||||
28, 49, 59, 94, 137, 0, 0, &
|
|
||||||
7, 55, 83, 101, 131, 168, 0, &
|
|
||||||
24, 50, 78, 106, 143, 149, 0/
|
|
||||||
|
|
||||||
data nrw/ &
|
|
||||||
6,6,6,6,6,6,6,6,6,6, &
|
|
||||||
6,6,6,6,6,6,6,6,6,6, &
|
|
||||||
6,6,6,6,6,6,6,6,6,6, &
|
|
||||||
6,6,6,6,6,6,6,6,6,7, &
|
|
||||||
6,6,6,6,6,7,6,6,6,6, &
|
|
||||||
6,6,6,6,6,7,6,6,6,6, &
|
|
||||||
7,6,5,6,6,6,6,6,6,5, &
|
|
||||||
6,6,6,6,6,6,6,6,6,6, &
|
|
||||||
5,6,6,6,5,6,6/
|
|
||||||
|
|
||||||
ncw=3
|
|
||||||
|
|
||||||
decoded=0
|
|
||||||
toc=0
|
|
||||||
tov=0
|
|
||||||
tanhtoc=0
|
|
||||||
! initialize messages to checks
|
|
||||||
do j=1,M
|
|
||||||
do i=1,nrw(j)
|
|
||||||
toc(i,j)=llr((Nm(i,j)))
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
ncnt=0
|
|
||||||
|
|
||||||
do iter=0,maxiterations
|
|
||||||
|
|
||||||
! Update bit log likelihood ratios (tov=0 in iteration 0).
|
|
||||||
do i=1,N
|
|
||||||
if( apmask(i) .ne. 1 ) then
|
|
||||||
zn(i)=llr(i)+sum(tov(1:ncw,i))
|
|
||||||
else
|
|
||||||
zn(i)=llr(i)
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
|
|
||||||
! Check to see if we have a codeword (check before we do any iteration).
|
|
||||||
cw=0
|
|
||||||
where( zn .gt. 0. ) cw=1
|
|
||||||
ncheck=0
|
|
||||||
do i=1,M
|
|
||||||
synd(i)=sum(cw(Nm(1:nrw(i),i)))
|
|
||||||
if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1
|
|
||||||
! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied'
|
|
||||||
enddo
|
|
||||||
! write(*,*) 'number of unsatisfied parity checks ',ncheck
|
|
||||||
if( ncheck .eq. 0 ) then ! we have a codeword - reorder the columns and return it
|
|
||||||
codeword=cw(colorder+1)
|
|
||||||
decoded=codeword(M+1:N)
|
|
||||||
nerr=0
|
|
||||||
do i=1,N
|
|
||||||
if( (2*cw(i)-1)*llr(i) .lt. 0.0 ) nerr=nerr+1
|
|
||||||
enddo
|
|
||||||
nharderror=nerr
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if( iter.gt.0 ) then ! this code block implements an early stopping criterion
|
|
||||||
! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion
|
|
||||||
nd=ncheck-nclast
|
|
||||||
if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased
|
|
||||||
ncnt=0 ! reset counter
|
|
||||||
else
|
|
||||||
ncnt=ncnt+1
|
|
||||||
endif
|
|
||||||
! write(*,*) iter,ncheck,nd,ncnt
|
|
||||||
if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then
|
|
||||||
nharderror=-1
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
nclast=ncheck
|
|
||||||
|
|
||||||
! Send messages from bits to check nodes
|
|
||||||
do j=1,M
|
|
||||||
do i=1,nrw(j)
|
|
||||||
ibj=Nm(i,j)
|
|
||||||
toc(i,j)=zn(ibj)
|
|
||||||
do kk=1,ncw ! subtract off what the bit had received from the check
|
|
||||||
if( Mn(kk,ibj) .eq. j ) then
|
|
||||||
toc(i,j)=toc(i,j)-tov(kk,ibj)
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
! send messages from check nodes to variable nodes
|
|
||||||
do i=1,M
|
|
||||||
tanhtoc(1:7,i)=tanh(-toc(1:7,i)/2)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
do j=1,N
|
|
||||||
do i=1,ncw
|
|
||||||
ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j
|
|
||||||
Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j)
|
|
||||||
call platanh(-Tmn,y)
|
|
||||||
! y=atanh(-Tmn)
|
|
||||||
tov(i,j)=2*y
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
enddo
|
|
||||||
nharderror=-1
|
|
||||||
return
|
|
||||||
end subroutine bpdecode174
|
|
@ -1,24 +0,0 @@
|
|||||||
subroutine chkcrc12a(decoded,nbadcrc)
|
|
||||||
|
|
||||||
use crc
|
|
||||||
integer*1 decoded(87)
|
|
||||||
integer*1, target:: i1Dec8BitBytes(11)
|
|
||||||
character*87 cbits
|
|
||||||
|
|
||||||
! Write decoded bits into cbits: 75-bit message plus 12-bit CRC
|
|
||||||
write(cbits,1000) decoded
|
|
||||||
1000 format(87i1)
|
|
||||||
read(cbits,1001) i1Dec8BitBytes
|
|
||||||
1001 format(11b8)
|
|
||||||
read(cbits,1002) ncrc12 !Received CRC12
|
|
||||||
1002 format(75x,b12)
|
|
||||||
|
|
||||||
i1Dec8BitBytes(10)=iand(i1Dec8BitBytes(10),128+64+32)
|
|
||||||
i1Dec8BitBytes(11)=0
|
|
||||||
icrc12=crc12(c_loc(i1Dec8BitBytes),11) !CRC12 computed from 75 msg bits
|
|
||||||
|
|
||||||
nbadcrc=1
|
|
||||||
if(ncrc12.eq.icrc12) nbadcrc=0
|
|
||||||
|
|
||||||
return
|
|
||||||
end subroutine chkcrc12a
|
|
@ -20,7 +20,6 @@ subroutine foxgen()
|
|||||||
character*37 msg,msgsent
|
character*37 msg,msgsent
|
||||||
integer itone(79)
|
integer itone(79)
|
||||||
integer*1 msgbits(77),msgbits2
|
integer*1 msgbits(77),msgbits2
|
||||||
integer*1, target:: i1Msg8BitBytes(11)
|
|
||||||
integer*1, target:: mycall
|
integer*1, target:: mycall
|
||||||
real x(NFFT)
|
real x(NFFT)
|
||||||
real*8 dt,twopi,f0,fstep,dfreq,phi,dphi
|
real*8 dt,twopi,f0,fstep,dfreq,phi,dphi
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
! LDPC (174,87) code
|
! LDPC (174,91) code
|
||||||
parameter (KK=87) !Information bits (75 + CRC12)
|
parameter (KK=91) !Information bits (77 + CRC14)
|
||||||
parameter (ND=58) !Data symbols
|
parameter (ND=58) !Data symbols
|
||||||
parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
|
parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
|
||||||
parameter (NN=NS+ND) !Total channel symbols (79)
|
parameter (NN=NS+ND) !Total channel symbols (79)
|
||||||
|
@ -4,7 +4,6 @@ subroutine ft8apset(mycall12,hiscall12,apsym)
|
|||||||
character*37 msg
|
character*37 msg
|
||||||
character*12 mycall12,hiscall12,hiscall
|
character*12 mycall12,hiscall12,hiscall
|
||||||
integer apsym(58)
|
integer apsym(58)
|
||||||
integer*1 msgbits(77)
|
|
||||||
logical nohiscall
|
logical nohiscall
|
||||||
|
|
||||||
if(len(trim(mycall12)).eq.0) then
|
if(len(trim(mycall12)).eq.0) then
|
||||||
@ -30,10 +29,10 @@ subroutine ft8apset(mycall12,hiscall12,apsym)
|
|||||||
apsym(1)=99
|
apsym(1)=99
|
||||||
apsym(30)=99
|
apsym(30)=99
|
||||||
return
|
return
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
read(c77,'(58i1)',err=1) apsym(1:58)
|
read(c77,'(58i1)',err=1) apsym(1:58)
|
||||||
|
apsym=2*apsym-1
|
||||||
if(nohiscall) apsym(30)=99
|
if(nohiscall) apsym(30)=99
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -7,30 +7,25 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
|||||||
use packjt77
|
use packjt77
|
||||||
include 'ft8_params.f90'
|
include 'ft8_params.f90'
|
||||||
parameter(NP2=2812)
|
parameter(NP2=2812)
|
||||||
character*37 msg37,msgsent37
|
character*37 msg37
|
||||||
character*12 mycall12,hiscall12,hiscall12_0
|
character*12 mycall12,hiscall12,hiscall12_0
|
||||||
character*77 c77
|
character*77 c77
|
||||||
character*6 mycall6,hiscall6,c1,c2
|
|
||||||
character*13 c13
|
character*13 c13
|
||||||
character*87 cbits
|
|
||||||
real a(5)
|
real a(5)
|
||||||
real s8(0:7,NN)
|
real s8(0:7,NN)
|
||||||
real s2(0:511),s2l(0:511)
|
real s2(0:511),s2l(0:511)
|
||||||
real bmeta(174),bmetb(174),bmetc(174)
|
real bmeta(174),bmetb(174),bmetc(174)
|
||||||
real bmetal(174),bmetbl(174),bmetcl(174)
|
|
||||||
real llra(174),llrb(174),llrc(174),llrd(174) !Soft symbols
|
real llra(174),llrb(174),llrc(174),llrd(174) !Soft symbols
|
||||||
real llral(174),llrbl(174),llrcl(174) !Soft symbols
|
|
||||||
real dd0(15*12000)
|
real dd0(15*12000)
|
||||||
integer*1 message77(77),apmask(174),cw(174)
|
integer*1 message77(77),apmask(174),cw(174)
|
||||||
integer apsym(58)
|
integer apsym(58)
|
||||||
integer mcq(29),mcqru(29),mcqfd(29),mcqtest(29),mcqhund(29)
|
integer mcq(29),mcqru(29),mcqfd(29),mcqtest(29)
|
||||||
integer mrrr(19),m73(19),mrr73(19)
|
integer mrrr(19),m73(19),mrr73(19)
|
||||||
integer itone(NN)
|
integer itone(NN)
|
||||||
integer icos7(0:6),ip(1)
|
integer icos7(0:6),ip(1)
|
||||||
integer nappasses(0:5) !Number of decoding passes to use for each QSO state
|
integer nappasses(0:5) !Number of decoding passes to use for each QSO state
|
||||||
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
|
integer naptypes(0:5,4) ! (nQSOProgress, decoding pass) maximum of 4 passes for now
|
||||||
integer ncontest,ncontest0
|
integer ncontest,ncontest0
|
||||||
integer*1, target:: i1hiscall(12)
|
|
||||||
logical one(0:511,0:8)
|
logical one(0:511,0:8)
|
||||||
integer graymap(0:7)
|
integer graymap(0:7)
|
||||||
complex cd0(0:3199)
|
complex cd0(0:3199)
|
||||||
@ -43,7 +38,6 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
|||||||
data mcqru/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0/
|
data mcqru/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,1,1,0,0/
|
||||||
data mcqfd/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0/
|
data mcqfd/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0/
|
||||||
data mcqtest/0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0/
|
data mcqtest/0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,0,1,0/
|
||||||
data mcqhund/0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1,0,0,1,1,1,0,0/
|
|
||||||
data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/
|
data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/
|
||||||
data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/
|
data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/
|
||||||
data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/
|
data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/
|
||||||
@ -57,7 +51,6 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
|||||||
mcqfd=2*mcqfd-1
|
mcqfd=2*mcqfd-1
|
||||||
mcqru=2*mcqru-1
|
mcqru=2*mcqru-1
|
||||||
mcqtest=2*mcqtest-1
|
mcqtest=2*mcqtest-1
|
||||||
mcqhund=2*mcqhund-1
|
|
||||||
mrrr=2*mrrr-1
|
mrrr=2*mrrr-1
|
||||||
m73=2*m73-1
|
m73=2*m73-1
|
||||||
mrr73=2*mrr73-1
|
mrr73=2*mrr73-1
|
||||||
@ -205,37 +198,26 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
|||||||
do ib=0,ibmax
|
do ib=0,ibmax
|
||||||
bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - &
|
bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - &
|
||||||
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib))
|
maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib))
|
||||||
! bml=maxval(s2l(0:nt-1),one(0:nt-1,ibmax-ib)) - &
|
|
||||||
! maxval(s2l(0:nt-1),.not.one(0:nt-1,ibmax-ib))
|
|
||||||
if(i32+ib .gt.174) cycle
|
if(i32+ib .gt.174) cycle
|
||||||
if(nsym.eq.1) then
|
if(nsym.eq.1) then
|
||||||
bmeta(i32+ib)=bm
|
bmeta(i32+ib)=bm
|
||||||
! bmetal(i32+ib)=bml
|
|
||||||
elseif(nsym.eq.2) then
|
elseif(nsym.eq.2) then
|
||||||
bmetb(i32+ib)=bm
|
bmetb(i32+ib)=bm
|
||||||
! bmetbl(i32+ib)=bml
|
|
||||||
elseif(nsym.eq.3) then
|
elseif(nsym.eq.3) then
|
||||||
bmetc(i32+ib)=bm
|
bmetc(i32+ib)=bm
|
||||||
! bmetcl(i32+ib)=bml
|
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
enddo
|
enddo
|
||||||
call normalizebmet(bmeta,174)
|
call normalizebmet(bmeta,174)
|
||||||
! call normalizebmet(bmetal,174)
|
|
||||||
call normalizebmet(bmetb,174)
|
call normalizebmet(bmetb,174)
|
||||||
! call normalizebmet(bmetbl,174)
|
|
||||||
call normalizebmet(bmetc,174)
|
call normalizebmet(bmetc,174)
|
||||||
! call normalizebmet(bmetcl,174)
|
|
||||||
|
|
||||||
scalefac=2.83
|
scalefac=2.83
|
||||||
llra=scalefac*bmeta
|
llra=scalefac*bmeta
|
||||||
! llral=scalefac*bmetal
|
|
||||||
llrb=scalefac*bmetb
|
llrb=scalefac*bmetb
|
||||||
! llrbl=scalefac*bmetbl
|
|
||||||
llrc=scalefac*bmetc
|
llrc=scalefac*bmetc
|
||||||
! llrcl=scalefac*bmetcl
|
|
||||||
|
|
||||||
apmag=maxval(abs(llra))*1.01
|
apmag=maxval(abs(llra))*1.01
|
||||||
|
|
||||||
@ -290,7 +272,6 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
|||||||
if(ncontest.eq.6.and.f1.gt.950.0) cycle ! Hounds use AP only for signals below 950 Hz
|
if(ncontest.eq.6.and.f1.gt.950.0) cycle ! Hounds use AP only for signals below 950 Hz
|
||||||
if(iaptype.ge.2 .and. apsym(1).gt.1) cycle ! No, or nonstandard, mycall
|
if(iaptype.ge.2 .and. apsym(1).gt.1) cycle ! No, or nonstandard, mycall
|
||||||
if(iaptype.ge.3 .and. apsym(30).gt.1) cycle ! No, or nonstandard, dxcall
|
if(iaptype.ge.3 .and. apsym(30).gt.1) cycle ! No, or nonstandard, dxcall
|
||||||
apsym=2*apsym-1 ! Change from [0,1] to antipodal
|
|
||||||
|
|
||||||
if(iaptype.eq.1) then ! CQ or CQ RU or CQ TEST or CQ FD
|
if(iaptype.eq.1) then ! CQ or CQ RU or CQ TEST or CQ FD
|
||||||
apmask=0
|
apmask=0
|
||||||
@ -300,7 +281,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, &
|
|||||||
if(ncontest.eq.2) llrd(1:29)=apmag*mcqtest(1:29)
|
if(ncontest.eq.2) llrd(1:29)=apmag*mcqtest(1:29)
|
||||||
if(ncontest.eq.3) llrd(1:29)=apmag*mcqfd(1:29)
|
if(ncontest.eq.3) llrd(1:29)=apmag*mcqfd(1:29)
|
||||||
if(ncontest.eq.4) llrd(1:29)=apmag*mcqru(1:29)
|
if(ncontest.eq.4) llrd(1:29)=apmag*mcqru(1:29)
|
||||||
if(ncontest.eq.6) llrd(1:29)=apmag*mcqhund(1:29)
|
if(ncontest.eq.6) llrd(1:29)=apmag*mcq(1:29)
|
||||||
apmask(75:77)=1
|
apmask(75:77)=1
|
||||||
llrd(75:76)=apmag*(-1)
|
llrd(75:76)=apmag*(-1)
|
||||||
llrd(77)=apmag*(+1)
|
llrd(77)=apmag*(+1)
|
||||||
|
@ -8,14 +8,11 @@ program ft8code
|
|||||||
include 'ft8_testmsg.f90'
|
include 'ft8_testmsg.f90'
|
||||||
parameter (NWAVE=NN*NSPS)
|
parameter (NWAVE=NN*NSPS)
|
||||||
|
|
||||||
character*77 c77
|
|
||||||
character*37 msg,msgsent
|
character*37 msg,msgsent
|
||||||
character*9 comment
|
character*9 comment
|
||||||
character bad*1,msgtype*16
|
character bad*1,msgtype*18
|
||||||
character*91 cbits
|
|
||||||
integer itone(NN)
|
integer itone(NN)
|
||||||
integer*1 msgbits(77)
|
integer*1 msgbits(77)
|
||||||
logical unpk77_success
|
|
||||||
|
|
||||||
! Get command-line argument(s)
|
! Get command-line argument(s)
|
||||||
nargs=iargc()
|
nargs=iargc()
|
||||||
@ -69,10 +66,10 @@ program ft8code
|
|||||||
if(msg.ne.msgsent) bad="*"
|
if(msg.ne.msgsent) bad="*"
|
||||||
if(n3.ge.0) then
|
if(n3.ge.0) then
|
||||||
write(*,1020) imsg,msg,msgsent,bad,i3,n3,msgtype,comment
|
write(*,1020) imsg,msg,msgsent,bad,i3,n3,msgtype,comment
|
||||||
1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a16,1x,a9)
|
1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a18,1x,a9)
|
||||||
else
|
else
|
||||||
write(*,1022) imsg,msg,msgsent,bad,i3,msgtype,comment
|
write(*,1022) imsg,msg,msgsent,bad,i3,msgtype,comment
|
||||||
1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a16,1x,a9)
|
1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a18,1x,a9)
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ program ft8sim
|
|||||||
parameter (NWAVE=NN*NSPS)
|
parameter (NWAVE=NN*NSPS)
|
||||||
type(hdr) h !Header for .wav file
|
type(hdr) h !Header for .wav file
|
||||||
character arg*12,fname*17
|
character arg*12,fname*17
|
||||||
character msg37*37,msgsent37*37,msg40*40
|
character msg37*37,msgsent37*37
|
||||||
character c77*77
|
character c77*77
|
||||||
complex c0(0:NMAX-1)
|
complex c0(0:NMAX-1)
|
||||||
complex c(0:NMAX-1)
|
complex c(0:NMAX-1)
|
||||||
@ -108,7 +108,6 @@ program ft8sim
|
|||||||
ib=k
|
ib=k
|
||||||
wave=real(c)
|
wave=real(c)
|
||||||
peak=maxval(abs(wave(ia:ib)))
|
peak=maxval(abs(wave(ia:ib)))
|
||||||
rms=sqrt(dot_product(wave(ia:ib),wave(ia:ib))/NWAVE)
|
|
||||||
nslots=1
|
nslots=1
|
||||||
if(width.gt.0.0) call filt8(f0,nslots,width,wave)
|
if(width.gt.0.0) call filt8(f0,nslots,width,wave)
|
||||||
|
|
||||||
@ -119,10 +118,16 @@ program ft8sim
|
|||||||
enddo
|
enddo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
fac=32767.0
|
gain=100.0
|
||||||
rms=100.0
|
if(snrdb.lt.90.0) then
|
||||||
if(snrdb.ge.90.0) iwave(1:NMAX)=nint(fac*wave)
|
wave=gain*wave
|
||||||
if(snrdb.lt.90.0) iwave(1:NMAX)=nint(rms*wave)
|
else
|
||||||
|
datpk=maxval(abs(wave))
|
||||||
|
fac=32766.9/datpk
|
||||||
|
wave=fac*wave
|
||||||
|
endif
|
||||||
|
if(any(abs(wave).gt.32767.0)) print*,"Warning - data will be clipped."
|
||||||
|
iwave=nint(wave)
|
||||||
|
|
||||||
h=default_header(12000,NMAX)
|
h=default_header(12000,NMAX)
|
||||||
write(fname,1102) ifile
|
write(fname,1102) ifile
|
||||||
|
@ -19,8 +19,11 @@ subroutine genft8(msg,i3,n3,msgsent,msgbits,itone)
|
|||||||
call pack77(msg,i3,n3,c77)
|
call pack77(msg,i3,n3,c77)
|
||||||
call unpack77(c77,msgsent,unpk77_success)
|
call unpack77(c77,msgsent,unpk77_success)
|
||||||
read(c77,'(77i1)',err=1) msgbits
|
read(c77,'(77i1)',err=1) msgbits
|
||||||
go to 2
|
if(unpk77_success) go to 2
|
||||||
1 write(81,*) msg,c77 ; flush(81)
|
1 msgbits=0
|
||||||
|
itone=0
|
||||||
|
msgsent='*** bad message *** '
|
||||||
|
go to 900
|
||||||
|
|
||||||
entry get_tones_from_77bits(msgbits,itone)
|
entry get_tones_from_77bits(msgbits,itone)
|
||||||
|
|
||||||
@ -39,5 +42,5 @@ entry get_tones_from_77bits(msgbits,itone)
|
|||||||
itone(k)=graymap(indx)
|
itone(k)=graymap(indx)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
return
|
900 return
|
||||||
end subroutine genft8
|
end subroutine genft8
|
||||||
|
@ -1,365 +0,0 @@
|
|||||||
subroutine osd174(llr,apmask,ndeep,decoded,cw,nhardmin,dmin)
|
|
||||||
!
|
|
||||||
! An ordered-statistics decoder for the (174,87) code.
|
|
||||||
!
|
|
||||||
include "ldpc_174_87_params.f90"
|
|
||||||
|
|
||||||
integer*1 apmask(N),apmaskr(N)
|
|
||||||
integer*1 gen(K,N)
|
|
||||||
integer*1 genmrb(K,N),g2(N,K)
|
|
||||||
integer*1 temp(K),m0(K),me(K),mi(K),misub(K),e2sub(N-K),e2(N-K),ui(N-K)
|
|
||||||
integer*1 r2pat(N-K)
|
|
||||||
integer indices(N),nxor(N)
|
|
||||||
integer*1 cw(N),ce(N),c0(N),hdec(N)
|
|
||||||
integer*1 decoded(K)
|
|
||||||
integer indx(N)
|
|
||||||
real llr(N),rx(N),absrx(N)
|
|
||||||
logical first,reset
|
|
||||||
data first/.true./
|
|
||||||
save first,gen
|
|
||||||
|
|
||||||
if( first ) then ! fill the generator matrix
|
|
||||||
gen=0
|
|
||||||
do i=1,M
|
|
||||||
do j=1,22
|
|
||||||
read(g(i)(j:j),"(Z1)") istr
|
|
||||||
do jj=1, 4
|
|
||||||
irow=(j-1)*4+jj
|
|
||||||
if( btest(istr,4-jj) ) gen(irow,i)=1
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
do irow=1,K
|
|
||||||
gen(irow,M+irow)=1
|
|
||||||
enddo
|
|
||||||
first=.false.
|
|
||||||
endif
|
|
||||||
|
|
||||||
! Re-order received vector to place systematic msg bits at the end.
|
|
||||||
rx=llr(colorder+1)
|
|
||||||
apmaskr=apmask(colorder+1)
|
|
||||||
|
|
||||||
! Hard decisions on the received word.
|
|
||||||
hdec=0
|
|
||||||
where(rx .ge. 0) hdec=1
|
|
||||||
|
|
||||||
! Use magnitude of received symbols as a measure of reliability.
|
|
||||||
absrx=abs(rx)
|
|
||||||
call indexx(absrx,N,indx)
|
|
||||||
|
|
||||||
! Re-order the columns of the generator matrix in order of decreasing reliability.
|
|
||||||
do i=1,N
|
|
||||||
genmrb(1:K,i)=gen(1:K,indx(N+1-i))
|
|
||||||
indices(i)=indx(N+1-i)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
! Do gaussian elimination to create a generator matrix with the most reliable
|
|
||||||
! received bits in positions 1:K in order of decreasing reliability (more or less).
|
|
||||||
do id=1,K ! diagonal element indices
|
|
||||||
do icol=id,K+20 ! The 20 is ad hoc - beware
|
|
||||||
iflag=0
|
|
||||||
if( genmrb(id,icol) .eq. 1 ) then
|
|
||||||
iflag=1
|
|
||||||
if( icol .ne. id ) then ! reorder column
|
|
||||||
temp(1:K)=genmrb(1:K,id)
|
|
||||||
genmrb(1:K,id)=genmrb(1:K,icol)
|
|
||||||
genmrb(1:K,icol)=temp(1:K)
|
|
||||||
itmp=indices(id)
|
|
||||||
indices(id)=indices(icol)
|
|
||||||
indices(icol)=itmp
|
|
||||||
endif
|
|
||||||
do ii=1,K
|
|
||||||
if( ii .ne. id .and. genmrb(ii,id) .eq. 1 ) then
|
|
||||||
genmrb(ii,1:N)=ieor(genmrb(ii,1:N),genmrb(id,1:N))
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
g2=transpose(genmrb)
|
|
||||||
|
|
||||||
! The hard decisions for the K MRB bits define the order 0 message, m0.
|
|
||||||
! Encode m0 using the modified generator matrix to find the "order 0" codeword.
|
|
||||||
! Flip various combinations of bits in m0 and re-encode to generate a list of
|
|
||||||
! codewords. Return the member of the list that has the smallest Euclidean
|
|
||||||
! distance to the received word.
|
|
||||||
|
|
||||||
hdec=hdec(indices) ! hard decisions from received symbols
|
|
||||||
m0=hdec(1:K) ! zero'th order message
|
|
||||||
absrx=absrx(indices)
|
|
||||||
rx=rx(indices)
|
|
||||||
apmaskr=apmaskr(indices)
|
|
||||||
|
|
||||||
call mrbencode(m0,c0,g2,N,K)
|
|
||||||
nxor=ieor(c0,hdec)
|
|
||||||
nhardmin=sum(nxor)
|
|
||||||
dmin=sum(nxor*absrx)
|
|
||||||
|
|
||||||
cw=c0
|
|
||||||
ntotal=0
|
|
||||||
nrejected=0
|
|
||||||
|
|
||||||
if(ndeep.eq.0) goto 998 ! norder=0
|
|
||||||
if(ndeep.gt.5) ndeep=5
|
|
||||||
if( ndeep.eq. 1) then
|
|
||||||
nord=1
|
|
||||||
npre1=0
|
|
||||||
npre2=0
|
|
||||||
nt=40
|
|
||||||
ntheta=12
|
|
||||||
elseif(ndeep.eq.2) then
|
|
||||||
nord=1
|
|
||||||
npre1=1
|
|
||||||
npre2=0
|
|
||||||
nt=40
|
|
||||||
ntheta=12
|
|
||||||
elseif(ndeep.eq.3) then
|
|
||||||
nord=1
|
|
||||||
npre1=1
|
|
||||||
npre2=1
|
|
||||||
nt=40
|
|
||||||
ntheta=12
|
|
||||||
ntau=14
|
|
||||||
elseif(ndeep.eq.4) then
|
|
||||||
nord=2
|
|
||||||
npre1=1
|
|
||||||
npre2=0
|
|
||||||
nt=40
|
|
||||||
ntheta=12
|
|
||||||
ntau=19
|
|
||||||
elseif(ndeep.eq.5) then
|
|
||||||
nord=2
|
|
||||||
npre1=1
|
|
||||||
npre2=1
|
|
||||||
nt=40
|
|
||||||
ntheta=12
|
|
||||||
ntau=19
|
|
||||||
endif
|
|
||||||
|
|
||||||
do iorder=1,nord
|
|
||||||
misub(1:K-iorder)=0
|
|
||||||
misub(K-iorder+1:K)=1
|
|
||||||
iflag=K-iorder+1
|
|
||||||
do while(iflag .ge.0)
|
|
||||||
if(iorder.eq.nord .and. npre1.eq.0) then
|
|
||||||
iend=iflag
|
|
||||||
else
|
|
||||||
iend=1
|
|
||||||
endif
|
|
||||||
do n1=iflag,iend,-1
|
|
||||||
mi=misub
|
|
||||||
mi(n1)=1
|
|
||||||
if(any(iand(apmaskr(1:K),mi).eq.1)) cycle
|
|
||||||
ntotal=ntotal+1
|
|
||||||
me=ieor(m0,mi)
|
|
||||||
if(n1.eq.iflag) then
|
|
||||||
call mrbencode(me,ce,g2,N,K)
|
|
||||||
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
|
|
||||||
e2=e2sub
|
|
||||||
nd1Kpt=sum(e2sub(1:nt))+1
|
|
||||||
d1=sum(ieor(me(1:K),hdec(1:K))*absrx(1:K))
|
|
||||||
else
|
|
||||||
e2=ieor(e2sub,g2(K+1:N,n1))
|
|
||||||
nd1Kpt=sum(e2(1:nt))+2
|
|
||||||
endif
|
|
||||||
if(nd1Kpt .le. ntheta) then
|
|
||||||
call mrbencode(me,ce,g2,N,K)
|
|
||||||
nxor=ieor(ce,hdec)
|
|
||||||
if(n1.eq.iflag) then
|
|
||||||
dd=d1+sum(e2sub*absrx(K+1:N))
|
|
||||||
else
|
|
||||||
dd=d1+ieor(ce(n1),hdec(n1))*absrx(n1)+sum(e2*absrx(K+1:N))
|
|
||||||
endif
|
|
||||||
if( dd .lt. dmin ) then
|
|
||||||
dmin=dd
|
|
||||||
cw=ce
|
|
||||||
nhardmin=sum(nxor)
|
|
||||||
nd1Kptbest=nd1Kpt
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
nrejected=nrejected+1
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
! Get the next test error pattern, iflag will go negative
|
|
||||||
! when the last pattern with weight iorder has been generated.
|
|
||||||
call nextpat(misub,k,iorder,iflag)
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
if(npre2.eq.1) then
|
|
||||||
reset=.true.
|
|
||||||
ntotal=0
|
|
||||||
do i1=K,1,-1
|
|
||||||
do i2=i1-1,1,-1
|
|
||||||
ntotal=ntotal+1
|
|
||||||
mi(1:ntau)=ieor(g2(K+1:K+ntau,i1),g2(K+1:K+ntau,i2))
|
|
||||||
call boxit(reset,mi(1:ntau),ntau,ntotal,i1,i2)
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
ncount2=0
|
|
||||||
ntotal2=0
|
|
||||||
reset=.true.
|
|
||||||
! Now run through again and do the second pre-processing rule
|
|
||||||
misub(1:K-nord)=0
|
|
||||||
misub(K-nord+1:K)=1
|
|
||||||
iflag=K-nord+1
|
|
||||||
do while(iflag .ge.0)
|
|
||||||
me=ieor(m0,misub)
|
|
||||||
call mrbencode(me,ce,g2,N,K)
|
|
||||||
e2sub=ieor(ce(K+1:N),hdec(K+1:N))
|
|
||||||
do i2=0,ntau
|
|
||||||
ntotal2=ntotal2+1
|
|
||||||
ui=0
|
|
||||||
if(i2.gt.0) ui(i2)=1
|
|
||||||
r2pat=ieor(e2sub,ui)
|
|
||||||
778 continue
|
|
||||||
call fetchit(reset,r2pat(1:ntau),ntau,in1,in2)
|
|
||||||
if(in1.gt.0.and.in2.gt.0) then
|
|
||||||
ncount2=ncount2+1
|
|
||||||
mi=misub
|
|
||||||
mi(in1)=1
|
|
||||||
mi(in2)=1
|
|
||||||
if(sum(mi).lt.nord+npre1+npre2.or.any(iand(apmaskr(1:K),mi).eq.1)) cycle
|
|
||||||
me=ieor(m0,mi)
|
|
||||||
call mrbencode(me,ce,g2,N,K)
|
|
||||||
nxor=ieor(ce,hdec)
|
|
||||||
dd=sum(nxor*absrx)
|
|
||||||
if( dd .lt. dmin ) then
|
|
||||||
dmin=dd
|
|
||||||
cw=ce
|
|
||||||
nhardmin=sum(nxor)
|
|
||||||
endif
|
|
||||||
goto 778
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
call nextpat(misub,K,nord,iflag)
|
|
||||||
enddo
|
|
||||||
endif
|
|
||||||
|
|
||||||
998 continue
|
|
||||||
! Re-order the codeword to place message bits at the end.
|
|
||||||
cw(indices)=cw
|
|
||||||
hdec(indices)=hdec
|
|
||||||
decoded=cw(M+1:N)
|
|
||||||
cw(colorder+1)=cw ! put the codeword back into received-word order
|
|
||||||
return
|
|
||||||
end subroutine osd174
|
|
||||||
|
|
||||||
subroutine mrbencode(me,codeword,g2,N,K)
|
|
||||||
integer*1 me(K),codeword(N),g2(N,K)
|
|
||||||
! fast encoding for low-weight test patterns
|
|
||||||
codeword=0
|
|
||||||
do i=1,K
|
|
||||||
if( me(i) .eq. 1 ) then
|
|
||||||
codeword=ieor(codeword,g2(1:N,i))
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
return
|
|
||||||
end subroutine mrbencode
|
|
||||||
|
|
||||||
subroutine nextpat(mi,k,iorder,iflag)
|
|
||||||
integer*1 mi(k),ms(k)
|
|
||||||
! generate the next test error pattern
|
|
||||||
ind=-1
|
|
||||||
do i=1,k-1
|
|
||||||
if( mi(i).eq.0 .and. mi(i+1).eq.1) ind=i
|
|
||||||
enddo
|
|
||||||
if( ind .lt. 0 ) then ! no more patterns of this order
|
|
||||||
iflag=ind
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
ms=0
|
|
||||||
ms(1:ind-1)=mi(1:ind-1)
|
|
||||||
ms(ind)=1
|
|
||||||
ms(ind+1)=0
|
|
||||||
if( ind+1 .lt. k ) then
|
|
||||||
nz=iorder-sum(ms)
|
|
||||||
ms(k-nz+1:k)=1
|
|
||||||
endif
|
|
||||||
mi=ms
|
|
||||||
do i=1,k ! iflag will point to the lowest-index 1 in mi
|
|
||||||
if(mi(i).eq.1) then
|
|
||||||
iflag=i
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
return
|
|
||||||
end subroutine nextpat
|
|
||||||
|
|
||||||
subroutine boxit(reset,e2,ntau,npindex,i1,i2)
|
|
||||||
integer*1 e2(1:ntau)
|
|
||||||
integer indexes(4000,2),fp(0:525000),np(4000)
|
|
||||||
logical reset
|
|
||||||
common/boxes/indexes,fp,np
|
|
||||||
|
|
||||||
if(reset) then
|
|
||||||
patterns=-1
|
|
||||||
fp=-1
|
|
||||||
np=-1
|
|
||||||
sc=-1
|
|
||||||
indexes=-1
|
|
||||||
reset=.false.
|
|
||||||
endif
|
|
||||||
|
|
||||||
indexes(npindex,1)=i1
|
|
||||||
indexes(npindex,2)=i2
|
|
||||||
ipat=0
|
|
||||||
do i=1,ntau
|
|
||||||
if(e2(i).eq.1) then
|
|
||||||
ipat=ipat+ishft(1,ntau-i)
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
|
|
||||||
ip=fp(ipat) ! see what's currently stored in fp(ipat)
|
|
||||||
if(ip.eq.-1) then
|
|
||||||
fp(ipat)=npindex
|
|
||||||
else
|
|
||||||
do while (np(ip).ne.-1)
|
|
||||||
ip=np(ip)
|
|
||||||
enddo
|
|
||||||
np(ip)=npindex
|
|
||||||
endif
|
|
||||||
return
|
|
||||||
end subroutine boxit
|
|
||||||
|
|
||||||
subroutine fetchit(reset,e2,ntau,i1,i2)
|
|
||||||
integer indexes(4000,2),fp(0:525000),np(4000)
|
|
||||||
integer lastpat
|
|
||||||
integer*1 e2(ntau)
|
|
||||||
logical reset
|
|
||||||
common/boxes/indexes,fp,np
|
|
||||||
save lastpat,inext
|
|
||||||
|
|
||||||
if(reset) then
|
|
||||||
lastpat=-1
|
|
||||||
reset=.false.
|
|
||||||
endif
|
|
||||||
|
|
||||||
ipat=0
|
|
||||||
do i=1,ntau
|
|
||||||
if(e2(i).eq.1) then
|
|
||||||
ipat=ipat+ishft(1,ntau-i)
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
index=fp(ipat)
|
|
||||||
|
|
||||||
if(lastpat.ne.ipat .and. index.gt.0) then ! return first set of indices
|
|
||||||
i1=indexes(index,1)
|
|
||||||
i2=indexes(index,2)
|
|
||||||
inext=np(index)
|
|
||||||
elseif(lastpat.eq.ipat .and. inext.gt.0) then
|
|
||||||
i1=indexes(inext,1)
|
|
||||||
i2=indexes(inext,2)
|
|
||||||
inext=np(inext)
|
|
||||||
else
|
|
||||||
i1=-1
|
|
||||||
i2=-1
|
|
||||||
inext=-1
|
|
||||||
endif
|
|
||||||
lastpat=ipat
|
|
||||||
return
|
|
||||||
end subroutine fetchit
|
|
||||||
|
|
@ -44,7 +44,6 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,maxcand,s,candidate, &
|
|||||||
nssy=NSPS/NSTEP ! # steps per symbol
|
nssy=NSPS/NSTEP ! # steps per symbol
|
||||||
nfos=NFFT1/NSPS ! # frequency bin oversampling factor
|
nfos=NFFT1/NSPS ! # frequency bin oversampling factor
|
||||||
jstrt=0.5/tstep
|
jstrt=0.5/tstep
|
||||||
|
|
||||||
candidate0=0.
|
candidate0=0.
|
||||||
k=0
|
k=0
|
||||||
|
|
||||||
@ -133,7 +132,8 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,maxcand,s,candidate, &
|
|||||||
j=indx(i)
|
j=indx(i)
|
||||||
! if( candidate0(3,j) .ge. syncmin .and. candidate0(2,j).ge.-1.5 ) then
|
! if( candidate0(3,j) .ge. syncmin .and. candidate0(2,j).ge.-1.5 ) then
|
||||||
if( candidate0(3,j) .ge. syncmin ) then
|
if( candidate0(3,j) .ge. syncmin ) then
|
||||||
candidate(1:3,k)=abs(candidate0(1:3,j))
|
candidate(2:3,k)=candidate0(2:3,j)
|
||||||
|
candidate(1,k)=abs(candidate0(1,j))
|
||||||
k=k+1
|
k=k+1
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
@ -52,7 +52,7 @@ contains
|
|||||||
character*12 mycall12,hiscall12,mycall12_0
|
character*12 mycall12,hiscall12,mycall12_0
|
||||||
character*6 hisgrid6
|
character*6 hisgrid6
|
||||||
integer*2 iwave(15*12000)
|
integer*2 iwave(15*12000)
|
||||||
integer apsym1(KK),apsym2(58)
|
integer apsym2(58)
|
||||||
character datetime*13,msg37*37
|
character datetime*13,msg37*37
|
||||||
! character message*22
|
! character message*22
|
||||||
character*37 allmessages(100)
|
character*37 allmessages(100)
|
||||||
|
@ -21,12 +21,13 @@ program jt65sim
|
|||||||
character msg*22,fname*11,csubmode*1,c,optarg*500,numbuf*32
|
character msg*22,fname*11,csubmode*1,c,optarg*500,numbuf*32
|
||||||
! character call1*5,call2*5
|
! character call1*5,call2*5
|
||||||
logical :: display_help=.false.,seed_prngs=.true.
|
logical :: display_help=.false.,seed_prngs=.true.
|
||||||
type (option) :: long_options(12) = [ &
|
type (option) :: long_options(13) = [ &
|
||||||
option ('help',.false.,'h','Display this help message',''), &
|
option ('help',.false.,'h','Display this help message',''), &
|
||||||
option ('sub-mode',.true.,'m','sub mode, default MODE=A','MODE'), &
|
option ('sub-mode',.true.,'m','sub mode, default MODE=A','MODE'), &
|
||||||
option ('num-sigs',.true.,'n','number of signals per file, default SIGNALS=10','SIGNALS'), &
|
option ('num-sigs',.true.,'n','number of signals per file, default SIGNALS=10','SIGNALS'), &
|
||||||
option ('f0',.true.,'F','base frequency offset, default F0=1500.0','F0'), &
|
option ('f0',.true.,'F','base frequency offset, default F0=1500.0','F0'), &
|
||||||
option ('doppler-spread',.true.,'d','Doppler spread, default SPREAD=0.0','SPREAD'), &
|
option ('doppler-spread',.true.,'d','Doppler spread, default SPREAD=0.0','SPREAD'), &
|
||||||
|
option ('drift per min',.true.,'D','Frequency drift (Hz/min), default DRIFT=0.0','DRIFT'), &
|
||||||
option ('time-offset',.true.,'t','Time delta, default SECONDS=0.0','SECONDS'), &
|
option ('time-offset',.true.,'t','Time delta, default SECONDS=0.0','SECONDS'), &
|
||||||
option ('num-files',.true.,'f','Number of files to generate, default FILES=1','FILES'), &
|
option ('num-files',.true.,'f','Number of files to generate, default FILES=1','FILES'), &
|
||||||
option ('no-prng-seed',.false.,'p','Do not seed PRNGs (use for reproducible tests)',''), &
|
option ('no-prng-seed',.false.,'p','Do not seed PRNGs (use for reproducible tests)',''), &
|
||||||
@ -50,6 +51,7 @@ program jt65sim
|
|||||||
nsigs=10
|
nsigs=10
|
||||||
bf0=1500.
|
bf0=1500.
|
||||||
fspread=0.
|
fspread=0.
|
||||||
|
drift=0.
|
||||||
xdt=0.
|
xdt=0.
|
||||||
snrdb=0.
|
snrdb=0.
|
||||||
nfiles=1
|
nfiles=1
|
||||||
@ -58,7 +60,7 @@ program jt65sim
|
|||||||
msg="K1ABC W9XYZ EN37"
|
msg="K1ABC W9XYZ EN37"
|
||||||
|
|
||||||
do
|
do
|
||||||
call getopt('hm:n:F:d:t:f:ps:SG:M:',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.)
|
call getopt('hm:n:F:d:D:t:f:ps:SG:M:',long_options,c,optarg,narglen,nstat,noffset,nremain,.true.)
|
||||||
if( nstat .ne. 0 ) then
|
if( nstat .ne. 0 ) then
|
||||||
exit
|
exit
|
||||||
end if
|
end if
|
||||||
@ -76,6 +78,8 @@ program jt65sim
|
|||||||
read (optarg(:narglen), *,err=10) bf0
|
read (optarg(:narglen), *,err=10) bf0
|
||||||
case ('d')
|
case ('d')
|
||||||
read (optarg(:narglen), *,err=10) fspread
|
read (optarg(:narglen), *,err=10) fspread
|
||||||
|
case ('D')
|
||||||
|
read (optarg(:narglen), *,err=10) drift
|
||||||
case ('t')
|
case ('t')
|
||||||
read (optarg(:narglen), *) numbuf
|
read (optarg(:narglen), *) numbuf
|
||||||
if (numbuf(1:1) == '\') then !'\'
|
if (numbuf(1:1) == '\') then !'\'
|
||||||
@ -105,7 +109,6 @@ program jt65sim
|
|||||||
end if
|
end if
|
||||||
case ('M')
|
case ('M')
|
||||||
read (optarg(:narglen), '(A)',err=10) msg
|
read (optarg(:narglen), '(A)',err=10) msg
|
||||||
write(*,*) msg
|
|
||||||
end select
|
end select
|
||||||
cycle
|
cycle
|
||||||
10 display_help=.true.
|
10 display_help=.true.
|
||||||
@ -190,6 +193,21 @@ program jt65sim
|
|||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
if(len(trim(msg)).eq.2.or.len(trim(msg)).eq.3) then
|
||||||
|
nshorthand=0
|
||||||
|
if(msg(1:2).eq.'RO') nshorthand=2
|
||||||
|
if(msg(1:3).eq.'RRR') nshorthand=3
|
||||||
|
if(msg(1:2).eq.'73') nshorthand=4
|
||||||
|
if(nshorthand.gt.0) then
|
||||||
|
ntoggle=0
|
||||||
|
do i=1,nsym,2
|
||||||
|
itone(i)=ntoggle*10*nshorthand
|
||||||
|
if(i+1.le.126) itone(i+1)=ntoggle*10*nshorthand
|
||||||
|
ntoggle=mod(ntoggle+1,2)
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
bandwidth_ratio=2500.0/(fsample/2.0)
|
bandwidth_ratio=2500.0/(fsample/2.0)
|
||||||
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*xsnr)
|
sig=sqrt(2*bandwidth_ratio)*10.0**(0.05*xsnr)
|
||||||
if(xsnr.gt.90.0) sig=1.0
|
if(xsnr.gt.90.0) sig=1.0
|
||||||
@ -203,11 +221,8 @@ program jt65sim
|
|||||||
do i=1,npts !Add this signal into cdat()
|
do i=1,npts !Add this signal into cdat()
|
||||||
isym=floor(i/sps)+1
|
isym=floor(i/sps)+1
|
||||||
if(isym.gt.nsym) exit
|
if(isym.gt.nsym) exit
|
||||||
if(isym.ne.isym0) then
|
freq=f0 + (drift/60.0)*(i-npts/2)*dt + itone(isym)*baud*mode65
|
||||||
freq=f0 + itone(isym)*baud*mode65
|
dphi=twopi*freq*dt
|
||||||
dphi=twopi*freq*dt
|
|
||||||
isym0=isym
|
|
||||||
endif
|
|
||||||
phi=phi + dphi
|
phi=phi + dphi
|
||||||
if(phi.gt.twopi) phi=phi-twopi
|
if(phi.gt.twopi) phi=phi-twopi
|
||||||
xphi=phi
|
xphi=phi
|
||||||
@ -282,9 +297,9 @@ program jt65sim
|
|||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dat=aimag(cdat) + xnoise !Add the generated noise
|
dat(1:npts)=aimag(cdat(1:npts)) + xnoise(1:npts) !Add the generated noise
|
||||||
if(snrdb.lt.90.0) then
|
if(snrdb.lt.90.0) then
|
||||||
dat=rms*dat(1:npts)
|
dat(1:npts)=rms*dat(1:npts)
|
||||||
else
|
else
|
||||||
datpk=maxval(abs(dat(1:npts)))
|
datpk=maxval(abs(dat(1:npts)))
|
||||||
fac=32766.9/datpk
|
fac=32766.9/datpk
|
||||||
|
@ -5,7 +5,7 @@ program msk144code
|
|||||||
|
|
||||||
use packjt77
|
use packjt77
|
||||||
character*77 c77
|
character*77 c77
|
||||||
character msg*37,msgsent*37,decoded,bad*1,msgtype*16
|
character msg*37,msgsent*37,decoded,bad*1,msgtype*18
|
||||||
integer*4 i4tone(144)
|
integer*4 i4tone(144)
|
||||||
include 'msk144_testmsg.f90'
|
include 'msk144_testmsg.f90'
|
||||||
|
|
||||||
@ -61,13 +61,13 @@ program msk144code
|
|||||||
if(msg.ne.msgsent) bad="*"
|
if(msg.ne.msgsent) bad="*"
|
||||||
if(i3.eq.0.and.n3.ge.0) then
|
if(i3.eq.0.and.n3.ge.0) then
|
||||||
write(*,1020) imsg,msg,msgsent,bad,i3,n3,msgtype
|
write(*,1020) imsg,msg,msgsent,bad,i3,n3,msgtype
|
||||||
1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a16)
|
1020 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',i1,1x,a18)
|
||||||
elseif(i3.ge.1) then
|
elseif(i3.ge.1) then
|
||||||
write(*,1022) imsg,msg,msgsent,bad,i3,msgtype
|
write(*,1022) imsg,msg,msgsent,bad,i3,msgtype
|
||||||
1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a16)
|
1022 format(i2,'.',1x,a37,1x,a37,1x,a1,2x,i1,'.',1x,1x,a18)
|
||||||
elseif(i3.lt.0) then
|
elseif(i3.lt.0) then
|
||||||
write(*,1024) imsg,msg,msgsent,bad,msgtype
|
write(*,1024) imsg,msg,msgsent,bad,msgtype
|
||||||
1024 format(i2,'.',1x,a37,1x,a37,1x,a1,6x,a16)
|
1024 format(i2,'.',1x,a37,1x,a37,1x,a1,6x,a18)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
enddo
|
enddo
|
||||||
|
@ -100,7 +100,7 @@ subroutine msk144decodeframe(c,softbits,msgreceived,nsuccess)
|
|||||||
if( nharderror .ge. 0 .and. nharderror .lt. 18 ) then
|
if( nharderror .ge. 0 .and. nharderror .lt. 18 ) then
|
||||||
nsuccess=1
|
nsuccess=1
|
||||||
write(c77,'(77i1)') decoded77
|
write(c77,'(77i1)') decoded77
|
||||||
read(c77(72:77),'(2b3)'),n3,i3
|
read(c77(72:77),'(2b3)') n3,i3
|
||||||
if( (i3.eq.0.and.(n3.eq.1 .or. n3.eq.3 .or. n3.eq.4 .or. n3.gt.5)) .or. i3.eq.3 .or. i3.gt.4 ) then
|
if( (i3.eq.0.and.(n3.eq.1 .or. n3.eq.3 .or. n3.eq.4 .or. n3.gt.5)) .or. i3.eq.3 .or. i3.gt.4 ) then
|
||||||
nsuccess=0
|
nsuccess=0
|
||||||
else
|
else
|
||||||
|
@ -5,7 +5,6 @@ program msk144sim
|
|||||||
real pings(0:NMAX-1)
|
real pings(0:NMAX-1)
|
||||||
real waveform(0:NMAX-1)
|
real waveform(0:NMAX-1)
|
||||||
character arg*8,msg*37,msgsent*37,fname*40
|
character arg*8,msg*37,msgsent*37,fname*40
|
||||||
character*77 c77
|
|
||||||
real wave(0:NMAX-1) !Simulated received waveform
|
real wave(0:NMAX-1) !Simulated received waveform
|
||||||
real*8 twopi,freq,phi,dphi0,dphi1,dphi
|
real*8 twopi,freq,phi,dphi0,dphi1,dphi
|
||||||
type(hdr) h !Header for .wav file
|
type(hdr) h !Header for .wav file
|
||||||
|
@ -29,7 +29,7 @@ subroutine sync4(dat,jz,ntol,nfqso,mode,mode4,minwidth,dtx,dfx,snrx, &
|
|||||||
df=0.5*11025.0/nfft
|
df=0.5*11025.0/nfft
|
||||||
ftop=nfqso + 7*mode4*df
|
ftop=nfqso + 7*mode4*df
|
||||||
if(ftop.gt.11025.0/4.0) then
|
if(ftop.gt.11025.0/4.0) then
|
||||||
print*,'*** Rx Freq is set too high for this submode ***'
|
print*,'*** Rx Freq is set too high for this sybmode ***'
|
||||||
go to 900
|
go to 900
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -139,11 +139,8 @@ subroutine sync4(dat,jz,ntol,nfqso,mode,mode4,minwidth,dtx,dfx,snrx, &
|
|||||||
ns=ns+1
|
ns=ns+1
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
rms=0.1
|
rms=sqrt(sq/ns)
|
||||||
snrx=-26.0
|
snrx=10.0*log10(ccfred(ipk1a)/rms) - 41.2
|
||||||
if(ns.gt.0) rms=sqrt(sq/ns)
|
|
||||||
if(ccfred(ipk1a).gt.0.0) snrx=10.0*log10(ccfred(ipk1a)/rms) - 41.2
|
|
||||||
if(snrx.gt.50.0) snrx=50.0
|
|
||||||
|
|
||||||
900 return
|
900 return
|
||||||
end subroutine sync4
|
end subroutine sync4
|
||||||
|
@ -159,8 +159,9 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Record fixup (QString const& call, prefix const& p) const
|
Record fixup (QString call, prefix const& p) const
|
||||||
{
|
{
|
||||||
|
call = call.toUpper ();
|
||||||
using entity_by_id = entities_type::index<id>::type;
|
using entity_by_id = entities_type::index<id>::type;
|
||||||
entity_by_id::iterator e; // iterator into entity set
|
entity_by_id::iterator e; // iterator into entity set
|
||||||
|
|
||||||
|
@ -1,22 +1,29 @@
|
|||||||
#include "WorkedBefore.hpp"
|
#include "WorkedBefore.hpp"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <stdexcept>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/multi_index_container.hpp>
|
#include <boost/multi_index_container.hpp>
|
||||||
#include <boost/multi_index/hashed_index.hpp>
|
#include <boost/multi_index/hashed_index.hpp>
|
||||||
#include <boost/multi_index/ordered_index.hpp>
|
#include <boost/multi_index/ordered_index.hpp>
|
||||||
#include <boost/multi_index/key_extractors.hpp>
|
#include <boost/multi_index/key_extractors.hpp>
|
||||||
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QFutureWatcher>
|
||||||
#include <QChar>
|
#include <QChar>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QDebug>
|
|
||||||
#include "qt_helpers.hpp"
|
#include "qt_helpers.hpp"
|
||||||
#include "pimpl_impl.hpp"
|
#include "pimpl_impl.hpp"
|
||||||
|
|
||||||
|
#include "moc_WorkedBefore.cpp"
|
||||||
|
|
||||||
using namespace boost::multi_index;
|
using namespace boost::multi_index;
|
||||||
|
|
||||||
// hash function for QString members in hashed indexes
|
// hash function for QString members in hashed indexes
|
||||||
@ -214,6 +221,20 @@ namespace
|
|||||||
{
|
{
|
||||||
auto const logFileName = "wsjtx_log.adi";
|
auto const logFileName = "wsjtx_log.adi";
|
||||||
|
|
||||||
|
// Expception class suitable for using with QtConcurrent across
|
||||||
|
// thread boundaries
|
||||||
|
class LoaderException final
|
||||||
|
: public QException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LoaderException (std::exception const& e) : error_ {e.what ()} {}
|
||||||
|
QString error () const {return error_;}
|
||||||
|
void raise () const override {throw *this;}
|
||||||
|
LoaderException * clone () const override {return new LoaderException {*this};}
|
||||||
|
private:
|
||||||
|
QString error_;
|
||||||
|
};
|
||||||
|
|
||||||
QString extractField (QString const& record, QString const& fieldName)
|
QString extractField (QString const& record, QString const& fieldName)
|
||||||
{
|
{
|
||||||
int fieldNameIndex = record.indexOf ('<' + fieldName + ':', 0, Qt::CaseInsensitive);
|
int fieldNameIndex = record.indexOf ('<' + fieldName + ':', 0, Qt::CaseInsensitive);
|
||||||
@ -228,8 +249,12 @@ namespace
|
|||||||
if (dataTypeIndex > closingBracketIndex)
|
if (dataTypeIndex > closingBracketIndex)
|
||||||
dataTypeIndex = -1; // second : was found but it was beyond the closing >
|
dataTypeIndex = -1; // second : was found but it was beyond the closing >
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw LoaderException (std::runtime_error {"Invalid ADIF field " + fieldName.toStdString () + ": " + record.toStdString ()});
|
||||||
|
}
|
||||||
|
|
||||||
if ((closingBracketIndex > fieldNameIndex) && (fieldLengthIndex > fieldNameIndex) && (fieldLengthIndex< closingBracketIndex))
|
if (closingBracketIndex > fieldNameIndex && fieldLengthIndex > fieldNameIndex && fieldLengthIndex < closingBracketIndex)
|
||||||
{
|
{
|
||||||
int fieldLengthCharCount = closingBracketIndex - fieldLengthIndex -1;
|
int fieldLengthCharCount = closingBracketIndex - fieldLengthIndex -1;
|
||||||
if (dataTypeIndex >= 0)
|
if (dataTypeIndex >= 0)
|
||||||
@ -241,8 +266,93 @@ namespace
|
|||||||
return record.mid(closingBracketIndex+1,fieldLength);
|
return record.mid(closingBracketIndex+1,fieldLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw LoaderException (std::runtime_error {"Malformed ADIF field " + fieldName.toStdString () + ": " + record.toStdString ()});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return QString {};
|
||||||
|
}
|
||||||
|
|
||||||
|
worked_before_database_type loader (QString const& path, AD1CCty const * prefixes)
|
||||||
|
{
|
||||||
|
worked_before_database_type worked;
|
||||||
|
QFile inputFile {path};
|
||||||
|
if (inputFile.exists ())
|
||||||
|
{
|
||||||
|
if (inputFile.open (QFile::ReadOnly))
|
||||||
|
{
|
||||||
|
QTextStream in {&inputFile};
|
||||||
|
QString buffer;
|
||||||
|
bool pre_read {false};
|
||||||
|
int end_position {-1};
|
||||||
|
|
||||||
|
// skip optional header record
|
||||||
|
do
|
||||||
|
{
|
||||||
|
buffer += in.readLine () + '\n';
|
||||||
|
if (buffer.startsWith (QChar {'<'})) // denotes no header
|
||||||
|
{
|
||||||
|
pre_read = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end_position = buffer.indexOf ("<EOH>", 0, Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!in.atEnd () && !pre_read && end_position < 0);
|
||||||
|
if (!pre_read) // found header
|
||||||
|
{
|
||||||
|
if (end_position < 0)
|
||||||
|
{
|
||||||
|
throw LoaderException (std::runtime_error {"Invalid ADIF header"});
|
||||||
|
}
|
||||||
|
buffer.remove (0, end_position + 5);
|
||||||
|
}
|
||||||
|
while (!in.atEnd ())
|
||||||
|
{
|
||||||
|
end_position = buffer.indexOf ("<EOR>", 0, Qt::CaseInsensitive);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!in.atEnd () && end_position < 0)
|
||||||
|
{
|
||||||
|
buffer += in.readLine () + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((end_position = buffer.indexOf ("<EOR>", 0, Qt::CaseInsensitive)) < 0 && !in.atEnd ());
|
||||||
|
if (end_position < 0)
|
||||||
|
{
|
||||||
|
throw LoaderException (std::runtime_error {"Invalid ADIF record starting at: " + buffer.left (40).toStdString ()});
|
||||||
|
}
|
||||||
|
auto record = buffer.left (end_position + 5).trimmed ();
|
||||||
|
auto next_record = buffer.indexOf (QChar {'<'}, end_position + 5);
|
||||||
|
buffer.remove (0, next_record >=0 ? next_record : buffer.size ());
|
||||||
|
record = record.mid (record.indexOf (QChar {'<'}));
|
||||||
|
auto call = extractField (record, "CALL");
|
||||||
|
if (call.size ())
|
||||||
|
{
|
||||||
|
auto const& entity = prefixes->lookup (call);
|
||||||
|
worked.emplace (call.toUpper ()
|
||||||
|
, extractField (record, "GRIDSQUARE").left (4).toUpper () // not interested in 6-digit grids
|
||||||
|
, extractField (record, "BAND").toUpper ()
|
||||||
|
, extractField (record, "MODE").toUpper ()
|
||||||
|
, entity.entity_name
|
||||||
|
, entity.continent
|
||||||
|
, entity.CQ_zone
|
||||||
|
, entity.ITU_zone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw LoaderException (std::runtime_error {"Invalid ADIF record with no CALL: " + record.toStdString ()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw LoaderException (std::runtime_error {"Error opening ADIF log file for read: " + inputFile.errorString ().toStdString ()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return worked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,70 +364,41 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reload ()
|
||||||
|
{
|
||||||
|
async_loader_ = QtConcurrent::run (loader, path_, &prefixes_);
|
||||||
|
loader_watcher_.setFuture (async_loader_);
|
||||||
|
}
|
||||||
|
|
||||||
QString path_;
|
QString path_;
|
||||||
AD1CCty prefixes_;
|
AD1CCty prefixes_;
|
||||||
|
QFutureWatcher<worked_before_database_type> loader_watcher_;
|
||||||
|
QFuture<worked_before_database_type> async_loader_;
|
||||||
worked_before_database_type worked_;
|
worked_before_database_type worked_;
|
||||||
};
|
};
|
||||||
|
|
||||||
WorkedBefore::WorkedBefore ()
|
WorkedBefore::WorkedBefore ()
|
||||||
{
|
{
|
||||||
QFile inputFile {m_->path_};
|
connect (&m_->loader_watcher_, &QFutureWatcher<worked_before_database_type>::finished, [this] () {
|
||||||
if (inputFile.open (QFile::ReadOnly))
|
QString error;
|
||||||
{
|
size_t n {0};
|
||||||
QTextStream in {&inputFile};
|
try
|
||||||
QString buffer;
|
{
|
||||||
bool pre_read {false};
|
m_->worked_ = m_->loader_watcher_.result ();
|
||||||
int end_position {-1};
|
n = m_->worked_.size ();
|
||||||
|
}
|
||||||
|
catch (LoaderException const& e)
|
||||||
|
{
|
||||||
|
error = e.error ();
|
||||||
|
}
|
||||||
|
Q_EMIT finished_loading (n, error);
|
||||||
|
});
|
||||||
|
reload ();
|
||||||
|
}
|
||||||
|
|
||||||
// skip optional header record
|
void WorkedBefore::reload ()
|
||||||
do
|
{
|
||||||
{
|
m_->reload ();
|
||||||
buffer += in.readLine () + '\n';
|
|
||||||
if (buffer.startsWith (QChar {'<'})) // denotes no header
|
|
||||||
{
|
|
||||||
pre_read = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
end_position = buffer.indexOf ("<EOH>", 0, Qt::CaseInsensitive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (!in.atEnd () && !pre_read && end_position < 0);
|
|
||||||
if (!pre_read) // found header
|
|
||||||
{
|
|
||||||
buffer.remove (0, end_position + 5);
|
|
||||||
}
|
|
||||||
while (buffer.size () || !in.atEnd ())
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
end_position = buffer.indexOf ("<EOR>", 0, Qt::CaseInsensitive);
|
|
||||||
if (!in.atEnd () && end_position < 0)
|
|
||||||
{
|
|
||||||
buffer += in.readLine () + '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (!in.atEnd () && end_position < 0);
|
|
||||||
int record_length {end_position >= 0 ? end_position + 5 : -1};
|
|
||||||
auto record = buffer.left (record_length).trimmed ();
|
|
||||||
auto next_record = buffer.indexOf (QChar {'<'}, record_length);
|
|
||||||
buffer.remove (0, next_record >=0 ? next_record : buffer.size ());
|
|
||||||
record = record.mid (record.indexOf (QChar {'<'}));
|
|
||||||
auto call = extractField (record, "CALL");
|
|
||||||
if (call.size ())
|
|
||||||
{
|
|
||||||
auto const& entity = m_->prefixes_.lookup (call);
|
|
||||||
m_->worked_.emplace (call
|
|
||||||
, extractField (record, "GRIDSQUARE").left (4) // not interested in 6-digit grids
|
|
||||||
, extractField (record, "BAND")
|
|
||||||
, extractField (record, "MODE")
|
|
||||||
, entity.entity_name
|
|
||||||
, entity.continent
|
|
||||||
, entity.CQ_zone
|
|
||||||
, entity.ITU_zone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkedBefore::~WorkedBefore ()
|
WorkedBefore::~WorkedBefore ()
|
||||||
@ -357,8 +438,8 @@ bool WorkedBefore::add (QString const& call
|
|||||||
}
|
}
|
||||||
out << ADIF_record << " <eor>" << endl;
|
out << ADIF_record << " <eor>" << endl;
|
||||||
}
|
}
|
||||||
m_->worked_.emplace (call, grid, band, mode, entity.entity_name
|
m_->worked_.emplace (call.toUpper (), grid.left (4).toUpper (), band.toUpper (), mode.toUpper ()
|
||||||
, entity.continent, entity.CQ_zone, entity.ITU_zone);
|
, entity.entity_name, entity.continent, entity.CQ_zone, entity.ITU_zone);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -372,7 +453,7 @@ bool WorkedBefore::country_worked (QString const& country, QString const& mode,
|
|||||||
return
|
return
|
||||||
country.size ()
|
country.size ()
|
||||||
&& m_->worked_.get<entity_mode_band> ().end ()
|
&& m_->worked_.get<entity_mode_band> ().end ()
|
||||||
!= m_->worked_.get<entity_mode_band> ().find (std::make_tuple (country, mode, band));
|
!= m_->worked_.get<entity_mode_band> ().find (std::make_tuple (country, mode.toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -380,7 +461,7 @@ bool WorkedBefore::country_worked (QString const& country, QString const& mode,
|
|||||||
return
|
return
|
||||||
country.size ()
|
country.size ()
|
||||||
&& m_->worked_.get<entity_mode_band> ().end ()
|
&& m_->worked_.get<entity_mode_band> ().end ()
|
||||||
!= m_->worked_.get<entity_mode_band> ().find (std::make_tuple (country, mode));
|
!= m_->worked_.get<entity_mode_band> ().find (std::make_tuple (country, mode.toUpper ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -390,7 +471,7 @@ bool WorkedBefore::country_worked (QString const& country, QString const& mode,
|
|||||||
return
|
return
|
||||||
country.size ()
|
country.size ()
|
||||||
&& m_->worked_.get<entity_band> ().end ()
|
&& m_->worked_.get<entity_band> ().end ()
|
||||||
!= m_->worked_.get<entity_band> ().find (std::make_tuple (country, band));
|
!= m_->worked_.get<entity_band> ().find (std::make_tuple (country, band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -410,13 +491,13 @@ bool WorkedBefore::grid_worked (QString const& grid, QString const& mode, QStrin
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<grid_mode_band> ().end ()
|
return m_->worked_.get<grid_mode_band> ().end ()
|
||||||
!= m_->worked_.get<grid_mode_band> ().find (std::make_tuple (grid, mode, band));
|
!= m_->worked_.get<grid_mode_band> ().find (std::make_tuple (grid.left (4).toUpper (), mode.toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partial key lookup
|
// partial key lookup
|
||||||
return m_->worked_.get<grid_mode_band> ().end ()
|
return m_->worked_.get<grid_mode_band> ().end ()
|
||||||
!= m_->worked_.get<grid_mode_band> ().find (std::make_tuple (grid, mode));
|
!= m_->worked_.get<grid_mode_band> ().find (std::make_tuple (grid.left (4).toUpper (), mode.toUpper ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -424,13 +505,13 @@ bool WorkedBefore::grid_worked (QString const& grid, QString const& mode, QStrin
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<grid_band> ().end ()
|
return m_->worked_.get<grid_band> ().end ()
|
||||||
!= m_->worked_.get<grid_band> ().find (std::make_tuple (grid, band));
|
!= m_->worked_.get<grid_band> ().find (std::make_tuple (grid.left (4).toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partial key lookup
|
// partial key lookup
|
||||||
return m_->worked_.get<grid_band> ().end ()
|
return m_->worked_.get<grid_band> ().end ()
|
||||||
!= m_->worked_.get<grid_band> ().find (grid);
|
!= m_->worked_.get<grid_band> ().find (grid.left (4).toUpper ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,13 +523,13 @@ bool WorkedBefore::call_worked (QString const& call, QString const& mode, QStrin
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<call_mode_band> ().end ()
|
return m_->worked_.get<call_mode_band> ().end ()
|
||||||
!= m_->worked_.get<call_mode_band> ().find (std::make_tuple (call, mode, band));
|
!= m_->worked_.get<call_mode_band> ().find (std::make_tuple (call.toUpper (), mode.toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partial key lookup
|
// partial key lookup
|
||||||
return m_->worked_.get<call_mode_band> ().end ()
|
return m_->worked_.get<call_mode_band> ().end ()
|
||||||
!= m_->worked_.get<call_mode_band> ().find (std::make_tuple (call, mode));
|
!= m_->worked_.get<call_mode_band> ().find (std::make_tuple (call.toUpper (), mode.toUpper ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -456,13 +537,13 @@ bool WorkedBefore::call_worked (QString const& call, QString const& mode, QStrin
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<call_band> ().end ()
|
return m_->worked_.get<call_band> ().end ()
|
||||||
!= m_->worked_.get<call_band> ().find (std::make_tuple (call, band));
|
!= m_->worked_.get<call_band> ().find (std::make_tuple (call.toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partial key lookup
|
// partial key lookup
|
||||||
return m_->worked_.get<call_band> ().end ()
|
return m_->worked_.get<call_band> ().end ()
|
||||||
!= m_->worked_.get<call_band> ().find (std::make_tuple (call));
|
!= m_->worked_.get<call_band> ().find (std::make_tuple (call.toUpper ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -474,13 +555,13 @@ bool WorkedBefore::continent_worked (Continent continent, QString const& mode, Q
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<continent_mode_band> ().end ()
|
return m_->worked_.get<continent_mode_band> ().end ()
|
||||||
!= m_->worked_.get<continent_mode_band> ().find (std::make_tuple (continent, mode, band));
|
!= m_->worked_.get<continent_mode_band> ().find (std::make_tuple (continent, mode.toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partial key lookup
|
// partial key lookup
|
||||||
return m_->worked_.get<continent_mode_band> ().end ()
|
return m_->worked_.get<continent_mode_band> ().end ()
|
||||||
!= m_->worked_.get<continent_mode_band> ().find (std::make_tuple (continent, mode));
|
!= m_->worked_.get<continent_mode_band> ().find (std::make_tuple (continent, mode.toUpper ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -488,7 +569,7 @@ bool WorkedBefore::continent_worked (Continent continent, QString const& mode, Q
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<continent_band> ().end ()
|
return m_->worked_.get<continent_band> ().end ()
|
||||||
!= m_->worked_.get<continent_band> ().find (std::make_tuple (continent, band));
|
!= m_->worked_.get<continent_band> ().find (std::make_tuple (continent, band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -506,13 +587,13 @@ bool WorkedBefore::CQ_zone_worked (int CQ_zone, QString const& mode, QString con
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<CQ_zone_mode_band> ().end ()
|
return m_->worked_.get<CQ_zone_mode_band> ().end ()
|
||||||
!= m_->worked_.get<CQ_zone_mode_band> ().find (std::make_tuple (CQ_zone, mode, band));
|
!= m_->worked_.get<CQ_zone_mode_band> ().find (std::make_tuple (CQ_zone, mode.toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partial key lookup
|
// partial key lookup
|
||||||
return m_->worked_.get<CQ_zone_mode_band> ().end ()
|
return m_->worked_.get<CQ_zone_mode_band> ().end ()
|
||||||
!= m_->worked_.get<CQ_zone_mode_band> ().find (std::make_tuple (CQ_zone, mode));
|
!= m_->worked_.get<CQ_zone_mode_band> ().find (std::make_tuple (CQ_zone, mode.toUpper ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -520,7 +601,7 @@ bool WorkedBefore::CQ_zone_worked (int CQ_zone, QString const& mode, QString con
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<CQ_zone_band> ().end ()
|
return m_->worked_.get<CQ_zone_band> ().end ()
|
||||||
!= m_->worked_.get<CQ_zone_band> ().find (std::make_tuple (CQ_zone, band));
|
!= m_->worked_.get<CQ_zone_band> ().find (std::make_tuple (CQ_zone, band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -538,13 +619,13 @@ bool WorkedBefore::ITU_zone_worked (int ITU_zone, QString const& mode, QString c
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<ITU_zone_mode_band> ().end ()
|
return m_->worked_.get<ITU_zone_mode_band> ().end ()
|
||||||
!= m_->worked_.get<ITU_zone_mode_band> ().find (std::make_tuple (ITU_zone, mode, band));
|
!= m_->worked_.get<ITU_zone_mode_band> ().find (std::make_tuple (ITU_zone, mode.toUpper (), band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partial key lookup
|
// partial key lookup
|
||||||
return m_->worked_.get<ITU_zone_mode_band> ().end ()
|
return m_->worked_.get<ITU_zone_mode_band> ().end ()
|
||||||
!= m_->worked_.get<ITU_zone_mode_band> ().find (std::make_tuple (ITU_zone, mode));
|
!= m_->worked_.get<ITU_zone_mode_band> ().find (std::make_tuple (ITU_zone, mode.toUpper ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -552,7 +633,7 @@ bool WorkedBefore::ITU_zone_worked (int ITU_zone, QString const& mode, QString c
|
|||||||
if (band.size ())
|
if (band.size ())
|
||||||
{
|
{
|
||||||
return m_->worked_.get<ITU_zone_band> ().end ()
|
return m_->worked_.get<ITU_zone_band> ().end ()
|
||||||
!= m_->worked_.get<ITU_zone_band> ().find (std::make_tuple (ITU_zone, band));
|
!= m_->worked_.get<ITU_zone_band> ().find (std::make_tuple (ITU_zone, band.toUpper ()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef WORKWED_BEFORE_HPP_
|
#ifndef WORKWED_BEFORE_HPP_
|
||||||
#define WORKWED_BEFORE_HPP_
|
#define WORKWED_BEFORE_HPP_
|
||||||
|
|
||||||
#include <boost/core/noncopyable.hpp>
|
#include <QObject>
|
||||||
#include "AD1CCty.hpp"
|
#include "AD1CCty.hpp"
|
||||||
#include "pimpl_h.hpp"
|
#include "pimpl_h.hpp"
|
||||||
|
|
||||||
@ -10,21 +10,25 @@ class QString;
|
|||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
|
||||||
class WorkedBefore final
|
class WorkedBefore final
|
||||||
: private boost::noncopyable
|
: public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Continent = AD1CCty::Continent;
|
using Continent = AD1CCty::Continent;
|
||||||
|
|
||||||
explicit WorkedBefore ();
|
explicit WorkedBefore ();
|
||||||
~WorkedBefore ();
|
~WorkedBefore ();
|
||||||
|
|
||||||
|
Q_SLOT void reload ();
|
||||||
|
Q_SLOT bool add (QString const& call
|
||||||
|
, QString const& grid
|
||||||
|
, QString const& band
|
||||||
|
, QString const& mode
|
||||||
|
, QByteArray const& ADIF_record);
|
||||||
|
|
||||||
QString const& path () const;
|
QString const& path () const;
|
||||||
AD1CCty const& countries () const;
|
AD1CCty const& countries () const;
|
||||||
bool add (QString const& call
|
|
||||||
, QString const& grid
|
|
||||||
, QString const& band
|
|
||||||
, QString const& mode
|
|
||||||
, QByteArray const& ADIF_record);
|
|
||||||
bool country_worked (QString const& call, QString const& mode, QString const& band) const;
|
bool country_worked (QString const& call, QString const& mode, QString const& band) const;
|
||||||
bool grid_worked (QString const& grid, QString const& mode, QString const& band) const;
|
bool grid_worked (QString const& grid, QString const& mode, QString const& band) const;
|
||||||
bool call_worked (QString const& call, QString const& mode, QString const& band) const;
|
bool call_worked (QString const& call, QString const& mode, QString const& band) const;
|
||||||
@ -32,6 +36,8 @@ public:
|
|||||||
bool CQ_zone_worked (int CQ_zone, QString const& mode, QString const& band) const;
|
bool CQ_zone_worked (int CQ_zone, QString const& mode, QString const& band) const;
|
||||||
bool ITU_zone_worked (int ITU_zone, QString const& mode, QString const& band) const;
|
bool ITU_zone_worked (int ITU_zone, QString const& mode, QString const& band) const;
|
||||||
|
|
||||||
|
Q_SIGNAL void finished_loading (int worked_before_record_count, QString const& error) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class impl;
|
class impl;
|
||||||
pimpl<impl> m_;
|
pimpl<impl> m_;
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
#include "logbook.h"
|
#include "logbook.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
|
||||||
#include "Configuration.hpp"
|
#include "Configuration.hpp"
|
||||||
#include "AD1CCty.hpp"
|
#include "AD1CCty.hpp"
|
||||||
|
|
||||||
|
#include "moc_logbook.cpp"
|
||||||
|
|
||||||
LogBook::LogBook (Configuration const * configuration)
|
LogBook::LogBook (Configuration const * configuration)
|
||||||
: config_ {configuration}
|
: config_ {configuration}
|
||||||
{
|
{
|
||||||
|
connect (&worked_before_, &WorkedBefore::finished_loading, this, &LogBook::finished_loading);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogBook::match (QString const& call, QString const& mode, QString const& grid,
|
void LogBook::match (QString const& call, QString const& mode, QString const& grid,
|
||||||
@ -52,6 +54,11 @@ bool LogBook::add (QString const& call
|
|||||||
return worked_before_.add (call, grid, band, mode, ADIF_record);
|
return worked_before_.add (call, grid, band, mode, ADIF_record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogBook::rescan ()
|
||||||
|
{
|
||||||
|
worked_before_.reload ();
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray LogBook::QSOToADIF (QString const& hisCall, QString const& hisGrid, QString const& mode,
|
QByteArray LogBook::QSOToADIF (QString const& hisCall, QString const& hisGrid, QString const& mode,
|
||||||
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
|
QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn,
|
||||||
QDateTime const& dateTimeOff, QString const& band, QString const& comments,
|
QDateTime const& dateTimeOff, QString const& band, QString const& comments,
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
// -*- Mode: C++ -*-
|
||||||
/*
|
/*
|
||||||
* From an ADIF file and cty.dat, get a call's DXCC entity and its worked before status
|
* From an ADIF file and cty.dat, get a call's DXCC entity and its worked before status
|
||||||
* VK3ACF July 2013
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LOG_BOOK_H_
|
#ifndef LOG_BOOK_H_
|
||||||
#define LOG_BOOK_H_
|
#define LOG_BOOK_H_
|
||||||
|
|
||||||
#include <boost/core/noncopyable.hpp>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "WorkedBefore.hpp"
|
#include "WorkedBefore.hpp"
|
||||||
@ -16,9 +16,11 @@ class QByteArray;
|
|||||||
class QDateTime;
|
class QDateTime;
|
||||||
|
|
||||||
class LogBook final
|
class LogBook final
|
||||||
: private boost::noncopyable
|
: public QObject
|
||||||
{
|
{
|
||||||
public:
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
LogBook (Configuration const *);
|
LogBook (Configuration const *);
|
||||||
QString const& path () const {return worked_before_.path ();}
|
QString const& path () const {return worked_before_.path ();}
|
||||||
bool add (QString const& call
|
bool add (QString const& call
|
||||||
@ -27,6 +29,7 @@ class LogBook final
|
|||||||
, QString const& mode
|
, QString const& mode
|
||||||
, QByteArray const& ADIF_record);
|
, QByteArray const& ADIF_record);
|
||||||
AD1CCty const& countries () const {return worked_before_.countries ();}
|
AD1CCty const& countries () const {return worked_before_.countries ();}
|
||||||
|
void rescan ();
|
||||||
void match (QString const& call, QString const& mode, QString const& grid,
|
void match (QString const& call, QString const& mode, QString const& grid,
|
||||||
AD1CCty::Record const&, bool& callB4, bool& countryB4,
|
AD1CCty::Record const&, bool& callB4, bool& countryB4,
|
||||||
bool &gridB4, bool &continentB4, bool& CQZoneB4, bool& ITUZoneB4,
|
bool &gridB4, bool &continentB4, bool& CQZoneB4, bool& ITUZoneB4,
|
||||||
@ -38,7 +41,9 @@ class LogBook final
|
|||||||
QString const& m_myGrid, QString const& m_txPower, QString const& operator_call,
|
QString const& m_myGrid, QString const& m_txPower, QString const& operator_call,
|
||||||
QString const& xSent, QString const& xRcvd);
|
QString const& xSent, QString const& xRcvd);
|
||||||
|
|
||||||
private:
|
Q_SIGNAL void finished_loading (int worked_before_record_count, QString const& error) const;
|
||||||
|
|
||||||
|
private:
|
||||||
Configuration const * config_;
|
Configuration const * config_;
|
||||||
WorkedBefore worked_before_;
|
WorkedBefore worked_before_;
|
||||||
};
|
};
|
||||||
|
9
main.cpp
@ -6,6 +6,8 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
|
||||||
|
#include <QSharedMemory>
|
||||||
|
#include <QTemporaryFile>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
@ -21,6 +23,7 @@
|
|||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QCommandLineOption>
|
#include <QCommandLineOption>
|
||||||
#include <QSqlDatabase>
|
#include <QSqlDatabase>
|
||||||
|
#include <QSqlQuery>
|
||||||
#include <QSqlError>
|
#include <QSqlError>
|
||||||
|
|
||||||
#include "revision_utils.hpp"
|
#include "revision_utils.hpp"
|
||||||
@ -288,6 +291,12 @@ int main(int argc, char *argv[])
|
|||||||
throw std::runtime_error {("Database Error: " + db.lastError ().text ()).toStdString ()};
|
throw std::runtime_error {("Database Error: " + db.lastError ().text ()).toStdString ()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// better performance traded for a risk of d/b corruption
|
||||||
|
// on system crash or application crash
|
||||||
|
// db.exec ("PRAGMA synchronous=OFF"); // system crash risk
|
||||||
|
// db.exec ("PRAGMA journal_mode=MEMORY"); // application crash risk
|
||||||
|
db.exec ("PRAGMA locking_mode=EXCLUSIVE");
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <QSqlError>
|
#include <QSqlError>
|
||||||
#include <QSqlQuery>
|
#include <QSqlQuery>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QDebug>
|
|
||||||
#include "Configuration.hpp"
|
#include "Configuration.hpp"
|
||||||
#include "Bands.hpp"
|
#include "Bands.hpp"
|
||||||
#include "qt_db_helpers.hpp"
|
#include "qt_db_helpers.hpp"
|
||||||
@ -52,7 +51,7 @@ CabrilloLog::impl::impl (Configuration const * configuration)
|
|||||||
SQL_error_check (export_query_, &QSqlQuery::prepare,
|
SQL_error_check (export_query_, &QSqlQuery::prepare,
|
||||||
"SELECT frequency, \"when\", exchange_sent, call, exchange_rcvd FROM cabrillo_log ORDER BY \"when\"");
|
"SELECT frequency, \"when\", exchange_sent, call, exchange_rcvd FROM cabrillo_log ORDER BY \"when\"");
|
||||||
|
|
||||||
setEditStrategy (QSqlTableModel::OnRowChange);
|
setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||||
setTable ("cabrillo_log");
|
setTable ("cabrillo_log");
|
||||||
setHeaderData (fieldIndex ("frequency"), Qt::Horizontal, tr ("Freq(kHz)"));
|
setHeaderData (fieldIndex ("frequency"), Qt::Horizontal, tr ("Freq(kHz)"));
|
||||||
setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
|
setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
|
||||||
@ -60,6 +59,12 @@ CabrilloLog::impl::impl (Configuration const * configuration)
|
|||||||
setHeaderData (fieldIndex ("exchange_sent"), Qt::Horizontal, tr ("Sent"));
|
setHeaderData (fieldIndex ("exchange_sent"), Qt::Horizontal, tr ("Sent"));
|
||||||
setHeaderData (fieldIndex ("exchange_rcvd"), Qt::Horizontal, tr ("Rcvd"));
|
setHeaderData (fieldIndex ("exchange_rcvd"), Qt::Horizontal, tr ("Rcvd"));
|
||||||
setHeaderData (fieldIndex ("band"), Qt::Horizontal, tr ("Band"));
|
setHeaderData (fieldIndex ("band"), Qt::Horizontal, tr ("Band"));
|
||||||
|
|
||||||
|
// This descending order by time is important, it makes the view
|
||||||
|
// place the latest row at the top, without this the model/view
|
||||||
|
// interactions are both sluggish and unhelpful.
|
||||||
|
setSort (fieldIndex ("when"), Qt::DescendingOrder);
|
||||||
|
|
||||||
SQL_error_check (*this, &QSqlTableModel::select);
|
SQL_error_check (*this, &QSqlTableModel::select);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,11 +115,15 @@ bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString c
|
|||||||
set_value_maybe_null (record, "exchange_sent", exchange_sent);
|
set_value_maybe_null (record, "exchange_sent", exchange_sent);
|
||||||
set_value_maybe_null (record, "exchange_rcvd", exchange_received);
|
set_value_maybe_null (record, "exchange_rcvd", exchange_received);
|
||||||
set_value_maybe_null (record, "band", m_->configuration_->bands ()->find (frequency));
|
set_value_maybe_null (record, "band", m_->configuration_->bands ()->find (frequency));
|
||||||
auto ok = m_->insertRecord (-1, record);
|
if (m_->isDirty ())
|
||||||
if (ok)
|
|
||||||
{
|
{
|
||||||
m_->select (); // to refresh views
|
m_->revert (); // discard any uncommitted changes
|
||||||
}
|
}
|
||||||
|
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
|
||||||
|
ConditionalTransaction transaction {*m_};
|
||||||
|
auto ok = m_->insertRecord (-1, record);
|
||||||
|
transaction.submit ();
|
||||||
|
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +145,7 @@ void CabrilloLog::reset ()
|
|||||||
SQL_error_check (*m_, &QSqlTableModel::removeRows, 0, m_->rowCount (), QModelIndex {});
|
SQL_error_check (*m_, &QSqlTableModel::removeRows, 0, m_->rowCount (), QModelIndex {});
|
||||||
transaction.submit ();
|
transaction.submit ();
|
||||||
m_->select (); // to refresh views
|
m_->select (); // to refresh views
|
||||||
m_->setEditStrategy (QSqlTableModel::OnRowChange);
|
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QBrush>
|
#include <QBrush>
|
||||||
#include <QFont>
|
#include <QColor>
|
||||||
|
#include <QFont>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
@ -160,7 +161,10 @@ QVariant DecodeHighlightingModel::data (const QModelIndex& index, int role) cons
|
|||||||
result = item.enabled_ ? Qt::Checked : Qt::Unchecked;
|
result = item.enabled_ ? Qt::Checked : Qt::Unchecked;
|
||||||
break;
|
break;
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
result = highlight_name (item.type_);
|
return QString {"%1 [f/g:%2, b/g:%3]"}
|
||||||
|
.arg (highlight_name (item.type_))
|
||||||
|
.arg (item.foreground_.style () != Qt::NoBrush ? QString {"#%1"}.arg (item.foreground_.color ().rgb () & 0xffffff, 6, 16, QChar {'0'}) : QString {"unset"})
|
||||||
|
.arg (item.background_.style () != Qt::NoBrush ? QString {"#%1"}.arg (item.background_.color ().rgb () & 0xffffff, 6, 16, QChar {'0'}) : QString {"unset"});
|
||||||
break;
|
break;
|
||||||
case Qt::ForegroundRole:
|
case Qt::ForegroundRole:
|
||||||
if (Qt::NoBrush != item.foreground_.style ())
|
if (Qt::NoBrush != item.foreground_.style ())
|
||||||
|
@ -43,7 +43,7 @@ FoxLog::impl::impl ()
|
|||||||
SQL_error_check (dupe_query_, &QSqlQuery::prepare,
|
SQL_error_check (dupe_query_, &QSqlQuery::prepare,
|
||||||
"SELECT COUNT(*) FROM fox_log WHERE call = :call AND band = :band");
|
"SELECT COUNT(*) FROM fox_log WHERE call = :call AND band = :band");
|
||||||
|
|
||||||
setEditStrategy (QSqlTableModel::OnRowChange);
|
setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||||
setTable ("fox_log");
|
setTable ("fox_log");
|
||||||
setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
|
setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)"));
|
||||||
setHeaderData (fieldIndex ("call"), Qt::Horizontal, tr ("Call"));
|
setHeaderData (fieldIndex ("call"), Qt::Horizontal, tr ("Call"));
|
||||||
@ -51,6 +51,12 @@ FoxLog::impl::impl ()
|
|||||||
setHeaderData (fieldIndex ("report_sent"), Qt::Horizontal, tr ("Sent"));
|
setHeaderData (fieldIndex ("report_sent"), Qt::Horizontal, tr ("Sent"));
|
||||||
setHeaderData (fieldIndex ("report_rcvd"), Qt::Horizontal, tr ("Rcvd"));
|
setHeaderData (fieldIndex ("report_rcvd"), Qt::Horizontal, tr ("Rcvd"));
|
||||||
setHeaderData (fieldIndex ("band"), Qt::Horizontal, tr ("Band"));
|
setHeaderData (fieldIndex ("band"), Qt::Horizontal, tr ("Band"));
|
||||||
|
|
||||||
|
// This descending order by time is important, it makes the view
|
||||||
|
// place the latest row at the top, without this the model/view
|
||||||
|
// interactions are both sluggish and unhelpful.
|
||||||
|
setSort (fieldIndex ("when"), Qt::DescendingOrder);
|
||||||
|
|
||||||
SQL_error_check (*this, &QSqlTableModel::select);
|
SQL_error_check (*this, &QSqlTableModel::select);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,11 +106,18 @@ bool FoxLog::add_QSO (QDateTime const& when, QString const& call, QString const&
|
|||||||
set_value_maybe_null (record, "report_sent", report_sent);
|
set_value_maybe_null (record, "report_sent", report_sent);
|
||||||
set_value_maybe_null (record, "report_rcvd", report_received);
|
set_value_maybe_null (record, "report_rcvd", report_received);
|
||||||
set_value_maybe_null (record, "band", band);
|
set_value_maybe_null (record, "band", band);
|
||||||
|
if (m_->isDirty ())
|
||||||
|
{
|
||||||
|
m_->revert (); // discard any uncommitted changes
|
||||||
|
}
|
||||||
|
m_->setEditStrategy (QSqlTableModel::OnManualSubmit);
|
||||||
|
ConditionalTransaction transaction {*m_};
|
||||||
auto ok = m_->insertRecord (-1, record);
|
auto ok = m_->insertRecord (-1, record);
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
m_->select (); // to refresh views
|
ok = transaction.submit (false);
|
||||||
}
|
}
|
||||||
|
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +139,6 @@ void FoxLog::reset ()
|
|||||||
SQL_error_check (*m_, &QSqlTableModel::removeRows, 0, m_->rowCount (), QModelIndex {});
|
SQL_error_check (*m_, &QSqlTableModel::removeRows, 0, m_->rowCount (), QModelIndex {});
|
||||||
transaction.submit ();
|
transaction.submit ();
|
||||||
m_->select (); // to refresh views
|
m_->select (); // to refresh views
|
||||||
m_->setEditStrategy (QSqlTableModel::OnRowChange);
|
m_->setEditStrategy (QSqlTableModel::OnFieldChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,10 +84,23 @@ AbstractLogWindow::AbstractLogWindow (QString const& settings_key, QSettings * s
|
|||||||
: QWidget {parent}
|
: QWidget {parent}
|
||||||
, m_ {this, settings_key, settings, configuration}
|
, m_ {this, settings_key, settings, configuration}
|
||||||
{
|
{
|
||||||
// ensure view scrolls to latest new row
|
// this attempt to scroll to the last new record doesn't work, some
|
||||||
connect (&m_->model_, &QAbstractItemModel::rowsInserted, [this] (QModelIndex const& /*parent*/, int /*first*/, int /*last*/) {
|
// sort of issue with model indexes and optimized DB fetches. For
|
||||||
if (m_->log_view_) m_->log_view_->scrollToBottom ();
|
// now sorting by the same column and direction as the underlying DB
|
||||||
});
|
// select and that DB select being in descending order so new rows
|
||||||
|
// at the end appear at view row 0 gets the job done
|
||||||
|
|
||||||
|
// // ensure view scrolls to latest new row
|
||||||
|
// connect (&m_->model_, &QAbstractItemModel::rowsInserted, this, [this] (QModelIndex const& parent, int first, int last) {
|
||||||
|
// // note col 0 is hidden so use col 1
|
||||||
|
// // queued connection required otherwise row may not be available
|
||||||
|
// // in time
|
||||||
|
// auto index = m_->model_.index (last, 1, parent);
|
||||||
|
// if (m_->log_view_)
|
||||||
|
// {
|
||||||
|
// m_->log_view_->scrollTo (index);
|
||||||
|
// }
|
||||||
|
// }, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractLogWindow::~AbstractLogWindow ()
|
AbstractLogWindow::~AbstractLogWindow ()
|
||||||
@ -102,23 +115,27 @@ void AbstractLogWindow::set_log_view (QTableView * log_view)
|
|||||||
SettingsGroup g {m_->settings_, m_->settings_key_};
|
SettingsGroup g {m_->settings_, m_->settings_key_};
|
||||||
restoreGeometry (m_->settings_->value ("window/geometry").toByteArray ());
|
restoreGeometry (m_->settings_->value ("window/geometry").toByteArray ());
|
||||||
m_->log_view_ = log_view;
|
m_->log_view_ = log_view;
|
||||||
m_->log_view_->setContextMenuPolicy (Qt::ActionsContextMenu);
|
set_log_view_font (m_->configuration_->decoded_text_font ());
|
||||||
m_->log_view_->setAlternatingRowColors (true);
|
log_view->setSortingEnabled (true);
|
||||||
m_->log_view_->setSelectionBehavior (QAbstractItemView::SelectRows);
|
log_view->setContextMenuPolicy (Qt::ActionsContextMenu);
|
||||||
m_->log_view_->setSelectionMode (QAbstractItemView::ExtendedSelection);
|
log_view->setAlternatingRowColors (true);
|
||||||
m_->model_.setSourceModel (m_->log_view_->model ());
|
log_view->setSelectionBehavior (QAbstractItemView::SelectRows);
|
||||||
m_->log_view_->setModel (&m_->model_);
|
log_view->setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||||
m_->log_view_->setColumnHidden (0, true);
|
log_view->setVerticalScrollMode (QAbstractItemView::ScrollPerPixel);
|
||||||
|
m_->model_.setSourceModel (log_view->model ());
|
||||||
|
log_view->setModel (&m_->model_);
|
||||||
|
log_view->setColumnHidden (0, true);
|
||||||
auto horizontal_header = log_view->horizontalHeader ();
|
auto horizontal_header = log_view->horizontalHeader ();
|
||||||
|
horizontal_header->setResizeContentsPrecision (0); // visible region only
|
||||||
horizontal_header->setSectionResizeMode (QHeaderView::ResizeToContents);
|
horizontal_header->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
horizontal_header->setSectionsMovable (true);
|
horizontal_header->setSectionsMovable (true);
|
||||||
m_->log_view_->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents);
|
auto vertical_header = log_view->horizontalHeader ();
|
||||||
set_log_view_font (m_->configuration_->decoded_text_font ());
|
vertical_header->setResizeContentsPrecision (0); // visible region only
|
||||||
m_->log_view_->scrollToBottom ();
|
vertical_header->setSectionResizeMode (QHeaderView::ResizeToContents);
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
auto delete_action = new QAction {tr ("&Delete ..."), m_->log_view_};
|
auto delete_action = new QAction {tr ("&Delete ..."), log_view};
|
||||||
m_->log_view_->insertAction (nullptr, delete_action);
|
log_view->insertAction (nullptr, delete_action);
|
||||||
connect (delete_action, &QAction::triggered, [this] (bool /*checked*/) {
|
connect (delete_action, &QAction::triggered, [this] (bool /*checked*/) {
|
||||||
m_->delete_QSOs ();
|
m_->delete_QSOs ();
|
||||||
});
|
});
|
||||||
@ -126,8 +143,8 @@ void AbstractLogWindow::set_log_view (QTableView * log_view)
|
|||||||
|
|
||||||
void AbstractLogWindow::set_log_view_font (QFont const& font)
|
void AbstractLogWindow::set_log_view_font (QFont const& font)
|
||||||
{
|
{
|
||||||
// m_->log_view_->setFont (font);
|
m_->log_view_->setFont (font);
|
||||||
// m_->log_view_->horizontalHeader ()->setFont (font);
|
m_->log_view_->horizontalHeader ()->setFont (font);
|
||||||
// m_->log_view_->verticalHeader ()->setFont (font);
|
m_->log_view_->verticalHeader ()->setFont (font);
|
||||||
m_->model_.set_font (font);
|
m_->model_.set_font (font);
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,9 @@ CabrilloLogWindow::CabrilloLogWindow (QSettings * settings, Configuration const
|
|||||||
set_log_view (m_->ui_.log_table_view);
|
set_log_view (m_->ui_.log_table_view);
|
||||||
m_->ui_.log_table_view->setItemDelegateForColumn (2, new DateTimeAsSecsSinceEpochDelegate {this});
|
m_->ui_.log_table_view->setItemDelegateForColumn (2, new DateTimeAsSecsSinceEpochDelegate {this});
|
||||||
m_->ui_.log_table_view->setItemDelegateForColumn (3, new CallsignDelegate {this});
|
m_->ui_.log_table_view->setItemDelegateForColumn (3, new CallsignDelegate {this});
|
||||||
m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), m_->log_model_, 0, 6, this});
|
m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), 0, this});
|
||||||
m_->ui_.log_table_view->horizontalHeader ()->moveSection (6, 1); // band to first column
|
auto h_header = m_->ui_.log_table_view->horizontalHeader ();
|
||||||
|
h_header->moveSection (6, 1); // band to first column
|
||||||
}
|
}
|
||||||
|
|
||||||
CabrilloLogWindow::~CabrilloLogWindow ()
|
CabrilloLogWindow::~CabrilloLogWindow ()
|
||||||
|
@ -6,31 +6,12 @@
|
|||||||
#include "models/DecodeHighlightingModel.hpp"
|
#include "models/DecodeHighlightingModel.hpp"
|
||||||
#include "MessageBox.hpp"
|
#include "MessageBox.hpp"
|
||||||
|
|
||||||
#include "pimpl_impl.hpp"
|
|
||||||
|
|
||||||
class DecodeHighlightingListView::impl final
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
impl ()
|
|
||||||
: fg_colour_action_ {tr ("&Foreground color ..."), nullptr}
|
|
||||||
, bg_colour_action_ {tr ("&Background color ..."), nullptr}
|
|
||||||
, defaults_action_ {tr ("&Reset this item to defaults"), nullptr}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DecodeHighlightingListView * self_;
|
|
||||||
QAction fg_colour_action_;
|
|
||||||
QAction bg_colour_action_;
|
|
||||||
QAction defaults_action_;
|
|
||||||
};
|
|
||||||
|
|
||||||
DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent)
|
DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent)
|
||||||
: QListView {parent}
|
: QListView {parent}
|
||||||
{
|
{
|
||||||
addAction (&m_->fg_colour_action_);
|
auto * fg_colour_action = new QAction {tr ("&Foreground color ..."), this};
|
||||||
addAction (&m_->bg_colour_action_);
|
addAction (fg_colour_action);
|
||||||
addAction (&m_->defaults_action_);
|
connect (fg_colour_action, &QAction::triggered, [this] (bool /*checked*/) {
|
||||||
connect (&m_->fg_colour_action_, &QAction::triggered, [this] (bool /*checked*/) {
|
|
||||||
auto const& index = currentIndex ();
|
auto const& index = currentIndex ();
|
||||||
auto colour = QColorDialog::getColor (model ()->data (index, Qt::ForegroundRole).value<QBrush> ().color ()
|
auto colour = QColorDialog::getColor (model ()->data (index, Qt::ForegroundRole).value<QBrush> ().color ()
|
||||||
, this
|
, this
|
||||||
@ -38,10 +19,19 @@ DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent)
|
|||||||
.arg (model ()->data (index).toString ()));
|
.arg (model ()->data (index).toString ()));
|
||||||
if (colour.isValid ())
|
if (colour.isValid ())
|
||||||
{
|
{
|
||||||
model ()->setData (index, colour, Qt::ForegroundRole);
|
model ()->setData (index, QBrush {colour}, Qt::ForegroundRole);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect (&m_->bg_colour_action_, &QAction::triggered, [this] (bool /*checked*/) {
|
|
||||||
|
auto * unset_fg_colour_action = new QAction {tr ("&Unset foreground color"), this};
|
||||||
|
addAction (unset_fg_colour_action);
|
||||||
|
connect (unset_fg_colour_action, &QAction::triggered, [this] (bool /*checked*/) {
|
||||||
|
model ()->setData (currentIndex (), QBrush {}, Qt::ForegroundRole);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto * bg_colour_action = new QAction {tr ("&Background color ..."), this};
|
||||||
|
addAction (bg_colour_action);
|
||||||
|
connect (bg_colour_action, &QAction::triggered, [this] (bool /*checked*/) {
|
||||||
auto const& index = currentIndex ();
|
auto const& index = currentIndex ();
|
||||||
auto colour = QColorDialog::getColor (model ()->data (index, Qt::BackgroundRole).value<QBrush> ().color ()
|
auto colour = QColorDialog::getColor (model ()->data (index, Qt::BackgroundRole).value<QBrush> ().color ()
|
||||||
, this
|
, this
|
||||||
@ -49,10 +39,19 @@ DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent)
|
|||||||
.arg (model ()->data (index).toString ()));
|
.arg (model ()->data (index).toString ()));
|
||||||
if (colour.isValid ())
|
if (colour.isValid ())
|
||||||
{
|
{
|
||||||
model ()->setData (index, colour, Qt::BackgroundRole);
|
model ()->setData (index, QBrush {colour}, Qt::BackgroundRole);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect (&m_->defaults_action_, &QAction::triggered, [this] (bool /*checked*/) {
|
|
||||||
|
auto * unset_bg_colour_action = new QAction {tr ("U&nset background color"), this};
|
||||||
|
addAction (unset_bg_colour_action);
|
||||||
|
connect (unset_bg_colour_action, &QAction::triggered, [this] (bool /*checked*/) {
|
||||||
|
model ()->setData (currentIndex (), QBrush {}, Qt::BackgroundRole);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto * defaults_action = new QAction {tr ("&Reset this item to defaults"), this};
|
||||||
|
addAction (defaults_action);
|
||||||
|
connect (defaults_action, &QAction::triggered, [this] (bool /*checked*/) {
|
||||||
auto const& index = currentIndex ();
|
auto const& index = currentIndex ();
|
||||||
model ()->setData (index, model ()->data (index, DecodeHighlightingModel::EnabledDefaultRole).toBool () ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
|
model ()->setData (index, model ()->data (index, DecodeHighlightingModel::EnabledDefaultRole).toBool () ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
|
||||||
model ()->setData (index, model ()->data (index, DecodeHighlightingModel::ForegroundDefaultRole), Qt::ForegroundRole);
|
model ()->setData (index, model ()->data (index, DecodeHighlightingModel::ForegroundDefaultRole), Qt::ForegroundRole);
|
||||||
@ -60,10 +59,6 @@ DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodeHighlightingListView::~DecodeHighlightingListView ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize DecodeHighlightingListView::sizeHint () const
|
QSize DecodeHighlightingListView::sizeHint () const
|
||||||
{
|
{
|
||||||
auto item_height = sizeHintForRow (0);
|
auto item_height = sizeHintForRow (0);
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include <QListView>
|
#include <QListView>
|
||||||
|
|
||||||
#include "pimpl_h.hpp"
|
|
||||||
|
|
||||||
class QWidget;
|
class QWidget;
|
||||||
|
|
||||||
// Class Decode Highlighting List View
|
// Class Decode Highlighting List View
|
||||||
@ -20,13 +18,9 @@ class DecodeHighlightingListView final
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DecodeHighlightingListView (QWidget * parent = nullptr);
|
explicit DecodeHighlightingListView (QWidget * parent = nullptr);
|
||||||
~DecodeHighlightingListView ();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSize sizeHint () const override;
|
QSize sizeHint () const override;
|
||||||
|
|
||||||
class impl;
|
|
||||||
pimpl<impl> m_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,7 +43,7 @@ FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configur
|
|||||||
m_->ui_.log_table_view->setItemDelegateForColumn (1, new DateTimeAsSecsSinceEpochDelegate {this});
|
m_->ui_.log_table_view->setItemDelegateForColumn (1, new DateTimeAsSecsSinceEpochDelegate {this});
|
||||||
m_->ui_.log_table_view->setItemDelegateForColumn (2, new CallsignDelegate {this});
|
m_->ui_.log_table_view->setItemDelegateForColumn (2, new CallsignDelegate {this});
|
||||||
m_->ui_.log_table_view->setItemDelegateForColumn (3, new MaidenheadLocatorDelegate {this});
|
m_->ui_.log_table_view->setItemDelegateForColumn (3, new MaidenheadLocatorDelegate {this});
|
||||||
m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), m_->log_model_, 0, 6, this});
|
m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), 0, this});
|
||||||
m_->ui_.log_table_view->horizontalHeader ()->moveSection (6, 1); // move band to first column
|
m_->ui_.log_table_view->horizontalHeader ()->moveSection (6, 1); // move band to first column
|
||||||
m_->ui_.rate_label->setNum (0);
|
m_->ui_.rate_label->setNum (0);
|
||||||
m_->ui_.queued_label->setNum (0);
|
m_->ui_.queued_label->setNum (0);
|
||||||
|