From 9520eb130924ad4f2959d0ee8461798d70d0b30f Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Wed, 28 Sep 2022 08:07:12 -0700 Subject: [PATCH 01/20] read/write QRG files with additional information; support JSON format for human inspection --- Configuration.cpp | 188 ++++++++++++++-- models/FrequencyList.cpp | 458 +++++++++++++++++++++++++++------------ models/FrequencyList.hpp | 42 +++- 3 files changed, 531 insertions(+), 157 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index e45bc99af..1e7f83e93 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -168,6 +168,11 @@ #include #include #include +#include +#include +#include +#include + #include "pimpl_impl.hpp" #include "Logger.hpp" @@ -250,7 +255,8 @@ namespace // Magic numbers for file validation constexpr quint32 qrg_magic {0xadbccbdb}; - constexpr quint32 qrg_version {100}; // M.mm + constexpr quint32 qrg_version {101}; // M.mm + constexpr quint32 qrg_version_100 {100}; } @@ -268,8 +274,21 @@ public: explicit FrequencyDialog (IARURegions * regions_model, Modes * modes_model, QWidget * parent = nullptr) : QDialog {parent} { + start_date_time_edit_ = new QDateTimeEdit(QDateTime(QDate::currentDate(), QTime(0,0,0,0), Qt::UTC), parent); + end_date_time_edit_ = new QDateTimeEdit(QDateTime(QDate::currentDate().addDays(2), QTime(0,0,0,0), Qt::UTC), parent); + + enable_dates_checkbox_ = new QCheckBox {tr ("Validity Period")}; + start_date_time_edit_->setDisplayFormat("yyyy.MM.dd hh:mm:ss 'UTC'"); + start_date_time_edit_->setTimeSpec(Qt::UTC); + start_date_time_edit_->setMinimumDate(QDate::currentDate().addDays(-365)); + + end_date_time_edit_->setDisplayFormat("yyyy.MM.dd hh:mm:ss 'UTC'"); + end_date_time_edit_->setTimeSpec(Qt::UTC); + end_date_time_edit_->setMinimumDate(QDate::currentDate().addDays(-365)); + setWindowTitle (QApplication::applicationName () + " - " + tr ("Add Frequency")); + region_combo_box_.setModel (regions_model); mode_combo_box_.setModel (modes_model); @@ -277,28 +296,71 @@ public: form_layout->addRow (tr ("IARU &Region:"), ®ion_combo_box_); form_layout->addRow (tr ("&Mode:"), &mode_combo_box_); form_layout->addRow (tr ("&Frequency (MHz):"), &frequency_line_edit_); + form_layout->addRow (tr ("&Enable Date Range"), enable_dates_checkbox_); + form_layout->addRow (tr ("S&tart:"), start_date_time_edit_); + form_layout->addRow (tr ("&End:"), end_date_time_edit_); + form_layout->addRow (tr ("&Description:"), &description_line_edit_); + form_layout->addRow (tr ("&Source:"), &source_line_edit_); auto main_layout = new QVBoxLayout (this); main_layout->addLayout (form_layout); - auto button_box = new QDialogButtonBox {QDialogButtonBox::Ok | QDialogButtonBox::Cancel}; + button_box = new QDialogButtonBox {QDialogButtonBox::Ok | QDialogButtonBox::Cancel}; main_layout->addWidget (button_box); connect (button_box, &QDialogButtonBox::accepted, this, &FrequencyDialog::accept); connect (button_box, &QDialogButtonBox::rejected, this, &FrequencyDialog::reject); + connect(start_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates); + connect(end_date_time_edit_, &QDateTimeEdit::dateTimeChanged, this, &FrequencyDialog::checkSaneDates); + connect(enable_dates_checkbox_, &QCheckBox::stateChanged, this, &FrequencyDialog::toggleValidity); + toggleValidity(); } + void toggleValidity() + { + start_date_time_edit_->setEnabled(enable_dates_checkbox_->isChecked()); + end_date_time_edit_->setEnabled(enable_dates_checkbox_->isChecked()); + checkSaneDates(); + } + + void checkSaneDates() + { + if (enable_dates_checkbox_->isChecked() && start_date_time_edit_->dateTime().isValid() && end_date_time_edit_->dateTime().isValid()) + { + if (start_date_time_edit_->dateTime() > end_date_time_edit_->dateTime()) + { + QMessageBox::warning(this, tr("Invalid Date Range"), tr("Start date must be before end date")); + button_box->button(QDialogButtonBox::Ok)->setEnabled(false); + return; + } + } + button_box->button(QDialogButtonBox::Ok)->setEnabled(true); + } + Item item () const { - return {frequency_line_edit_.frequency () - , Modes::value (mode_combo_box_.currentText ()) - , IARURegions::value (region_combo_box_.currentText ())}; + QDateTime start_time = enable_dates_checkbox_->isChecked() ? start_date_time_edit_->dateTime() : QDateTime(); + QDateTime end_time = enable_dates_checkbox_->isChecked() ? end_date_time_edit_->dateTime() : QDateTime(); + return { + frequency_line_edit_.frequency(), + Modes::value(mode_combo_box_.currentText()), + IARURegions::value(region_combo_box_.currentText()), + description_line_edit_.text(), source_line_edit_.text(), + start_time, + end_time + }; } private: QComboBox region_combo_box_; QComboBox mode_combo_box_; FrequencyLineEdit frequency_line_edit_; + QLineEdit description_line_edit_; + QLineEdit source_line_edit_; + QDialogButtonBox * button_box; + QCheckBox *enable_dates_checkbox_; + QDateTimeEdit *end_date_time_edit_; + QDateTimeEdit *start_date_time_edit_; }; @@ -477,7 +539,9 @@ private: void save_frequencies (); void reset_frequencies (); void insert_frequency (); - FrequencyList_v2::FrequencyItems read_frequencies_file (QString const&); + void size_frequency_table_columns(); + + FrequencyList_v2::FrequencyItems read_frequencies_file (QString const&); void delete_stations (); void insert_station (); @@ -1198,6 +1262,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network ui_->frequencies_table_view->setModel (&next_frequencies_); ui_->frequencies_table_view->horizontalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents); + ui_->frequencies_table_view->horizontalHeader ()->setResizeContentsPrecision (0); ui_->frequencies_table_view->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents); ui_->frequencies_table_view->verticalHeader ()->setResizeContentsPrecision (0); @@ -2508,17 +2573,25 @@ void Configuration::impl::check_multicast (QHostAddress const& ha) udp_server_name_edited_ = false; } +void Configuration::impl::size_frequency_table_columns() +{ + ui_->frequencies_table_view->setVisible(false); + ui_->frequencies_table_view->resizeColumnsToContents(); + ui_->frequencies_table_view->setVisible(true); +} + void Configuration::impl::delete_frequencies () { auto selection_model = ui_->frequencies_table_view->selectionModel (); selection_model->select (selection_model->selection (), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); next_frequencies_.removeDisjointRows (selection_model->selectedRows ()); ui_->frequencies_table_view->resizeColumnToContents (FrequencyList_v2::mode_column); + size_frequency_table_columns (); } void Configuration::impl::load_frequencies () { - auto file_name = QFileDialog::getOpenFileName (this, tr ("Load Working Frequencies"), writeable_data_dir_.absolutePath (), tr ("Frequency files (*.qrg);;All files (*.*)")); + auto file_name = QFileDialog::getOpenFileName (this, tr ("Load Working Frequencies"), writeable_data_dir_.absolutePath (), tr ("Frequency files (*.qrg *.qrg.json);;All files (*.*)")); if (!file_name.isNull ()) { auto const list = read_frequencies_file (file_name); @@ -2532,15 +2605,17 @@ void Configuration::impl::load_frequencies () { next_frequencies_.frequency_list (list); // update the model } + size_frequency_table_columns(); } } void Configuration::impl::merge_frequencies () { - auto file_name = QFileDialog::getOpenFileName (this, tr ("Merge Working Frequencies"), writeable_data_dir_.absolutePath (), tr ("Frequency files (*.qrg);;All files (*.*)")); + auto file_name = QFileDialog::getOpenFileName (this, tr ("Merge Working Frequencies"), writeable_data_dir_.absolutePath (), tr ("Frequency files (*.qrg *.qrg.json);;All files (*.*)")); if (!file_name.isNull ()) { next_frequencies_.frequency_list_merge (read_frequencies_file (file_name)); // update the model + size_frequency_table_columns(); } } @@ -2550,6 +2625,62 @@ FrequencyList_v2::FrequencyItems Configuration::impl::read_frequencies_file (QSt frequencies_file.open (QFile::ReadOnly); QDataStream ids {&frequencies_file}; FrequencyList_v2::FrequencyItems list; + FrequencyList_v2_100::FrequencyItems list_v100; + + // read file as json if ends with qrg.json + if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) + { + QJsonDocument doc = QJsonDocument::fromJson(frequencies_file.readAll()); + if (doc.isNull()) + { + MessageBox::critical_message (this, tr ("Error reading frequencies file"), tr ("%1 - Invalid Format").arg (file_name)); + return list; + } + QJsonObject obj = doc.object(); + if (obj.isEmpty()) + { + MessageBox::critical_message (this, tr ("Error reading frequencies file"), tr ("%1 - Information Missing ").arg (file_name)); + return list; + } + QJsonArray arr = obj["frequencies"].toArray(); + if (arr.isEmpty()) + { + MessageBox::critical_message (this, tr ("Error reading frequencies file"), tr ("No Frequencies were found")); + return list; + } + int valid_entry_count = 0; + int skipped_entry_count = 0; + for (auto const &item: arr) + { + QString mode_s, region_s; + QJsonObject obj = item.toObject(); + FrequencyList_v2::Item freq; + region_s = obj["region"].toString(); + mode_s = obj["mode"].toString(); + + freq.frequency_ = obj["frequency"].toString().toDouble() * 1e6; + freq.region_ = IARURegions::value(region_s); + freq.mode_ = Modes::value(mode_s); + freq.description_ = obj["description"].toString(); + freq.source_ = obj["source"].toString(); + freq.start_time_ = QDateTime::fromString(obj["start_time"].toString(), Qt::ISODate); + freq.end_time_ = QDateTime::fromString(obj["end_time"].toString(), Qt::ISODate); + //MessageBox::critical_message (this, tr ("Entry"), tr ("Entry: %1 ").arg(freq.toString()+"[sane:" +freq.isSane() + "] [region:" + obj["region"].toString() + "] [mode:" + obj["mode"].toString()+"] ")); + if ((freq.mode_ != Modes::ALL || QString::compare("ALL", mode_s)) && + (freq.region_ != IARURegions::ALL || QString::compare("ALL", region_s, Qt::CaseInsensitive)) && + freq.isSane()) + { + list.push_back(freq); + valid_entry_count++; + } else + skipped_entry_count++; + } + MessageBox::information_message(this, tr("Loaded Frequencies from %1").arg(file_name), + tr("Entries Valid/Skipped %1").arg(QString::number(valid_entry_count) + "/" + + QString::number(skipped_entry_count))); + return list; + } + quint32 magic; ids >> magic; if (qrg_magic != magic) @@ -2568,8 +2699,19 @@ FrequencyList_v2::FrequencyItems Configuration::impl::read_frequencies_file (QSt } // de-serialize the data using version if necessary to - // handle old schemata - ids >> list; + // handle old schema + if (version == qrg_version_100) + { + ids >> list_v100; + Q_FOREACH (auto const& item, list_v100) + { + list << FrequencyList_v2::Item{item.frequency_, item.mode_, item.region_, QString(), QString(), QDateTime(),QDateTime()}; + } + } + else + { + ids >> list; + } if (ids.status () != QDataStream::Ok || !ids.atEnd ()) { @@ -2577,13 +2719,12 @@ FrequencyList_v2::FrequencyItems Configuration::impl::read_frequencies_file (QSt list.clear (); return list; } - return list; } void Configuration::impl::save_frequencies () { - auto file_name = QFileDialog::getSaveFileName (this, tr ("Save Working Frequencies"), writeable_data_dir_.absolutePath (), tr ("Frequency files (*.qrg);;All files (*.*)")); + auto file_name = QFileDialog::getSaveFileName (this, tr ("Save Working Frequencies"), writeable_data_dir_.absolutePath (), tr ("Frequency files (*.qrg *.qrg.json);;All files (*.*)")); if (!file_name.isNull ()) { QFile frequencies_file {file_name}; @@ -2598,11 +2739,28 @@ void Configuration::impl::save_frequencies () "Click No to save all."))) { selection_model->select (selection_model->selection (), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); - ods << qrg_magic << qrg_version << next_frequencies_.frequency_list (selection_model->selectedRows ()); + if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) + { + next_frequencies_.to_json_stream(&ods, "0x" + QString::number(qrg_magic, 16).toUpper(), + "0x" + QString::number(qrg_version, 16).toUpper(), + next_frequencies_.frequency_list(selection_model->selectedRows())); + } else + { + ods << qrg_magic << qrg_version << next_frequencies_.frequency_list(selection_model->selectedRows()); + } } else { - ods << qrg_magic << qrg_version << next_frequencies_.frequency_list (); + if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) + { + next_frequencies_.to_json_stream(&ods, + "0x" + QString::number(qrg_magic, 16).toUpper(), + "0x" + QString::number(qrg_version, 16).toUpper(), + next_frequencies_.frequency_list()); + } else + { + ods << qrg_magic << qrg_version << next_frequencies_.frequency_list(); + } } } } @@ -2616,6 +2774,7 @@ void Configuration::impl::reset_frequencies () { next_frequencies_.reset_to_defaults (); } + size_frequency_table_columns (); } void Configuration::impl::insert_frequency () @@ -2624,6 +2783,7 @@ void Configuration::impl::insert_frequency () { ui_->frequencies_table_view->setCurrentIndex (next_frequencies_.add (frequency_dialog_->item ())); ui_->frequencies_table_view->resizeColumnToContents (FrequencyList_v2::mode_column); + size_frequency_table_columns(); } } diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index cac85ea5a..e04a7a184 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -5,6 +5,7 @@ #include #include + #include #include #include @@ -17,10 +18,16 @@ #include #include #include +#include +#include +#include +#include +#include #include "Radio.hpp" #include "Bands.hpp" #include "pimpl_impl.hpp" +#include "revision_utils.hpp" #include "moc_FrequencyList.cpp" @@ -28,40 +35,40 @@ namespace { FrequencyList_v2::FrequencyItems const default_frequency_list = { - {198000, Modes::FreqCal, IARURegions::R1}, // BBC Radio 4 Droitwich - {4996000, Modes::FreqCal, IARURegions::R1}, // RWM time signal - {9996000, Modes::FreqCal, IARURegions::R1}, // RWM time signal - {14996000, Modes::FreqCal, IARURegions::R1}, // RWM time signal + {198000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // BBC Radio 4 Droitwich + {4996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // RWM time signal + {9996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // RWM time signal + {14996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // RWM time signal - {660000, Modes::FreqCal, IARURegions::R2}, - {880000, Modes::FreqCal, IARURegions::R2}, - {1210000, Modes::FreqCal, IARURegions::R2}, + {660000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {880000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {1210000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {2500000, Modes::FreqCal, IARURegions::ALL}, - {3330000, Modes::FreqCal, IARURegions::ALL}, - {5000000, Modes::FreqCal, IARURegions::ALL}, - {7850000, Modes::FreqCal, IARURegions::ALL}, - {10000000, Modes::FreqCal, IARURegions::ALL}, - {14670000, Modes::FreqCal, IARURegions::ALL}, - {15000000, Modes::FreqCal, IARURegions::ALL}, - {20000000, Modes::FreqCal, IARURegions::ALL}, + {2500000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {3330000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {5000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {7850000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {10000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {14670000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {15000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {20000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {136000, Modes::WSPR, IARURegions::ALL}, - {136000, Modes::FST4, IARURegions::ALL}, - {136000, Modes::FST4W, IARURegions::ALL}, - {136000, Modes::JT9, IARURegions::ALL}, + {136000, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {136000, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {136000, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {136000, Modes::JT9, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {474200, Modes::JT9, IARURegions::ALL}, - {474200, Modes::FST4, IARURegions::ALL}, - {474200, Modes::WSPR, IARURegions::ALL}, - {474200, Modes::FST4W, IARURegions::ALL}, + {474200, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {474200, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {474200, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {474200, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {1836600, Modes::WSPR, IARURegions::ALL}, - {1836800, Modes::FST4W, IARURegions::ALL}, - {1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations - {1839000, Modes::JT9, IARURegions::ALL}, - {1839000, Modes::FST4, IARURegions::ALL}, - {1840000, Modes::FT8, IARURegions::ALL}, + {1836600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {1836800, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {1838000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // squeezed allocations + {1839000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {1839000, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {1840000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // Band plans (all USB dial unless stated otherwise) // @@ -90,12 +97,12 @@ namespace // 3580 PSK31 // 3600 LSB EMCOMM // - {3570000, Modes::JT65, IARURegions::ALL}, // JA compatible - {3572000, Modes::JT9, IARURegions::ALL}, - {3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65 is out of DM allocation - {3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker and lock out - {3575000, Modes::FT4, IARURegions::ALL}, // provisional - {3568000, Modes::FT4, IARURegions::R3}, // provisional + {3570000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // JA compatible + {3572000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {3573000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // above as below JT65 is out of DM allocation + {3568600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // needs guard marker and lock out + {3575000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional + {3568000, Modes::FT4, IARURegions::R3, "","", QDateTime(), QDateTime()}, // provisional // Band plans (all USB dial unless stated otherwise) // @@ -128,11 +135,11 @@ namespace // 7090 LSB QRP CoA // 7110 LSB EMCOMM // - {7038600, Modes::WSPR, IARURegions::ALL}, - {7074000, Modes::FT8, IARURegions::ALL}, - {7076000, Modes::JT65, IARURegions::ALL}, - {7078000, Modes::JT9, IARURegions::ALL}, - {7047500, Modes::FT4, IARURegions::ALL}, // provisional - moved + {7038600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {7074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {7076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {7078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {7047500, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional - moved // up 500Hz to clear // W1AW code practice QRG @@ -162,11 +169,11 @@ namespace // 10142.25 OLIVIA, Contestia, etc. // 10143.25 OLIVIA, Contestia, etc. (main QRG) // - {10136000, Modes::FT8, IARURegions::ALL}, - {10138000, Modes::JT65, IARURegions::ALL}, - {10138700, Modes::WSPR, IARURegions::ALL}, - {10140000, Modes::JT9, IARURegions::ALL}, - {10140000, Modes::FT4, IARURegions::ALL}, // provisional + {10136000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {10138000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {10138700, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {10140000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {10140000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional // Band plans (all USB dial unless stated otherwise) // @@ -205,11 +212,11 @@ namespace // 14105.5 OLIVIA 1000 // 14106.5 OLIVIA 1000 (main QRG) // - {14095600, Modes::WSPR, IARURegions::ALL}, - {14074000, Modes::FT8, IARURegions::ALL}, - {14076000, Modes::JT65, IARURegions::ALL}, - {14078000, Modes::JT9, IARURegions::ALL}, - {14080000, Modes::FT4, IARURegions::ALL}, // provisional + {14095600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {14074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {14076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {14078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {14080000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional // Band plans (all USB dial unless stated otherwise) // @@ -238,111 +245,111 @@ namespace // 18104.4 OLIVIA, Contestia, etc. // 18110 NCDXF beacons // - {18100000, Modes::FT8, IARURegions::ALL}, - {18102000, Modes::JT65, IARURegions::ALL}, - {18104000, Modes::JT9, IARURegions::ALL}, - {18104000, Modes::FT4, IARURegions::ALL}, // provisional - {18104600, Modes::WSPR, IARURegions::ALL}, + {18100000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {18102000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {18104000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {18104000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional + {18104600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {21074000, Modes::FT8, IARURegions::ALL}, - {21076000, Modes::JT65, IARURegions::ALL}, - {21078000, Modes::JT9, IARURegions::ALL}, - {21094600, Modes::WSPR, IARURegions::ALL}, - {21140000, Modes::FT4, IARURegions::ALL}, + {21074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {21076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {21078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {21094600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {21140000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {24915000, Modes::FT8, IARURegions::ALL}, - {24917000, Modes::JT65, IARURegions::ALL}, - {24919000, Modes::JT9, IARURegions::ALL}, - {24919000, Modes::FT4, IARURegions::ALL}, // provisional - {24924600, Modes::WSPR, IARURegions::ALL}, + {24915000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {24917000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {24919000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {24919000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional + {24924600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {28074000, Modes::FT8, IARURegions::ALL}, - {28076000, Modes::JT65, IARURegions::ALL}, - {28078000, Modes::JT9, IARURegions::ALL}, - {28124600, Modes::WSPR, IARURegions::ALL}, - {28180000, Modes::FT4, IARURegions::ALL}, + {28074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {28076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {28078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {28124600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {28180000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {50200000, Modes::Echo, IARURegions::ALL}, - {50211000, Modes::Q65, IARURegions::ALL}, - {50275000, Modes::Q65, IARURegions::ALL}, - {50276000, Modes::JT65, IARURegions::R2}, - {50276000, Modes::JT65, IARURegions::R3}, - {50380000, Modes::MSK144, IARURegions::R1}, - {50260000, Modes::MSK144, IARURegions::R2}, - {50260000, Modes::MSK144, IARURegions::R3}, - {50293000, Modes::WSPR, IARURegions::R2}, - {50293000, Modes::WSPR, IARURegions::R3}, - {50310000, Modes::JT65, IARURegions::ALL}, - {50312000, Modes::JT9, IARURegions::ALL}, - {50313000, Modes::FT8, IARURegions::ALL}, - {50318000, Modes::FT4, IARURegions::ALL}, // provisional - {50323000, Modes::FT8, IARURegions::ALL}, + {50200000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {50211000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {50275000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {50276000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {50276000, Modes::JT65, IARURegions::R3, "","", QDateTime(), QDateTime()}, + {50380000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime()}, + {50260000, Modes::MSK144, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {50260000, Modes::MSK144, IARURegions::R3, "","", QDateTime(), QDateTime()}, + {50293000, Modes::WSPR, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {50293000, Modes::WSPR, IARURegions::R3, "","", QDateTime(), QDateTime()}, + {50310000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {50312000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {50313000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {50318000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional + {50323000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {70102000, Modes::JT65, IARURegions::R1}, - {70104000, Modes::JT9, IARURegions::R1}, - {70091000, Modes::WSPR, IARURegions::R1}, - {70154000, Modes::FT8, IARURegions::R1}, - {70230000, Modes::MSK144, IARURegions::R1}, + {70102000, Modes::JT65, IARURegions::R1, "","", QDateTime(), QDateTime()}, + {70104000, Modes::JT9, IARURegions::R1, "","", QDateTime(), QDateTime()}, + {70091000, Modes::WSPR, IARURegions::R1, "","", QDateTime(), QDateTime()}, + {70154000, Modes::FT8, IARURegions::R1, "","", QDateTime(), QDateTime()}, + {70230000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime()}, - {144116000, Modes::Q65, IARURegions::ALL}, - {144120000, Modes::JT65, IARURegions::ALL}, - {144120000, Modes::Echo, IARURegions::ALL}, - {144170000, Modes::FT4, IARURegions::ALL}, - {144174000, Modes::FT8, IARURegions::ALL}, - {144360000, Modes::MSK144, IARURegions::R1}, - {144150000, Modes::MSK144, IARURegions::R2}, - {144489000, Modes::WSPR, IARURegions::ALL}, + {144116000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {144120000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {144120000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {144170000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {144174000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {144360000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime()}, + {144150000, Modes::MSK144, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {144489000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {222065000, Modes::Echo, IARURegions::R2}, - {222065000, Modes::JT65, IARURegions::R2}, - {222065000, Modes::Q65, IARURegions::R2}, + {222065000, Modes::Echo, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {222065000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {222065000, Modes::Q65, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {432065000, Modes::Echo, IARURegions::ALL}, - {432065000, Modes::JT65, IARURegions::ALL}, - {432300000, Modes::WSPR, IARURegions::ALL}, - {432360000, Modes::MSK144, IARURegions::ALL}, - {432065000, Modes::Q65, IARURegions::ALL}, + {432065000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {432065000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {432300000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {432360000, Modes::MSK144, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {432065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {902065000, Modes::JT65, IARURegions::R2}, - {902065000, Modes::Q65, IARURegions::R2}, + {902065000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {902065000, Modes::Q65, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {1296065000, Modes::Echo, IARURegions::ALL}, - {1296065000, Modes::JT65, IARURegions::ALL}, - {1296500000, Modes::WSPR, IARURegions::ALL}, - {1296065000, Modes::Q65, IARURegions::ALL}, + {1296065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {1296065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {1296500000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {1296065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2301000000, Modes::Echo, IARURegions::ALL}, - {2301065000, Modes::JT4, IARURegions::ALL}, - {2301065000, Modes::JT65, IARURegions::ALL}, - {2301065000, Modes::Q65, IARURegions::ALL}, + {2301000000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {2301065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2301065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2301065000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {2304065000, Modes::Echo, IARURegions::ALL}, - {2304065000, Modes::JT4, IARURegions::ALL}, - {2304065000, Modes::JT65, IARURegions::ALL}, - {2304065000, Modes::Q65, IARURegions::ALL}, + {2304065000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {2304065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2304065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2304065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2320065000, Modes::Echo, IARURegions::ALL}, - {2320065000, Modes::JT4, IARURegions::ALL}, - {2320065000, Modes::JT65, IARURegions::ALL}, - {2320065000, Modes::Q65, IARURegions::ALL}, + {2320065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2320065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2320065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2320065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {3400065000, Modes::Echo, IARURegions::ALL}, - {3400065000, Modes::JT4, IARURegions::ALL}, - {3400065000, Modes::JT65, IARURegions::ALL}, - {3400065000, Modes::Q65, IARURegions::ALL}, + {3400065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {3400065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {3400065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {3400065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {5760065000, Modes::Echo, IARURegions::ALL}, - {5760065000, Modes::JT4, IARURegions::ALL}, - {5760065000, Modes::JT65, IARURegions::ALL}, - {5760200000, Modes::Q65, IARURegions::ALL}, + {5760065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {5760065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {5760065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {5760200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {10368100000, Modes::Echo, IARURegions::ALL}, - {10368200000, Modes::JT4, IARURegions::ALL}, - {10368200000, Modes::Q65, IARURegions::ALL}, + {10368100000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {10368200000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {10368200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {24048100000, Modes::Echo, IARURegions::ALL}, - {24048200000, Modes::JT4, IARURegions::ALL}, - {24048200000, Modes::Q65, IARURegions::ALL}, + {24048100000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {24048200000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {24048200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, }; } @@ -353,6 +360,11 @@ QDebug operator << (QDebug debug, FrequencyList_v2::Item const& item) return debug.nospace () << item.toString (); } #endif +bool FrequencyList_v2::Item::isSane() const +{ + return frequency_ > 0.0 && (!start_time_.isValid() || !end_time_.isValid() || start_time_ < end_time_) + && (region_ == IARURegions::ALL || region_ == IARURegions::R1 || region_ == IARURegions::R2 || region_ == IARURegions::R3); +} QString FrequencyList_v2::Item::toString () const { @@ -361,22 +373,45 @@ QString FrequencyList_v2::Item::toString () const qts << "FrequencyItem(" << Radio::frequency_MHz_string (frequency_) << ", " << IARURegions::name (region_) << ", " - << Modes::name (mode_) << ')'; + << Modes::name (mode_) << ", " + << start_time_.toString(Qt::ISODate) << ", " + << end_time_.toString(Qt::ISODate) << ", " + << description_ << ", " + << source_ << ')'; + return string; } +QJsonObject FrequencyList_v2::Item::toJson() const { + return {{"frequency", Radio::frequency_MHz_string (frequency_) }, + {"mode", Modes::name (mode_) }, + {"region", IARURegions::name (region_)}, + {"description", description_}, + {"source", source_}, + {"start_time", start_time_.toString(Qt::ISODate) }, + {"end_time", end_time_.toString(Qt::ISODate)}}; +} + QDataStream& operator << (QDataStream& os, FrequencyList_v2::Item const& item) { return os << item.frequency_ << item.mode_ - << item.region_; + << item.region_ + << item.start_time_ + << item.end_time_ + << item.description_ + << item.source_; } QDataStream& operator >> (QDataStream& is, FrequencyList_v2::Item& item) { return is >> item.frequency_ >> item.mode_ - >> item.region_; + >> item.region_ + >> item.start_time_ + >> item.end_time_ + >> item.description_ + >> item.source_; } class FrequencyList_v2::impl final @@ -453,6 +488,7 @@ void FrequencyList_v2::frequency_list_merge (FrequencyItems const& items) m_->add (items); } + int FrequencyList_v2::best_working_frequency (Frequency f) const { int result {-1}; @@ -761,6 +797,93 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const break; } break; + + case description_column: + switch (role) + { + case SortRole: + case Qt::DisplayRole: + case Qt::EditRole: + case Qt::AccessibleTextRole: + item = frequency_item.description_; + break; + + case Qt::ToolTipRole: + case Qt::AccessibleDescriptionRole: + item = tr ("Description"); + break; + + case Qt::TextAlignmentRole: + item = Qt::AlignLeft + Qt::AlignVCenter; + break; + } + break; + + case source_column: + switch (role) + { + case SortRole: + case Qt::DisplayRole: + case Qt::EditRole: + case Qt::AccessibleTextRole: + item = frequency_item.start_time_ == frequency_item.end_time_ + ? tr ("Equal") + : tr ("NOTEQUAL"); + item = frequency_item.source_; + break; + + case Qt::ToolTipRole: + case Qt::AccessibleDescriptionRole: + item = tr ("Source"); + break; + + case Qt::TextAlignmentRole: + item = Qt::AlignLeft + Qt::AlignVCenter; + break; + } + break; + + case start_time_column: + switch (role) + { + case SortRole: + case Qt::DisplayRole: + case Qt::EditRole: + case Qt::AccessibleTextRole: + item = frequency_item.start_time_.toString(Qt::ISODate); + break; + + case Qt::ToolTipRole: + case Qt::AccessibleDescriptionRole: + item = tr ("Start Time"); + break; + + case Qt::TextAlignmentRole: + item = Qt::AlignLeft + Qt::AlignVCenter; + break; + } + break; + + case end_time_column: + switch (role) + { + case SortRole: + case Qt::DisplayRole: + case Qt::EditRole: + case Qt::AccessibleTextRole: + item = frequency_item.end_time_.toString(Qt::ISODate); + break; + + case Qt::ToolTipRole: + case Qt::AccessibleDescriptionRole: + item = tr ("End Time"); + break; + + case Qt::TextAlignmentRole: + item = Qt::AlignLeft + Qt::AlignVCenter; + break; + } + break; } } return item; @@ -837,6 +960,10 @@ QVariant FrequencyList_v2::impl::headerData (int section, Qt::Orientation orient case mode_column: header = tr ("Mode"); break; case frequency_column: header = tr ("Frequency"); break; case frequency_mhz_column: header = tr ("Frequency (MHz)"); break; + case description_column: header = tr ("Description"); break; + case source_column: header = tr ("Source"); break; + case start_time_column: header = tr ("Start"); break; + case end_time_column: header = tr ("End"); break; } } else @@ -868,7 +995,7 @@ bool FrequencyList_v2::impl::insertRows (int row, int count, QModelIndex const& beginInsertRows (parent, row, row + count - 1); for (auto r = 0; r < count; ++r) { - frequency_list_.insert (row, Item {0, Mode::ALL, IARURegions::ALL}); + frequency_list_.insert (row, Item {0, Mode::ALL, IARURegions::ALL, QString(), QString(), QDateTime(), QDateTime()}); } endInsertRows (); return true; @@ -977,6 +1104,53 @@ auto FrequencyList_v2::all_bands (Region region, Mode mode) const -> BandSet return result; } +// write JSON format to a file +void FrequencyList_v2::to_json_stream(QDataStream *ods, QString magic_s, QString version_s, + FrequencyItems const &frequency_items) +{ + QJsonObject jobject{ + {"wsjtx_file", "qrg"}, + {"wsjtx_version", QCoreApplication::applicationVersion()+" "+revision()}, + {"generated_at", QDateTime::currentDateTimeUtc ().toString (Qt::ISODate)}, + {"wsjtx_filetype", magic_s}, + {"qrg_version", version_s}, + {"frequency_count", frequency_items.count()}}; + + QJsonArray array; + for (auto &item: frequency_items) + array.append(item.toJson()); + jobject["frequencies"] = array; + + QJsonDocument d = QJsonDocument(jobject); + ods->writeRawData(d.toJson().data(), d.toJson().size()); +} + +QTextStream& qStdOut() +{ + static QTextStream ts( stdout ); + return ts; +} + +FrequencyList_v2::FrequencyItems FrequencyList_v2::from_json_file(QFile *input_file) +{ + // attempt to read the file as JSON + FrequencyList_v2::FrequencyItems list; + QByteArray jsonData = input_file->readAll(); + QJsonDocument jsonDoc(QJsonDocument::fromJson(jsonData)); + QJsonArray array = jsonDoc.object().value("frequencies").toArray(); + qStdOut() << "Frequencies read"; + qStdOut() << array.count(); + return list; +} + +// previous version 100 of the FrequencyList_v2 class +QDataStream& operator >> (QDataStream& is, FrequencyList_v2_100::Item& item) +{ + return is >> item.frequency_ + >> item.mode_ + >> item.region_; +} + // // Obsolete version of FrequencyList no longer used but needed to // allow loading and saving of old settings contents without damage diff --git a/models/FrequencyList.hpp b/models/FrequencyList.hpp index a3b9c117a..40002762c 100644 --- a/models/FrequencyList.hpp +++ b/models/FrequencyList.hpp @@ -5,6 +5,10 @@ #include #include +#include +#include +#include +#include #include "Radio.hpp" #include "IARURegions.hpp" @@ -53,11 +57,18 @@ public: Mode mode_; Region region_; QString toString () const; + bool isSane() const; + QJsonObject toJson () const; + QString description_; + QString source_; + QDateTime start_time_; + QDateTime end_time_; + }; using FrequencyItems = QList; using BandSet = QSet; - enum Column {region_column, mode_column, frequency_column, frequency_mhz_column, SENTINAL}; + enum Column {region_column, mode_column, frequency_column, frequency_mhz_column, description_column, start_time_column, end_time_column, source_column, SENTINAL}; // an iterator that meets the requirements of the C++ for range statement class const_iterator @@ -78,9 +89,11 @@ public: private: FrequencyList_v2 const * parent_; int row_; + //qint32 qrg_version_; }; explicit FrequencyList_v2 (Bands const *, QObject * parent = nullptr); + ~FrequencyList_v2 (); // Load and store underlying items @@ -88,6 +101,8 @@ public: FrequencyItems const& frequency_list () const; FrequencyItems frequency_list (QModelIndexList const&) const; void frequency_list_merge (FrequencyItems const&); + void to_json_stream(QDataStream *, QString, QString, FrequencyItems const&); + FrequencyList_v2::FrequencyItems from_json_file(QFile *); // Iterators for the sorted and filtered items // @@ -156,6 +171,31 @@ QDebug operator << (QDebug, FrequencyList_v2::Item const&); Q_DECLARE_METATYPE (FrequencyList_v2::Item); Q_DECLARE_METATYPE (FrequencyList_v2::FrequencyItems); +class FrequencyList_v2_100 final +{ +public: + using Frequency = Radio::Frequency; + using Mode = Modes::Mode; + using Region = IARURegions::Region; + + struct Item + { + Frequency frequency_; + Mode mode_; + Region region_; + QString toString () const; + }; + using FrequencyItems = QList; + +private: + FrequencyItems frequency_list_; +}; + +QDataStream& operator << (QDataStream&, FrequencyList_v2_100::Item const&); +QDataStream& operator >> (QDataStream&, FrequencyList_v2_100::Item&); + +Q_DECLARE_METATYPE (FrequencyList_v2_100::Item); +Q_DECLARE_METATYPE (FrequencyList_v2_100::FrequencyItems); // // Obsolete version of FrequencyList no longer used but needed to From 923de0ef38e45450e05d1445b3ff43aa1a38a492 Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Thu, 29 Sep 2022 08:39:22 -0700 Subject: [PATCH 02/20] move MessageItemDelegate to its own file --- CMakeLists.txt | 1 + item_delegates/MessageItemDelegate.cpp | 26 ++++++++++++++++++++++++++ item_delegates/MessageItemDelegate.hpp | 20 ++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 item_delegates/MessageItemDelegate.cpp create mode 100644 item_delegates/MessageItemDelegate.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0889c79bf..cd770c66a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,7 @@ set (wsjt_qt_CXXSRCS widgets/FrequencyDeltaLineEdit.cpp item_delegates/CandidateKeyFilter.cpp item_delegates/ForeignKeyDelegate.cpp + item_delegates/MessageItemDelegate.cpp validators/LiveFrequencyValidator.cpp GetUserId.cpp Audio/AudioDevice.cpp diff --git a/item_delegates/MessageItemDelegate.cpp b/item_delegates/MessageItemDelegate.cpp new file mode 100644 index 000000000..df9953e45 --- /dev/null +++ b/item_delegates/MessageItemDelegate.cpp @@ -0,0 +1,26 @@ +// +// Moved from Configuration.cpp +// + +#include "MessageItemDelegate.hpp" + +#include +#include + +// +// Class MessageItemDelegate +// +// Item delegate for message entry such as free text message macros. +// +MessageItemDelegate::MessageItemDelegate(QObject *parent): QStyledItemDelegate{parent} +{ +} + +QWidget *MessageItemDelegate::createEditor(QWidget *parent, QStyleOptionViewItem const &, QModelIndex const &) const +{ + QRegularExpression message_alphabet{"[- @A-Za-z0-9+./?#<>;$]*"}; + auto editor = new QLineEdit{parent}; + editor->setFrame(false); + editor->setValidator(new QRegularExpressionValidator{message_alphabet, editor}); + return editor; +} diff --git a/item_delegates/MessageItemDelegate.hpp b/item_delegates/MessageItemDelegate.hpp new file mode 100644 index 000000000..eede221c1 --- /dev/null +++ b/item_delegates/MessageItemDelegate.hpp @@ -0,0 +1,20 @@ +// +// +// + +#ifndef WSJTX_MESSAGEITEMDELEGATE_H +#define WSJTX_MESSAGEITEMDELEGATE_H + +#include + +class MessageItemDelegate: public QStyledItemDelegate + { + Q_OBJECT + +public: + explicit MessageItemDelegate(QObject *parent = nullptr); + QWidget *createEditor(QWidget *parent, QStyleOptionViewItem const & /* option*/ + , QModelIndex const & /* index */ + ) const override; +}; +#endif //WSJTX_MESSAGEITEMDELEGATE_H From 85cb05a8122884ca586d632fe11fc44ea7dd0ece Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Thu, 29 Sep 2022 08:44:31 -0700 Subject: [PATCH 03/20] edit new frequency table fields inline; refresh filter periodically; --- Configuration.cpp | 103 ++++------------- models/Bands.hpp | 2 +- models/FrequencyList.cpp | 234 +++++++++++++++++++++++++++++---------- models/FrequencyList.hpp | 39 +++++-- widgets/mainwindow.cpp | 12 +- widgets/mainwindow.h | 1 + 6 files changed, 238 insertions(+), 153 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 1e7f83e93..9cbd0f6e7 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -185,6 +185,7 @@ #include "item_delegates/ForeignKeyDelegate.hpp" #include "item_delegates/FrequencyDelegate.hpp" #include "item_delegates/FrequencyDeltaDelegate.hpp" +#include "item_delegates/MessageItemDelegate.hpp" #include "Transceiver/TransceiverFactory.hpp" #include "Transceiver/Transceiver.hpp" #include "models/Bands.hpp" @@ -437,31 +438,7 @@ public: }; -// -// Class MessageItemDelegate -// -// Item delegate for message entry such as free text message macros. -// -class MessageItemDelegate final - : public QStyledItemDelegate -{ -public: - explicit MessageItemDelegate (QObject * parent = nullptr) - : QStyledItemDelegate {parent} - { - } - QWidget * createEditor (QWidget * parent - , QStyleOptionViewItem const& /* option*/ - , QModelIndex const& /* index */ - ) const override - { - auto editor = new QLineEdit {parent}; - editor->setFrame (false); - editor->setValidator (new QRegularExpressionValidator {message_alphabet, editor}); - return editor; - } -}; // Internal implementation of the Configuration class. class Configuration::impl final @@ -1268,6 +1245,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network ui_->frequencies_table_view->verticalHeader ()->setResizeContentsPrecision (0); ui_->frequencies_table_view->sortByColumn (FrequencyList_v2::frequency_column, Qt::AscendingOrder); ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::frequency_mhz_column, true); + ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::source_column, true); // delegates ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::frequency_column, new FrequencyDelegate {this}); @@ -2052,7 +2030,6 @@ TransceiverFactory::ParameterPack Configuration::impl::gather_rig_data () void Configuration::impl::accept () { // Called when OK button is clicked. - if (!validate ()) { return; // not accepting @@ -2627,59 +2604,19 @@ FrequencyList_v2::FrequencyItems Configuration::impl::read_frequencies_file (QSt FrequencyList_v2::FrequencyItems list; FrequencyList_v2_100::FrequencyItems list_v100; - // read file as json if ends with qrg.json - if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) + // read file as json if ends with qrg.json. + if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) + { + try { - QJsonDocument doc = QJsonDocument::fromJson(frequencies_file.readAll()); - if (doc.isNull()) - { - MessageBox::critical_message (this, tr ("Error reading frequencies file"), tr ("%1 - Invalid Format").arg (file_name)); - return list; - } - QJsonObject obj = doc.object(); - if (obj.isEmpty()) - { - MessageBox::critical_message (this, tr ("Error reading frequencies file"), tr ("%1 - Information Missing ").arg (file_name)); - return list; - } - QJsonArray arr = obj["frequencies"].toArray(); - if (arr.isEmpty()) - { - MessageBox::critical_message (this, tr ("Error reading frequencies file"), tr ("No Frequencies were found")); - return list; - } - int valid_entry_count = 0; - int skipped_entry_count = 0; - for (auto const &item: arr) - { - QString mode_s, region_s; - QJsonObject obj = item.toObject(); - FrequencyList_v2::Item freq; - region_s = obj["region"].toString(); - mode_s = obj["mode"].toString(); - - freq.frequency_ = obj["frequency"].toString().toDouble() * 1e6; - freq.region_ = IARURegions::value(region_s); - freq.mode_ = Modes::value(mode_s); - freq.description_ = obj["description"].toString(); - freq.source_ = obj["source"].toString(); - freq.start_time_ = QDateTime::fromString(obj["start_time"].toString(), Qt::ISODate); - freq.end_time_ = QDateTime::fromString(obj["end_time"].toString(), Qt::ISODate); - //MessageBox::critical_message (this, tr ("Entry"), tr ("Entry: %1 ").arg(freq.toString()+"[sane:" +freq.isSane() + "] [region:" + obj["region"].toString() + "] [mode:" + obj["mode"].toString()+"] ")); - if ((freq.mode_ != Modes::ALL || QString::compare("ALL", mode_s)) && - (freq.region_ != IARURegions::ALL || QString::compare("ALL", region_s, Qt::CaseInsensitive)) && - freq.isSane()) - { - list.push_back(freq); - valid_entry_count++; - } else - skipped_entry_count++; - } - MessageBox::information_message(this, tr("Loaded Frequencies from %1").arg(file_name), - tr("Entries Valid/Skipped %1").arg(QString::number(valid_entry_count) + "/" + - QString::number(skipped_entry_count))); - return list; - } + list = FrequencyList_v2::from_json_file(&frequencies_file); + } + catch (ReadFileException const &e) + { + MessageBox::critical_message(this, tr("Error reading frequency file"), e.message_); + } + return list; + } quint32 magic; ids >> magic; @@ -2727,9 +2664,13 @@ void Configuration::impl::save_frequencies () auto file_name = QFileDialog::getSaveFileName (this, tr ("Save Working Frequencies"), writeable_data_dir_.absolutePath (), tr ("Frequency files (*.qrg *.qrg.json);;All files (*.*)")); if (!file_name.isNull ()) { + bool b_write_json = file_name.endsWith(".qrg.json", Qt::CaseInsensitive); + QFile frequencies_file {file_name}; frequencies_file.open (QFile::WriteOnly); + QDataStream ods {&frequencies_file}; + auto selection_model = ui_->frequencies_table_view->selectionModel (); if (selection_model->hasSelection () && MessageBox::Yes == MessageBox::query_message (this @@ -2739,9 +2680,9 @@ void Configuration::impl::save_frequencies () "Click No to save all."))) { selection_model->select (selection_model->selection (), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); - if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) + if (b_write_json) { - next_frequencies_.to_json_stream(&ods, "0x" + QString::number(qrg_magic, 16).toUpper(), + next_frequencies_.to_json_file(&frequencies_file, "0x" + QString::number(qrg_magic, 16).toUpper(), "0x" + QString::number(qrg_version, 16).toUpper(), next_frequencies_.frequency_list(selection_model->selectedRows())); } else @@ -2751,9 +2692,9 @@ void Configuration::impl::save_frequencies () } else { - if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) + if (b_write_json) { - next_frequencies_.to_json_stream(&ods, + next_frequencies_.to_json_file(&frequencies_file, "0x" + QString::number(qrg_magic, 16).toUpper(), "0x" + QString::number(qrg_version, 16).toUpper(), next_frequencies_.frequency_list()); diff --git a/models/Bands.hpp b/models/Bands.hpp index 170d4c756..77ae5766b 100644 --- a/models/Bands.hpp +++ b/models/Bands.hpp @@ -24,7 +24,7 @@ // // Implements the QAbstractTableModel interface as an immutable table // where rows are bands and columns are band name, lower frequency -// limit and, upper ferquency limit respectively. +// limit and, upper frequency limit respectively. // class Bands final : public QAbstractTableModel diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index e04a7a184..b5d12e859 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -23,11 +23,13 @@ #include #include #include +#include #include "Radio.hpp" #include "Bands.hpp" #include "pimpl_impl.hpp" #include "revision_utils.hpp" +#include "Logger.hpp" #include "moc_FrequencyList.cpp" @@ -378,7 +380,6 @@ QString FrequencyList_v2::Item::toString () const << end_time_.toString(Qt::ISODate) << ", " << description_ << ", " << source_ << ')'; - return string; } @@ -423,6 +424,7 @@ public: , bands_ {bands} , region_filter_ {IARURegions::ALL} , mode_filter_ {Modes::ALL} + , filter_on_time_ {false} { } @@ -449,6 +451,7 @@ public: FrequencyItems frequency_list_; Region region_filter_; Mode mode_filter_; + bool filter_on_time_; }; FrequencyList_v2::FrequencyList_v2 (Bands const * bands, QObject * parent) @@ -564,7 +567,7 @@ bool FrequencyList_v2::removeDisjointRows (QModelIndexList rows) // We must work with source model indexes because we don't want row // removes to invalidate model indexes we haven't yet processed. We - // achieve that by processing them in decending row order. + // achieve that by processing them in descending row order. for (int r = 0; r < rows.size (); ++r) { rows[r] = mapToSource (rows[r]); @@ -585,10 +588,16 @@ bool FrequencyList_v2::removeDisjointRows (QModelIndexList rows) return result; } -void FrequencyList_v2::filter (Region region, Mode mode) +void FrequencyList_v2::filter (Region region, Mode mode, bool filter_on_time) { m_->region_filter_ = region; m_->mode_filter_ = mode; + m_->filter_on_time_ = filter_on_time; + invalidateFilter (); +} + +void FrequencyList_v2::filter_refresh () +{ invalidateFilter (); } @@ -606,6 +615,11 @@ bool FrequencyList_v2::filterAcceptsRow (int source_row, QModelIndex const& /* p result = (Modes::ALL == item.mode_ && m_->mode_filter_ != Modes::FreqCal) || m_->mode_filter_ == item.mode_; } + if (result && m_->filter_on_time_) + { + result = (!item.start_time_.isValid() || item.start_time_ <= QDateTime::currentDateTimeUtc ()) && + (!item.end_time_.isValid() || item.end_time_ >= QDateTime::currentDateTimeUtc ()); + } return result; } @@ -796,7 +810,7 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const item = Qt::AlignRight + Qt::AlignVCenter; break; } - break; + break; case description_column: switch (role) @@ -810,14 +824,14 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const case Qt::ToolTipRole: case Qt::AccessibleDescriptionRole: - item = tr ("Description"); + item = tr("Description"); break; case Qt::TextAlignmentRole: item = Qt::AlignLeft + Qt::AlignVCenter; break; } - break; + break; case source_column: switch (role) @@ -826,9 +840,6 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const case Qt::DisplayRole: case Qt::EditRole: case Qt::AccessibleTextRole: - item = frequency_item.start_time_ == frequency_item.end_time_ - ? tr ("Equal") - : tr ("NOTEQUAL"); item = frequency_item.source_; break; @@ -847,6 +858,8 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const switch (role) { case SortRole: + item = frequency_item.start_time_; + break; case Qt::DisplayRole: case Qt::EditRole: case Qt::AccessibleTextRole: @@ -868,6 +881,8 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const switch (role) { case SortRole: + item = frequency_item.end_time_; + break; case Qt::DisplayRole: case Qt::EditRole: case Qt::AccessibleTextRole: @@ -902,45 +917,111 @@ bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant c roles << role; auto& item = frequency_list_[row]; - switch (model_index.column ()) + switch (model_index.column()) { - case region_column: - { - auto region = IARURegions::value (value.toString ()); - if (region != item.region_) - { - item.region_ = region; - Q_EMIT dataChanged (model_index, model_index, roles); - changed = true; - } - } - break; - - case mode_column: - { - auto mode = Modes::value (value.toString ()); - if (mode != item.mode_) - { - item.mode_ = mode; - Q_EMIT dataChanged (model_index, model_index, roles); - changed = true; - } - } - break; - - case frequency_column: - if (value.canConvert ()) + case region_column: { - Radio::Frequency frequency {qvariant_cast (value)}; - if (frequency != item.frequency_) + auto region = IARURegions::value(value.toString()); + if (region != item.region_) { - item.frequency_ = frequency; - // mark derived column (1) changed as well - Q_EMIT dataChanged (index (model_index.row (), 1), model_index, roles); + item.region_ = region; + Q_EMIT dataChanged(model_index, model_index, roles); changed = true; } } break; + + case mode_column: + { + auto mode = Modes::value(value.toString()); + if (mode != item.mode_) + { + item.mode_ = mode; + Q_EMIT dataChanged(model_index, model_index, roles); + changed = true; + } + } + break; + + case frequency_column: + { + if (value.canConvert()) + { + Radio::Frequency frequency{qvariant_cast(value)}; + if (frequency != item.frequency_) + { + item.frequency_ = frequency; + // mark derived column (1) changed as well + Q_EMIT dataChanged(index(model_index.row(), 1), model_index, roles); + changed = true; + } + } + } + break; + + case description_column: + { + if (value.toString() != item.description_) + { + item.description_ = value.toString(); + Q_EMIT dataChanged(model_index, model_index, roles); + changed = true; + } + } + break; + + case source_column: + { + if (value.toString() != item.source_) + { + item.source_ = value.toString(); + Q_EMIT dataChanged(model_index, model_index, roles); + changed = true; + } + } + break; + + case start_time_column: + { + QDateTime start_time = QDateTime::fromString(value.toString(), Qt::ISODate); + LOG_INFO(QString{"start_time = %1 - isEmpty %2"}.arg(value.toString()).arg(value.toString().isEmpty())); + if (value.toString().isEmpty()) + { // empty string is valid + start_time = QDateTime(); + } + if (start_time.isValid() || start_time.isNull()) + { + item.start_time_ = start_time; + if (item.end_time_.isValid() && !item.start_time_.isNull() && item.end_time_ < item.start_time_) + { + item.end_time_ = item.start_time_; + } + Q_EMIT dataChanged(model_index, index(model_index.row(), end_time_column), roles); + changed = true; + } + } + break; + + case end_time_column: + { + QDateTime end_time = QDateTime::fromString(value.toString(), Qt::ISODate); + if (value.toString().isEmpty()) + { // empty string is valid + end_time = QDateTime(); + } + if (end_time.isValid() || end_time.isNull()) + { + item.end_time_ = end_time; + if (item.start_time_.isValid() && !item.end_time_.isNull() && end_time <= item.start_time_) + { + item.start_time_ = end_time; + } + Q_EMIT dataChanged(index(model_index.row(), start_time_column), model_index, roles); + changed = true; + } + } + break; + } } @@ -1104,8 +1185,57 @@ auto FrequencyList_v2::all_bands (Region region, Mode mode) const -> BandSet return result; } +FrequencyList_v2::FrequencyItems FrequencyList_v2::from_json_file(QFile *input_file) +{ + FrequencyList_v2::FrequencyItems list; + QJsonDocument doc = QJsonDocument::fromJson(input_file->readAll()); + if (doc.isNull()) + { + throw ReadFileException {tr ("Failed to parse JSON file")}; + } + QJsonObject obj = doc.object(); + if (obj.isEmpty()) + { + throw ReadFileException{tr("Information Missing")}; + } + QJsonArray arr = obj["frequencies"].toArray(); + if (arr.isEmpty()) + { + throw ReadFileException{tr ("No Frequencies were found")}; + } + int valid_entry_count = 0; + int skipped_entry_count = 0; + for (auto const &item: arr) + { + QString mode_s, region_s; + QJsonObject obj = item.toObject(); + FrequencyList_v2::Item freq; + region_s = obj["region"].toString(); + mode_s = obj["mode"].toString(); + + freq.frequency_ = obj["frequency"].toString().toDouble() * 1e6; + freq.region_ = IARURegions::value(region_s); + freq.mode_ = Modes::value(mode_s); + freq.description_ = obj["description"].toString(); + freq.source_ = obj["source"].toString(); + freq.start_time_ = QDateTime::fromString(obj["start_time"].toString(), Qt::ISODate); + freq.end_time_ = QDateTime::fromString(obj["end_time"].toString(), Qt::ISODate); + if ((freq.mode_ != Modes::ALL || QString::compare("ALL", mode_s)) && + (freq.region_ != IARURegions::ALL || QString::compare("ALL", region_s, Qt::CaseInsensitive)) && + freq.isSane()) + { + list.push_back(freq); + valid_entry_count++; + } else + skipped_entry_count++; + } + //MessageBox::information_message(this, tr("Loaded Frequencies from %1").arg(file_name), + // tr("Entries Valid/Skipped %1").arg(QString::number(valid_entry_count) + "/" + + // QString::number(skipped_entry_count))); + return list; +} // write JSON format to a file -void FrequencyList_v2::to_json_stream(QDataStream *ods, QString magic_s, QString version_s, +void FrequencyList_v2::to_json_file(QFile *output_file, QString magic_s, QString version_s, FrequencyItems const &frequency_items) { QJsonObject jobject{ @@ -1122,25 +1252,7 @@ void FrequencyList_v2::to_json_stream(QDataStream *ods, QString magic_s, QString jobject["frequencies"] = array; QJsonDocument d = QJsonDocument(jobject); - ods->writeRawData(d.toJson().data(), d.toJson().size()); -} - -QTextStream& qStdOut() -{ - static QTextStream ts( stdout ); - return ts; -} - -FrequencyList_v2::FrequencyItems FrequencyList_v2::from_json_file(QFile *input_file) -{ - // attempt to read the file as JSON - FrequencyList_v2::FrequencyItems list; - QByteArray jsonData = input_file->readAll(); - QJsonDocument jsonDoc(QJsonDocument::fromJson(jsonData)); - QJsonArray array = jsonDoc.object().value("frequencies").toArray(); - qStdOut() << "Frequencies read"; - qStdOut() << array.count(); - return list; + output_file->write(d.toJson()); } // previous version 100 of the FrequencyList_v2 class diff --git a/models/FrequencyList.hpp b/models/FrequencyList.hpp index 40002762c..75b4adcf9 100644 --- a/models/FrequencyList.hpp +++ b/models/FrequencyList.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "Radio.hpp" #include "IARURegions.hpp" @@ -56,19 +57,19 @@ public: Frequency frequency_; Mode mode_; Region region_; - QString toString () const; - bool isSane() const; - QJsonObject toJson () const; QString description_; QString source_; QDateTime start_time_; QDateTime end_time_; + QString toString () const; + bool isSane() const; + QJsonObject toJson () const; }; using FrequencyItems = QList; using BandSet = QSet; - enum Column {region_column, mode_column, frequency_column, frequency_mhz_column, description_column, start_time_column, end_time_column, source_column, SENTINAL}; + enum Column {region_column, mode_column, frequency_column, frequency_mhz_column, description_column, start_time_column, end_time_column, source_column, SENTINAL}; // an iterator that meets the requirements of the C++ for range statement class const_iterator @@ -89,7 +90,6 @@ public: private: FrequencyList_v2 const * parent_; int row_; - //qint32 qrg_version_; }; explicit FrequencyList_v2 (Bands const *, QObject * parent = nullptr); @@ -101,8 +101,8 @@ public: FrequencyItems const& frequency_list () const; FrequencyItems frequency_list (QModelIndexList const&) const; void frequency_list_merge (FrequencyItems const&); - void to_json_stream(QDataStream *, QString, QString, FrequencyItems const&); - FrequencyList_v2::FrequencyItems from_json_file(QFile *); + void to_json_file(QFile *, QString, QString, FrequencyItems const&); + static FrequencyItems from_json_file(QFile *); // Iterators for the sorted and filtered items // @@ -131,7 +131,7 @@ public: int best_working_frequency (QString const& band) const; // Set filter - Q_SLOT void filter (Region, Mode); + Q_SLOT void filter (Region, Mode, bool); // Reset Q_SLOT void reset_to_defaults (); @@ -144,6 +144,9 @@ public: // Proxy API bool filterAcceptsRow (int source_row, QModelIndex const& parent) const override; + // Refresh the filter based on the current filter settings (underlying data may have changed) + void filter_refresh (); + // Custom roles. static int constexpr SortRole = Qt::UserRole; @@ -158,7 +161,11 @@ bool operator == (FrequencyList_v2::Item const& lhs, FrequencyList_v2::Item cons return lhs.frequency_ == rhs.frequency_ && lhs.region_ == rhs.region_ - && lhs.mode_ == rhs.mode_; + && lhs.mode_ == rhs.mode_ + && lhs.description_ == rhs.description_ + && lhs.source_ == rhs.source_ + && lhs.start_time_ == rhs.start_time_ + && lhs.end_time_ == rhs.end_time_; } QDataStream& operator << (QDataStream&, FrequencyList_v2::Item const&); @@ -224,4 +231,18 @@ QDataStream& operator >> (QDataStream&, FrequencyList::Item&); Q_DECLARE_METATYPE (FrequencyList::Item); Q_DECLARE_METATYPE (FrequencyList::FrequencyItems); +class ReadFileException : public QException { +public: + ReadFileException (QString const& message) + : message_ {message} + { + } + + void raise () const override { throw *this; } + ReadFileException * clone () const override { return new ReadFileException {*this}; } + + QString filename_; + QString message_; +}; + #endif diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 29cccad88..6de200886 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1035,6 +1035,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_wideGraph->setMode(m_mode); connect (&minuteTimer, &QTimer::timeout, this, &MainWindow::on_the_minute); + connect (&minuteTimer, &QTimer::timeout, this, &MainWindow::invalidate_frequencies_filter); + minuteTimer.setSingleShot (true); minuteTimer.start (ms_minute_error () + 60 * 1000); @@ -1079,6 +1081,14 @@ void MainWindow::splash_done () m_splash && m_splash->close (); } +void MainWindow::invalidate_frequencies_filter () +{ + // every interval, invalidate the frequency filter, so that if any + // working frequency goes in/out of scope, we pick it up. + m_config.frequencies ()->filter_refresh (); + ui->bandComboBox->update (); +} + void MainWindow::on_the_minute () { if (minuteTimer.isSingleShot ()) @@ -7159,7 +7169,7 @@ void MainWindow::on_actionFreqCal_triggered() void MainWindow::switch_mode (Mode mode) { m_fastGraph->setMode(m_mode); - m_config.frequencies ()->filter (m_config.region (), mode); + m_config.frequencies ()->filter (m_config.region (), mode, true); // filter on current time auto const& row = m_config.frequencies ()->best_working_frequency (m_freqNominal); ui->bandComboBox->setCurrentIndex (row); if (row >= 0) { diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 0c7cf3647..dca2e9cbb 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -824,6 +824,7 @@ private: void subProcessError (QProcess *, QProcess::ProcessError); void statusUpdate () const; void update_watchdog_label (); + void invalidate_frequencies_filter (); void on_the_minute (); void add_child_to_event_filter (QObject *); void remove_child_from_event_filter (QObject *); From 5db0b06aeb0fdfb942aa7b43af0e11f528fb7a12 Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Thu, 29 Sep 2022 20:54:45 -0700 Subject: [PATCH 04/20] add checkbox for preferred frequencies --- Configuration.cpp | 12 +- models/FrequencyList.cpp | 377 +++++++++++++++++++++++---------------- models/FrequencyList.hpp | 6 +- 3 files changed, 234 insertions(+), 161 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 9cbd0f6e7..45d22c20b 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -286,6 +286,7 @@ public: end_date_time_edit_->setDisplayFormat("yyyy.MM.dd hh:mm:ss 'UTC'"); end_date_time_edit_->setTimeSpec(Qt::UTC); end_date_time_edit_->setMinimumDate(QDate::currentDate().addDays(-365)); + preferred_frequency_checkbox_ = new QCheckBox {tr ("Preferred for Band/Mode")}; setWindowTitle (QApplication::applicationName () + " - " + tr ("Add Frequency")); @@ -297,10 +298,11 @@ public: form_layout->addRow (tr ("IARU &Region:"), ®ion_combo_box_); form_layout->addRow (tr ("&Mode:"), &mode_combo_box_); form_layout->addRow (tr ("&Frequency (MHz):"), &frequency_line_edit_); + form_layout->addRow (tr ("&Preferred:"), preferred_frequency_checkbox_); + form_layout->addRow (tr ("&Description:"), &description_line_edit_); form_layout->addRow (tr ("&Enable Date Range"), enable_dates_checkbox_); form_layout->addRow (tr ("S&tart:"), start_date_time_edit_); form_layout->addRow (tr ("&End:"), end_date_time_edit_); - form_layout->addRow (tr ("&Description:"), &description_line_edit_); form_layout->addRow (tr ("&Source:"), &source_line_edit_); auto main_layout = new QVBoxLayout (this); @@ -348,7 +350,8 @@ public: IARURegions::value(region_combo_box_.currentText()), description_line_edit_.text(), source_line_edit_.text(), start_time, - end_time + end_time, + false }; } @@ -360,6 +363,7 @@ private: QLineEdit source_line_edit_; QDialogButtonBox * button_box; QCheckBox *enable_dates_checkbox_; + QCheckBox *preferred_frequency_checkbox_; QDateTimeEdit *end_date_time_edit_; QDateTimeEdit *start_date_time_edit_; }; @@ -1241,6 +1245,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network ui_->frequencies_table_view->horizontalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents); ui_->frequencies_table_view->horizontalHeader ()->setResizeContentsPrecision (0); + ui_->frequencies_table_view->horizontalHeader ()->moveSection(8, 3); // swap preferred to be in front of description ui_->frequencies_table_view->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents); ui_->frequencies_table_view->verticalHeader ()->setResizeContentsPrecision (0); ui_->frequencies_table_view->sortByColumn (FrequencyList_v2::frequency_column, Qt::AscendingOrder); @@ -2642,7 +2647,8 @@ FrequencyList_v2::FrequencyItems Configuration::impl::read_frequencies_file (QSt ids >> list_v100; Q_FOREACH (auto const& item, list_v100) { - list << FrequencyList_v2::Item{item.frequency_, item.mode_, item.region_, QString(), QString(), QDateTime(),QDateTime()}; + list << FrequencyList_v2::Item{item.frequency_, item.mode_, item.region_, QString(), QString(), QDateTime(), + QDateTime(), false}; } } else diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index b5d12e859..32ec0e708 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -37,40 +37,40 @@ namespace { FrequencyList_v2::FrequencyItems const default_frequency_list = { - {198000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // BBC Radio 4 Droitwich - {4996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // RWM time signal - {9996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // RWM time signal - {14996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime()}, // RWM time signal + {198000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, // BBC Radio 4 Droitwich + {4996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, // RWM time signal + {9996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, // RWM time signal + {14996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, // RWM time signal - {660000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {880000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {1210000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {660000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {880000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {1210000, Modes::FreqCal, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, - {2500000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {3330000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {5000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {7850000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {10000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {14670000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {15000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {20000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {2500000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {3330000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {5000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {7850000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {10000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {14670000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {15000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {20000000, Modes::FreqCal, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {136000, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {136000, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {136000, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {136000, Modes::JT9, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {136000, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {136000, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {136000, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {136000, Modes::JT9, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {474200, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {474200, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {474200, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {474200, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {474200, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {474200, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {474200, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {474200, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {1836600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {1836800, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {1838000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // squeezed allocations - {1839000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {1839000, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {1840000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {1836600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {1836800, Modes::FST4W, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {1838000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // squeezed allocations + {1839000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {1839000, Modes::FST4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {1840000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // Band plans (all USB dial unless stated otherwise) // @@ -99,12 +99,12 @@ namespace // 3580 PSK31 // 3600 LSB EMCOMM // - {3570000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // JA compatible - {3572000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {3573000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // above as below JT65 is out of DM allocation - {3568600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // needs guard marker and lock out - {3575000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional - {3568000, Modes::FT4, IARURegions::R3, "","", QDateTime(), QDateTime()}, // provisional + {3570000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // JA compatible + {3572000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {3573000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // above as below JT65 is out of DM allocation + {3568600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // needs guard marker and lock out + {3575000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // provisional + {3568000, Modes::FT4, IARURegions::R3, "","", QDateTime(), QDateTime(), false}, // provisional // Band plans (all USB dial unless stated otherwise) // @@ -137,11 +137,11 @@ namespace // 7090 LSB QRP CoA // 7110 LSB EMCOMM // - {7038600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {7074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {7076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {7078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {7047500, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional - moved + {7038600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {7074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {7076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {7078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {7047500, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // provisional - moved // up 500Hz to clear // W1AW code practice QRG @@ -171,11 +171,11 @@ namespace // 10142.25 OLIVIA, Contestia, etc. // 10143.25 OLIVIA, Contestia, etc. (main QRG) // - {10136000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {10138000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {10138700, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {10140000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {10140000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional + {10136000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {10138000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {10138700, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {10140000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {10140000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // provisional // Band plans (all USB dial unless stated otherwise) // @@ -214,11 +214,11 @@ namespace // 14105.5 OLIVIA 1000 // 14106.5 OLIVIA 1000 (main QRG) // - {14095600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {14074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {14076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {14078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {14080000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional + {14095600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {14074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {14076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {14078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {14080000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // provisional // Band plans (all USB dial unless stated otherwise) // @@ -247,111 +247,111 @@ namespace // 18104.4 OLIVIA, Contestia, etc. // 18110 NCDXF beacons // - {18100000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {18102000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {18104000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {18104000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional - {18104600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {18100000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {18102000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {18104000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {18104000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // provisional + {18104600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {21074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {21076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {21078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {21094600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {21140000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {21074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {21076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {21078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {21094600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {21140000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {24915000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {24917000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {24919000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {24919000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional - {24924600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {24915000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {24917000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {24919000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {24919000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // provisional + {24924600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {28074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {28076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {28078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {28124600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {28180000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {28074000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {28076000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {28078000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {28124600, Modes::WSPR, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {28180000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {50200000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {50211000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {50275000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {50276000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {50276000, Modes::JT65, IARURegions::R3, "","", QDateTime(), QDateTime()}, - {50380000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime()}, - {50260000, Modes::MSK144, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {50260000, Modes::MSK144, IARURegions::R3, "","", QDateTime(), QDateTime()}, - {50293000, Modes::WSPR, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {50293000, Modes::WSPR, IARURegions::R3, "","", QDateTime(), QDateTime()}, - {50310000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {50312000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {50313000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {50318000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, // provisional - {50323000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {50200000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {50211000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {50275000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {50276000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {50276000, Modes::JT65, IARURegions::R3, "","", QDateTime(), QDateTime(), false}, + {50380000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, + {50260000, Modes::MSK144, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {50260000, Modes::MSK144, IARURegions::R3, "","", QDateTime(), QDateTime(), false}, + {50293000, Modes::WSPR, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {50293000, Modes::WSPR, IARURegions::R3, "","", QDateTime(), QDateTime(), false}, + {50310000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {50312000, Modes::JT9, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {50313000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {50318000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, // provisional + {50323000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {70102000, Modes::JT65, IARURegions::R1, "","", QDateTime(), QDateTime()}, - {70104000, Modes::JT9, IARURegions::R1, "","", QDateTime(), QDateTime()}, - {70091000, Modes::WSPR, IARURegions::R1, "","", QDateTime(), QDateTime()}, - {70154000, Modes::FT8, IARURegions::R1, "","", QDateTime(), QDateTime()}, - {70230000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime()}, + {70102000, Modes::JT65, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, + {70104000, Modes::JT9, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, + {70091000, Modes::WSPR, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, + {70154000, Modes::FT8, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, + {70230000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, - {144116000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {144120000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {144120000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {144170000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {144174000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {144360000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime()}, - {144150000, Modes::MSK144, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {144489000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {144116000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {144120000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {144120000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {144170000, Modes::FT4, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {144174000, Modes::FT8, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {144360000, Modes::MSK144, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, + {144150000, Modes::MSK144, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {144489000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {222065000, Modes::Echo, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {222065000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {222065000, Modes::Q65, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {222065000, Modes::Echo, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {222065000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {222065000, Modes::Q65, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, - {432065000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {432065000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {432300000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {432360000, Modes::MSK144, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {432065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {432065000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {432065000, Modes::JT65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {432300000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {432360000, Modes::MSK144, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {432065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {902065000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime()}, - {902065000, Modes::Q65, IARURegions::R2, "","", QDateTime(), QDateTime()}, + {902065000, Modes::JT65, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, + {902065000, Modes::Q65, IARURegions::R2, "","", QDateTime(), QDateTime(), false}, - {1296065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {1296065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {1296500000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {1296065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {1296065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {1296065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {1296500000, Modes::WSPR, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {1296065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {2301000000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {2301065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2301065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2301065000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime()}, + {2301000000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {2301065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {2301065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {2301065000, Modes::Q65, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, - {2304065000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime()}, - {2304065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2304065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2304065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2304065000, Modes::Echo, IARURegions::ALL, "","", QDateTime(), QDateTime(), false}, + {2304065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {2304065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {2304065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {2320065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2320065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2320065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {2320065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {2320065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {2320065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {2320065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {2320065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {3400065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {3400065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {3400065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {3400065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {3400065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {3400065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {3400065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {3400065000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {5760065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {5760065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {5760065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {5760200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {5760065000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {5760065000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {5760065000, Modes::JT65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {5760200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {10368100000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {10368200000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {10368200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {10368100000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {10368200000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {10368200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, - {24048100000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {24048200000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime()}, - {24048200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime()}, + {24048100000, Modes::Echo, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {24048200000, Modes::JT4, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, + {24048200000, Modes::Q65, IARURegions::ALL,"","", QDateTime(), QDateTime(), false}, }; } @@ -379,7 +379,8 @@ QString FrequencyList_v2::Item::toString () const << start_time_.toString(Qt::ISODate) << ", " << end_time_.toString(Qt::ISODate) << ", " << description_ << ", " - << source_ << ')'; + << source_ << "," + << preferred_ << ')'; return string; } @@ -390,7 +391,8 @@ QJsonObject FrequencyList_v2::Item::toJson() const { {"description", description_}, {"source", source_}, {"start_time", start_time_.toString(Qt::ISODate) }, - {"end_time", end_time_.toString(Qt::ISODate)}}; + {"end_time", end_time_.toString(Qt::ISODate) }, + {"preferred", preferred_}}; } QDataStream& operator << (QDataStream& os, FrequencyList_v2::Item const& item) @@ -401,7 +403,8 @@ QDataStream& operator << (QDataStream& os, FrequencyList_v2::Item const& item) << item.start_time_ << item.end_time_ << item.description_ - << item.source_; + << item.source_ + << item.preferred_; } QDataStream& operator >> (QDataStream& is, FrequencyList_v2::Item& item) @@ -412,7 +415,8 @@ QDataStream& operator >> (QDataStream& is, FrequencyList_v2::Item& item) >> item.start_time_ >> item.end_time_ >> item.description_ - >> item.source_; + >> item.source_ + >> item.preferred_; } class FrequencyList_v2::impl final @@ -697,6 +701,11 @@ Qt::ItemFlags FrequencyList_v2::impl::flags (QModelIndex const& index) const { result |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled; } + + if (preferred_column == column) + { + result |= Qt::ItemIsUserCheckable; + } } return result; } @@ -899,6 +908,33 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const break; } break; + + case preferred_column: + switch (role) + { + case SortRole: + item = frequency_item.preferred_; + break; + case Qt::DisplayRole: + case Qt::EditRole: + case Qt::AccessibleTextRole: + //item = frequency_item.preferred_ ? QString("True") : QString("False"); + break; + + case Qt::ToolTipRole: + case Qt::AccessibleDescriptionRole: + item = tr ("Pref"); + break; + + case Qt::TextAlignmentRole: + item = Qt::AlignHCenter + Qt::AlignVCenter; + break; + + case Qt::CheckStateRole: + item = frequency_item.preferred_ ? Qt::Checked : Qt::Unchecked; + break; + } + break; } } return item; @@ -907,16 +943,30 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant const& value, int role) { bool changed {false}; - auto const& row = model_index.row (); + auto& item = frequency_list_[row]; + + QVector roles; + roles << role; + + if (model_index.isValid () + && Qt::CheckStateRole == role + && row < frequency_list_.size () + && model_index.column () == preferred_column) + { + bool b_val = ((Qt::CheckState)value.toInt() == Qt::Checked); + if (b_val != item.preferred_) + { + item.preferred_ = b_val; + Q_EMIT dataChanged(model_index, model_index, roles); + changed = true; + } + } + if (model_index.isValid () && Qt::EditRole == role && row < frequency_list_.size ()) { - QVector roles; - roles << role; - - auto& item = frequency_list_[row]; switch (model_index.column()) { case region_column: @@ -1022,6 +1072,18 @@ bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant c } break; + case preferred_column: + { + bool b_value = value.toBool(); + if (b_value != item.preferred_) + { + item.preferred_ = b_value; + Q_EMIT dataChanged(index(model_index.row(), start_time_column), model_index, roles); + changed = true; + } + } + break; + } } @@ -1037,14 +1099,15 @@ QVariant FrequencyList_v2::impl::headerData (int section, Qt::Orientation orient { switch (section) { - case region_column: header = tr ("IARU Region"); break; - case mode_column: header = tr ("Mode"); break; - case frequency_column: header = tr ("Frequency"); break; - case frequency_mhz_column: header = tr ("Frequency (MHz)"); break; - case description_column: header = tr ("Description"); break; - case source_column: header = tr ("Source"); break; - case start_time_column: header = tr ("Start"); break; - case end_time_column: header = tr ("End"); break; + case region_column: header = tr ("IARU Region"); break; + case mode_column: header = tr ("Mode"); break; + case frequency_column: header = tr ("Frequency"); break; + case frequency_mhz_column: header = tr ("Frequency (MHz)"); break; + case source_column: header = tr ("Source"); break; + case start_time_column: header = tr ("Start"); break; + case end_time_column: header = tr ("End"); break; + case preferred_column: header = tr ("Pref"); break; + case description_column: header = tr ("Description"); break; } } else @@ -1076,7 +1139,7 @@ bool FrequencyList_v2::impl::insertRows (int row, int count, QModelIndex const& beginInsertRows (parent, row, row + count - 1); for (auto r = 0; r < count; ++r) { - frequency_list_.insert (row, Item {0, Mode::ALL, IARURegions::ALL, QString(), QString(), QDateTime(), QDateTime()}); + frequency_list_.insert (row, Item {0, Mode::ALL, IARURegions::ALL, QString(), QString(), QDateTime(), QDateTime(), false}); } endInsertRows (); return true; @@ -1220,6 +1283,8 @@ FrequencyList_v2::FrequencyItems FrequencyList_v2::from_json_file(QFile *input_f freq.source_ = obj["source"].toString(); freq.start_time_ = QDateTime::fromString(obj["start_time"].toString(), Qt::ISODate); freq.end_time_ = QDateTime::fromString(obj["end_time"].toString(), Qt::ISODate); + freq.preferred_ = obj["preferred"].toBool(); + if ((freq.mode_ != Modes::ALL || QString::compare("ALL", mode_s)) && (freq.region_ != IARURegions::ALL || QString::compare("ALL", region_s, Qt::CaseInsensitive)) && freq.isSane()) diff --git a/models/FrequencyList.hpp b/models/FrequencyList.hpp index 75b4adcf9..4e845bd6d 100644 --- a/models/FrequencyList.hpp +++ b/models/FrequencyList.hpp @@ -61,6 +61,7 @@ public: QString source_; QDateTime start_time_; QDateTime end_time_; + bool preferred_; // preferred frequency for this band and mode QString toString () const; bool isSane() const; QJsonObject toJson () const; @@ -69,7 +70,7 @@ public: using FrequencyItems = QList; using BandSet = QSet; - enum Column {region_column, mode_column, frequency_column, frequency_mhz_column, description_column, start_time_column, end_time_column, source_column, SENTINAL}; + enum Column {region_column, mode_column, frequency_column, frequency_mhz_column, description_column, start_time_column, end_time_column, source_column, preferred_column, SENTINAL}; // an iterator that meets the requirements of the C++ for range statement class const_iterator @@ -165,7 +166,8 @@ bool operator == (FrequencyList_v2::Item const& lhs, FrequencyList_v2::Item cons && lhs.description_ == rhs.description_ && lhs.source_ == rhs.source_ && lhs.start_time_ == rhs.start_time_ - && lhs.end_time_ == rhs.end_time_; + && lhs.end_time_ == rhs.end_time_ + && lhs.preferred_ == rhs.preferred_; } QDataStream& operator << (QDataStream&, FrequencyList_v2::Item const&); From eb33b6029f6be2a2e9dc168170447c8db5f5620d Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Thu, 29 Sep 2022 21:07:26 -0700 Subject: [PATCH 05/20] start with current datetime for in-place editing of blank datetime --- Configuration.cpp | 8 ++++---- models/FrequencyList.cpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 45d22c20b..8e9ffc610 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -278,7 +278,7 @@ public: start_date_time_edit_ = new QDateTimeEdit(QDateTime(QDate::currentDate(), QTime(0,0,0,0), Qt::UTC), parent); end_date_time_edit_ = new QDateTimeEdit(QDateTime(QDate::currentDate().addDays(2), QTime(0,0,0,0), Qt::UTC), parent); - enable_dates_checkbox_ = new QCheckBox {tr ("Validity Period")}; + enable_dates_checkbox_ = new QCheckBox {tr ("")}; start_date_time_edit_->setDisplayFormat("yyyy.MM.dd hh:mm:ss 'UTC'"); start_date_time_edit_->setTimeSpec(Qt::UTC); start_date_time_edit_->setMinimumDate(QDate::currentDate().addDays(-365)); @@ -286,7 +286,7 @@ public: end_date_time_edit_->setDisplayFormat("yyyy.MM.dd hh:mm:ss 'UTC'"); end_date_time_edit_->setTimeSpec(Qt::UTC); end_date_time_edit_->setMinimumDate(QDate::currentDate().addDays(-365)); - preferred_frequency_checkbox_ = new QCheckBox {tr ("Preferred for Band/Mode")}; + preferred_frequency_checkbox_ = new QCheckBox {tr ("")}; setWindowTitle (QApplication::applicationName () + " - " + tr ("Add Frequency")); @@ -298,9 +298,9 @@ public: form_layout->addRow (tr ("IARU &Region:"), ®ion_combo_box_); form_layout->addRow (tr ("&Mode:"), &mode_combo_box_); form_layout->addRow (tr ("&Frequency (MHz):"), &frequency_line_edit_); - form_layout->addRow (tr ("&Preferred:"), preferred_frequency_checkbox_); + form_layout->addRow (tr ("&Preferred for Band/Mode:"), preferred_frequency_checkbox_); form_layout->addRow (tr ("&Description:"), &description_line_edit_); - form_layout->addRow (tr ("&Enable Date Range"), enable_dates_checkbox_); + form_layout->addRow (tr ("&Enable Date Range:"), enable_dates_checkbox_); form_layout->addRow (tr ("S&tart:"), start_date_time_edit_); form_layout->addRow (tr ("&End:"), end_date_time_edit_); form_layout->addRow (tr ("&Source:"), &source_line_edit_); diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index 32ec0e708..4860eed3f 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -869,8 +869,19 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const case SortRole: item = frequency_item.start_time_; break; - case Qt::DisplayRole: + case Qt::EditRole: + if (frequency_item.start_time_.isNull () || !frequency_item.start_time_.isValid ()) + { + item = QDateTime::currentDateTimeUtc ().toString (Qt::ISODate); + } + else + { + item = frequency_item.start_time_.toString(Qt::ISODate); + } + break; + + case Qt::DisplayRole: case Qt::AccessibleTextRole: item = frequency_item.start_time_.toString(Qt::ISODate); break; @@ -892,8 +903,19 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const case SortRole: item = frequency_item.end_time_; break; - case Qt::DisplayRole: + case Qt::EditRole: + if (frequency_item.end_time_.isNull () || !frequency_item.end_time_.isValid ()) + { + item = QDateTime::currentDateTimeUtc ().toString (Qt::ISODate); + } + else + { + item = frequency_item.end_time_.toString(Qt::ISODate); + } + break; + + case Qt::DisplayRole: case Qt::AccessibleTextRole: item = frequency_item.end_time_.toString(Qt::ISODate); break; @@ -1104,8 +1126,8 @@ QVariant FrequencyList_v2::impl::headerData (int section, Qt::Orientation orient case frequency_column: header = tr ("Frequency"); break; case frequency_mhz_column: header = tr ("Frequency (MHz)"); break; case source_column: header = tr ("Source"); break; - case start_time_column: header = tr ("Start"); break; - case end_time_column: header = tr ("End"); break; + case start_time_column: header = tr ("Start Date/Time"); break; + case end_time_column: header = tr ("End Date/Time"); break; case preferred_column: header = tr ("Pref"); break; case description_column: header = tr ("Description"); break; } From a39a48d76a351b74053f2bb7be1d94d40a22caae Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Sat, 1 Oct 2022 16:51:17 -0700 Subject: [PATCH 06/20] show which Freqs are preferred; switch to preferred; show description with a separator --- Configuration.cpp | 2 +- models/FrequencyList.cpp | 55 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index 8e9ffc610..bc31688b3 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -351,7 +351,7 @@ public: description_line_edit_.text(), source_line_edit_.text(), start_time, end_time, - false + preferred_frequency_checkbox_->isChecked() }; } diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index 4860eed3f..1fa17fdea 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -448,6 +448,8 @@ public: QStringList mimeTypes () const override; QMimeData * mimeData (QModelIndexList const&) const override; + void unprefer_all_but(Item & item, int const row, QVector ); + static int constexpr num_cols {SENTINAL}; static auto constexpr mime_type = "application/wsjt.Frequencies"; @@ -456,6 +458,7 @@ public: Region region_filter_; Mode mode_filter_; bool filter_on_time_; + }; FrequencyList_v2::FrequencyList_v2 (Bands const * bands, QObject * parent) @@ -511,6 +514,11 @@ int FrequencyList_v2::best_working_frequency (Frequency f) const auto const& band = m_->bands_->find (candidate_frequency); if (band == target_band) { + // take the preferred one + if (m_->frequency_list_[source_row].preferred_) + { + return row; + } // take closest band match Radio::FrequencyDelta new_delta = f - candidate_frequency; if (std::abs (new_delta) < std::abs (delta)) @@ -536,7 +544,9 @@ int FrequencyList_v2::best_working_frequency (QString const& target_band) const auto const& band = m_->bands_->find (m_->frequency_list_[source_row].frequency_); if (band == target_band) { - return row; + if (m_->frequency_list_[source_row].preferred_) + return row; // return the preferred one immediately + result = row; } } } @@ -648,6 +658,9 @@ QModelIndex FrequencyList_v2::impl::add (Item f) frequency_list_.append (f); endInsertRows (); + // if we added one that had a preferred frequency, unprefer everything else + unprefer_all_but(f, row, {Qt::DisplayRole, Qt::CheckStateRole}); + return index (row, 0); } return QModelIndex {}; @@ -805,8 +818,14 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const case Qt::DisplayRole: { auto const& band = bands_->find (frequency_item.frequency_); - item = Radio::pretty_frequency_MHz_string (frequency_item.frequency_) - + " MHz (" + (band.isEmpty () ? "OOB" : band) + ')'; + QString desc_text; + desc_text = frequency_item.description_.isEmpty() ? "" : " \u2016 " + frequency_item.description_; + item = (frequency_item.preferred_ ? "\u2055 " : "") + + Radio::pretty_frequency_MHz_string(frequency_item.frequency_) + + " MHz (" + (band.isEmpty() ? "OOB" : band) + ")" + + (((frequency_item.start_time_.isValid() && !frequency_item.start_time_.isNull()) || + (frequency_item.end_time_.isValid() && !frequency_item.end_time_.isNull())) ? " \u2016 " : "") + + desc_text; } break; @@ -962,6 +981,30 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const return item; } +void FrequencyList_v2::impl::unprefer_all_but(Item &item, int const item_row, QVector roles) +{ + // un-prefer all of the other frequencies in this band + auto const band = bands_->find (item.frequency_); + if (band.isEmpty ()) return; // out of any band + + roles << Qt::CheckStateRole; + roles << Qt::DisplayRole; + + for (int row = 0; row < rowCount (); ++row) + { + if (row == item_row) continue; + + Item &i = frequency_list_[row]; + auto const &iter_band = bands_->find(i.frequency_); + + if (!iter_band.isEmpty() && band == iter_band && (i.region_ == item.region_) && (i.mode_ == item.mode_)) + { + i.preferred_ = false; + Q_EMIT dataChanged(index(row,preferred_column), index(row,preferred_column), roles); + } + } +} + bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant const& value, int role) { bool changed {false}; @@ -980,7 +1023,11 @@ bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant c if (b_val != item.preferred_) { item.preferred_ = b_val; - Q_EMIT dataChanged(model_index, model_index, roles); + if (item.preferred_) + { + unprefer_all_but (item, row, roles); // un-prefer all of the other frequencies in this band + } + Q_EMIT dataChanged(index(row,description_column), index(row,preferred_column), roles); changed = true; } } From c185f8578fb6df1b6decaae6c7ea35722b13e929 Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Tue, 11 Oct 2022 18:30:01 -0700 Subject: [PATCH 07/20] retain old type name for FrequencyList_v2, use new type name for new class --- Configuration.cpp | 96 ++++++++++++++++------ Configuration.hpp | 6 +- MetaDataRegistry.cpp | 8 +- WSPR/WSPRBandHopping.hpp | 2 +- models/FrequencyList.cpp | 113 ++++++++++++++------------ models/FrequencyList.hpp | 33 ++++---- models/StationList.cpp | 2 +- translations/wsjtx_ca.ts | 2 +- translations/wsjtx_es.ts | 2 +- translations/wsjtx_zh_HK.ts | 2 +- translations/wsjtx_zh_TW.ts | 2 +- validators/LiveFrequencyValidator.cpp | 2 +- validators/LiveFrequencyValidator.hpp | 6 +- widgets/BandComboBox.cpp | 2 +- widgets/mainwindow.cpp | 6 +- widgets/mainwindow.h | 2 +- 16 files changed, 170 insertions(+), 116 deletions(-) diff --git a/Configuration.cpp b/Configuration.cpp index bc31688b3..2047ca023 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -270,7 +270,7 @@ class FrequencyDialog final Q_OBJECT public: - using Item = FrequencyList_v2::Item; + using Item = FrequencyList_v2_101::Item; explicit FrequencyDialog (IARURegions * regions_model, Modes * modes_model, QWidget * parent = nullptr) : QDialog {parent} @@ -522,7 +522,7 @@ private: void insert_frequency (); void size_frequency_table_columns(); - FrequencyList_v2::FrequencyItems read_frequencies_file (QString const&); + FrequencyList_v2_101::FrequencyItems read_frequencies_file (QString const&); void delete_stations (); void insert_station (); @@ -614,8 +614,8 @@ private: IARURegions regions_; IARURegions::Region region_; Modes modes_; - FrequencyList_v2 frequencies_; - FrequencyList_v2 next_frequencies_; + FrequencyList_v2_101 frequencies_; + FrequencyList_v2_101 next_frequencies_; StationList stations_; StationList next_stations_; FrequencyDelta current_offset_; @@ -821,8 +821,8 @@ Bands const * Configuration::bands () const {return &m_->bands_;} StationList * Configuration::stations () {return &m_->stations_;} StationList const * Configuration::stations () const {return &m_->stations_;} IARURegions::Region Configuration::region () const {return m_->region_;} -FrequencyList_v2 * Configuration::frequencies () {return &m_->frequencies_;} -FrequencyList_v2 const * Configuration::frequencies () const {return &m_->frequencies_;} +FrequencyList_v2_101 * Configuration::frequencies () {return &m_->frequencies_;} +FrequencyList_v2_101 const * Configuration::frequencies () const {return &m_->frequencies_;} QStringListModel * Configuration::macros () {return &m_->macros_;} QStringListModel const * Configuration::macros () const {return &m_->macros_;} QDir Configuration::save_directory () const {return m_->save_directory_;} @@ -1090,7 +1090,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network throw std::runtime_error {"Failed to create save directory"}; } - // we now have a deafult save path that exists + // we now have a default save path that exists // make sure samples directory exists QString samples_dir {"samples"}; @@ -1239,7 +1239,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network // // setup working frequencies table model & view // - frequencies_.sort (FrequencyList_v2::frequency_column); + frequencies_.sort (FrequencyList_v2_101::frequency_column); ui_->frequencies_table_view->setModel (&next_frequencies_); ui_->frequencies_table_view->horizontalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents); @@ -1248,14 +1248,14 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network ui_->frequencies_table_view->horizontalHeader ()->moveSection(8, 3); // swap preferred to be in front of description ui_->frequencies_table_view->verticalHeader ()->setSectionResizeMode (QHeaderView::ResizeToContents); ui_->frequencies_table_view->verticalHeader ()->setResizeContentsPrecision (0); - ui_->frequencies_table_view->sortByColumn (FrequencyList_v2::frequency_column, Qt::AscendingOrder); - ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::frequency_mhz_column, true); - ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::source_column, true); + ui_->frequencies_table_view->sortByColumn (FrequencyList_v2_101::frequency_column, Qt::AscendingOrder); + ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2_101::frequency_mhz_column, true); + ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2_101::source_column, true); // delegates - ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::frequency_column, new FrequencyDelegate {this}); - ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::region_column, new ForeignKeyDelegate {®ions_, 0, this}); - ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::mode_column, new ForeignKeyDelegate {&modes_, 0, this}); + ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2_101::frequency_column, new FrequencyDelegate {this}); + ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2_101::region_column, new ForeignKeyDelegate {®ions_, 0, this}); + ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2_101::mode_column, new ForeignKeyDelegate {&modes_, 0, this}); // actions frequency_delete_action_ = new QAction {tr ("&Delete"), ui_->frequencies_table_view}; @@ -1498,6 +1498,13 @@ void Configuration::impl::done (int r) void Configuration::impl::read_settings () { SettingsGroup g {settings_, "Configuration"}; + LOG_INFO(QString{"Configuration Settings (%1)"}.arg(settings_->fileName())); + QStringList keys = settings_->allKeys(); + //Q_FOREACH (auto const& item, keys) + //{ + // LOG_INFO(QString{" %1 = %2"}.arg(item).arg(settings_->value(item).toString())); + //} + restoreGeometry (settings_->value ("window/geometry").toByteArray ()); my_callsign_ = settings_->value ("MyCall", QString {}).toString (); @@ -1551,12 +1558,20 @@ void Configuration::impl::read_settings () region_ = settings_->value ("Region", QVariant::fromValue (IARURegions::ALL)).value (); - if (settings_->contains ("FrequenciesForRegionModes")) + LOG_INFO(QString{"Reading frequencies"}); + + if (settings_->contains ("FrequenciesForRegionModes_v2")) { - auto const& v = settings_->value ("FrequenciesForRegionModes"); + LOG_INFO(QString{"read_settings found FrequenciesForRegionModes_v2"}); + if (settings_->contains ("FrequenciesForRegionModes")) + { + LOG_INFO(QString{"read_settings ALSO found FrequenciesForRegionModes"}); + } + + auto const& v = settings_->value ("FrequenciesForRegionModes_v2"); if (v.isValid ()) { - frequencies_.frequency_list (v.value ()); + frequencies_.frequency_list (v.value ()); } else { @@ -1565,7 +1580,34 @@ void Configuration::impl::read_settings () } else { - frequencies_.reset_to_defaults (); + LOG_INFO(QString{"read_settings looking for FrequenciesForRegionModes"}); + if (settings_->contains ("FrequenciesForRegionModes")) // has the old ones. + { + LOG_INFO(QString{"found FrequenciesForRegionModes"}); + auto const& v = settings_->value("FrequenciesForRegionModes"); + LOG_INFO(QString{"v is %1"}.arg(v.typeName())); + if (v.isValid()) + { + LOG_INFO(QString{"read_settings found VALID FrequenciesForRegionModes"}); + FrequencyList_v2_101::FrequencyItems list; + FrequencyList_v2::FrequencyItems v100 = v.value(); + LOG_INFO(QString{"read_settings read %1 old_format items from FrequenciesForRegionModes"}.arg(v100.size())); + + Q_FOREACH (auto const& item, v100) + { + list << FrequencyList_v2_101::Item{item.frequency_, item.mode_, item.region_, QString(), QString(), QDateTime(), + QDateTime(), false}; + } + LOG_INFO(QString{"converted %1 items to FrequenciesForRegionModes_v2"}.arg(list.size())); + + frequencies_.frequency_list(list); + } + else + { + LOG_INFO(QString{"read_settings INVALID FrequenciesForRegionModes"}); + frequencies_.reset_to_defaults(); + } + } } stations_.station_list (settings_->value ("stations").value ()); @@ -1707,8 +1749,8 @@ void Configuration::impl::write_settings () settings_->setValue ("After73", id_after_73_); settings_->setValue ("TxQSYAllowed", tx_QSY_allowed_); settings_->setValue ("Macros", macros_.stringList ()); - settings_->setValue ("FrequenciesForRegionModes", QVariant::fromValue (frequencies_.frequency_list ())); settings_->setValue ("stations", QVariant::fromValue (stations_.station_list ())); + settings_->setValue ("FrequenciesForRegionModes_v2", QVariant::fromValue (frequencies_.frequency_list ())); settings_->setValue ("DecodeHighlighting", QVariant::fromValue (decode_highlighing_model_.items ())); settings_->setValue ("HighlightByMode", highlight_by_mode_); settings_->setValue ("OnlyFieldsSought", highlight_only_fields_); @@ -2235,7 +2277,7 @@ void Configuration::impl::accept () if (frequencies_.frequency_list () != next_frequencies_.frequency_list ()) { frequencies_.frequency_list (next_frequencies_.frequency_list ()); - frequencies_.sort (FrequencyList_v2::frequency_column); + frequencies_.sort (FrequencyList_v2_101::frequency_column); } if (stations_.station_list () != next_stations_.station_list ()) @@ -2567,7 +2609,7 @@ void Configuration::impl::delete_frequencies () auto selection_model = ui_->frequencies_table_view->selectionModel (); selection_model->select (selection_model->selection (), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); next_frequencies_.removeDisjointRows (selection_model->selectedRows ()); - ui_->frequencies_table_view->resizeColumnToContents (FrequencyList_v2::mode_column); + ui_->frequencies_table_view->resizeColumnToContents (FrequencyList_v2_101::mode_column); size_frequency_table_columns (); } @@ -2601,20 +2643,20 @@ void Configuration::impl::merge_frequencies () } } -FrequencyList_v2::FrequencyItems Configuration::impl::read_frequencies_file (QString const& file_name) +FrequencyList_v2_101::FrequencyItems Configuration::impl::read_frequencies_file (QString const& file_name) { QFile frequencies_file {file_name}; frequencies_file.open (QFile::ReadOnly); QDataStream ids {&frequencies_file}; - FrequencyList_v2::FrequencyItems list; - FrequencyList_v2_100::FrequencyItems list_v100; + FrequencyList_v2_101::FrequencyItems list; + FrequencyList_v2::FrequencyItems list_v100; // read file as json if ends with qrg.json. if (file_name.endsWith(".qrg.json", Qt::CaseInsensitive)) { try { - list = FrequencyList_v2::from_json_file(&frequencies_file); + list = FrequencyList_v2_101::from_json_file(&frequencies_file); } catch (ReadFileException const &e) { @@ -2647,7 +2689,7 @@ FrequencyList_v2::FrequencyItems Configuration::impl::read_frequencies_file (QSt ids >> list_v100; Q_FOREACH (auto const& item, list_v100) { - list << FrequencyList_v2::Item{item.frequency_, item.mode_, item.region_, QString(), QString(), QDateTime(), + list << FrequencyList_v2_101::Item{item.frequency_, item.mode_, item.region_, QString(), QString(), QDateTime(), QDateTime(), false}; } } @@ -2729,7 +2771,7 @@ void Configuration::impl::insert_frequency () if (QDialog::Accepted == frequency_dialog_->exec ()) { ui_->frequencies_table_view->setCurrentIndex (next_frequencies_.add (frequency_dialog_->item ())); - ui_->frequencies_table_view->resizeColumnToContents (FrequencyList_v2::mode_column); + ui_->frequencies_table_view->resizeColumnToContents (FrequencyList_v2_101::mode_column); size_frequency_table_columns(); } } diff --git a/Configuration.hpp b/Configuration.hpp index cb32f0365..85b887ae7 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -18,7 +18,7 @@ class QAudioDeviceInfo; class QDir; class QNetworkAccessManager; class Bands; -class FrequencyList_v2; +class FrequencyList_v2_101; class StationList; class QStringListModel; class LotWUsers; @@ -164,8 +164,8 @@ public: Bands * bands (); Bands const * bands () const; IARURegions::Region region () const; - FrequencyList_v2 * frequencies (); - FrequencyList_v2 const * frequencies () const; + FrequencyList_v2_101 * frequencies (); + FrequencyList_v2_101 const * frequencies () const; StationList * stations (); StationList const * stations () const; QStringListModel * macros (); diff --git a/MetaDataRegistry.cpp b/MetaDataRegistry.cpp index c39551fa1..f6c50c1f1 100644 --- a/MetaDataRegistry.cpp +++ b/MetaDataRegistry.cpp @@ -52,9 +52,13 @@ void register_types () item_editor_factory->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ()); - // Frequency list model + // V101 Frequency list model + qRegisterMetaTypeStreamOperators ("Item_v2_101"); + QMetaType::registerConverter (&FrequencyList_v2_101::Item::toString); + qRegisterMetaTypeStreamOperators ("FrequencyItems_v2_101"); + + // V100 Frequency list model qRegisterMetaTypeStreamOperators ("Item_v2"); - QMetaType::registerConverter (&FrequencyList_v2::Item::toString); qRegisterMetaTypeStreamOperators ("FrequencyItems_v2"); // defunct old versions diff --git a/WSPR/WSPRBandHopping.hpp b/WSPR/WSPRBandHopping.hpp index 9af27b5f3..9f65de177 100644 --- a/WSPR/WSPRBandHopping.hpp +++ b/WSPR/WSPRBandHopping.hpp @@ -41,7 +41,7 @@ class QWidget; // storage using the provided QSettings object instance. // // A passed in Configuration object instance is used to query the -// FrequencyList_v2 model to determine working frequencies for each +// FrequencyList_v2_101 model to determine working frequencies for each // band. The row index of this model is returned by this classes // hopping scheduling method so it may be conveniently used to select // a new working frequency by a client. diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index 1fa17fdea..323dda126 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -35,7 +35,7 @@ namespace { - FrequencyList_v2::FrequencyItems const default_frequency_list = + FrequencyList_v2_101::FrequencyItems const default_frequency_list = { {198000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, // BBC Radio 4 Droitwich {4996000, Modes::FreqCal, IARURegions::R1, "","", QDateTime(), QDateTime(), false}, // RWM time signal @@ -356,19 +356,19 @@ namespace } #if !defined (QT_NO_DEBUG_STREAM) -QDebug operator << (QDebug debug, FrequencyList_v2::Item const& item) +QDebug operator << (QDebug debug, FrequencyList_v2_101::Item const& item) { QDebugStateSaver saver {debug}; return debug.nospace () << item.toString (); } #endif -bool FrequencyList_v2::Item::isSane() const +bool FrequencyList_v2_101::Item::isSane() const { return frequency_ > 0.0 && (!start_time_.isValid() || !end_time_.isValid() || start_time_ < end_time_) && (region_ == IARURegions::ALL || region_ == IARURegions::R1 || region_ == IARURegions::R2 || region_ == IARURegions::R3); } -QString FrequencyList_v2::Item::toString () const +QString FrequencyList_v2_101::Item::toString () const { QString string; QTextStream qts {&string}; @@ -384,7 +384,7 @@ QString FrequencyList_v2::Item::toString () const return string; } -QJsonObject FrequencyList_v2::Item::toJson() const { +QJsonObject FrequencyList_v2_101::Item::toJson() const { return {{"frequency", Radio::frequency_MHz_string (frequency_) }, {"mode", Modes::name (mode_) }, {"region", IARURegions::name (region_)}, @@ -395,7 +395,7 @@ QJsonObject FrequencyList_v2::Item::toJson() const { {"preferred", preferred_}}; } -QDataStream& operator << (QDataStream& os, FrequencyList_v2::Item const& item) +QDataStream& operator << (QDataStream& os, FrequencyList_v2_101::Item const& item) { return os << item.frequency_ << item.mode_ @@ -407,7 +407,7 @@ QDataStream& operator << (QDataStream& os, FrequencyList_v2::Item const& item) << item.preferred_; } -QDataStream& operator >> (QDataStream& is, FrequencyList_v2::Item& item) +QDataStream& operator >> (QDataStream& is, FrequencyList_v2_101::Item& item) { return is >> item.frequency_ >> item.mode_ @@ -419,7 +419,7 @@ QDataStream& operator >> (QDataStream& is, FrequencyList_v2::Item& item) >> item.preferred_; } -class FrequencyList_v2::impl final +class FrequencyList_v2_101::impl final : public QAbstractTableModel { public: @@ -461,7 +461,7 @@ public: }; -FrequencyList_v2::FrequencyList_v2 (Bands const * bands, QObject * parent) +FrequencyList_v2_101::FrequencyList_v2_101 (Bands const * bands, QObject * parent) : QSortFilterProxyModel {parent} , m_ {bands, parent} { @@ -469,21 +469,21 @@ FrequencyList_v2::FrequencyList_v2 (Bands const * bands, QObject * parent) setSortRole (SortRole); } -FrequencyList_v2::~FrequencyList_v2 () +FrequencyList_v2_101::~FrequencyList_v2_101 () { } -auto FrequencyList_v2::frequency_list (FrequencyItems frequency_list) -> FrequencyItems +auto FrequencyList_v2_101::frequency_list (FrequencyItems frequency_list) -> FrequencyItems { return m_->frequency_list (frequency_list); } -auto FrequencyList_v2::frequency_list () const -> FrequencyItems const& +auto FrequencyList_v2_101::frequency_list () const -> FrequencyItems const& { return m_->frequency_list_; } -auto FrequencyList_v2::frequency_list (QModelIndexList const& model_index_list) const -> FrequencyItems +auto FrequencyList_v2_101::frequency_list (QModelIndexList const& model_index_list) const -> FrequencyItems { FrequencyItems list; Q_FOREACH (auto const& index, model_index_list) @@ -493,13 +493,13 @@ auto FrequencyList_v2::frequency_list (QModelIndexList const& model_index_list) return list; } -void FrequencyList_v2::frequency_list_merge (FrequencyItems const& items) +void FrequencyList_v2_101::frequency_list_merge (FrequencyItems const& items) { m_->add (items); } -int FrequencyList_v2::best_working_frequency (Frequency f) const +int FrequencyList_v2_101::best_working_frequency (Frequency f) const { int result {-1}; auto const& target_band = m_->bands_->find (f); @@ -532,7 +532,7 @@ int FrequencyList_v2::best_working_frequency (Frequency f) const return result; } -int FrequencyList_v2::best_working_frequency (QString const& target_band) const +int FrequencyList_v2_101::best_working_frequency (QString const& target_band) const { int result {-1}; if (!target_band.isEmpty ()) @@ -553,17 +553,17 @@ int FrequencyList_v2::best_working_frequency (QString const& target_band) const return result; } -void FrequencyList_v2::reset_to_defaults () +void FrequencyList_v2_101::reset_to_defaults () { m_->frequency_list (default_frequency_list); } -QModelIndex FrequencyList_v2::add (Item f) +QModelIndex FrequencyList_v2_101::add (Item f) { return mapFromSource (m_->add (f)); } -bool FrequencyList_v2::remove (Item f) +bool FrequencyList_v2_101::remove (Item f) { auto row = m_->frequency_list_.indexOf (f); @@ -575,7 +575,7 @@ bool FrequencyList_v2::remove (Item f) return m_->removeRow (row); } -bool FrequencyList_v2::removeDisjointRows (QModelIndexList rows) +bool FrequencyList_v2_101::removeDisjointRows (QModelIndexList rows) { bool result {true}; @@ -602,7 +602,7 @@ bool FrequencyList_v2::removeDisjointRows (QModelIndexList rows) return result; } -void FrequencyList_v2::filter (Region region, Mode mode, bool filter_on_time) +void FrequencyList_v2_101::filter (Region region, Mode mode, bool filter_on_time) { m_->region_filter_ = region; m_->mode_filter_ = mode; @@ -610,12 +610,12 @@ void FrequencyList_v2::filter (Region region, Mode mode, bool filter_on_time) invalidateFilter (); } -void FrequencyList_v2::filter_refresh () +void FrequencyList_v2_101::filter_refresh () { invalidateFilter (); } -bool FrequencyList_v2::filterAcceptsRow (int source_row, QModelIndex const& /* parent */) const +bool FrequencyList_v2_101::filterAcceptsRow (int source_row, QModelIndex const& /* parent */) const { bool result {true}; auto const& item = m_->frequency_list_[source_row]; @@ -638,7 +638,7 @@ bool FrequencyList_v2::filterAcceptsRow (int source_row, QModelIndex const& /* p } -auto FrequencyList_v2::impl::frequency_list (FrequencyItems frequency_list) -> FrequencyItems +auto FrequencyList_v2_101::impl::frequency_list (FrequencyItems frequency_list) -> FrequencyItems { beginResetModel (); std::swap (frequency_list_, frequency_list); @@ -647,7 +647,7 @@ auto FrequencyList_v2::impl::frequency_list (FrequencyItems frequency_list) -> F } // add a frequency returning the new model index -QModelIndex FrequencyList_v2::impl::add (Item f) +QModelIndex FrequencyList_v2_101::impl::add (Item f) { // Any Frequency that isn't in the list may be added if (!frequency_list_.contains (f)) @@ -666,7 +666,7 @@ QModelIndex FrequencyList_v2::impl::add (Item f) return QModelIndex {}; } -void FrequencyList_v2::impl::add (FrequencyItems items) +void FrequencyList_v2_101::impl::add (FrequencyItems items) { // Any Frequency that isn't in the list may be added for (auto p = items.begin (); p != items.end ();) @@ -691,17 +691,17 @@ void FrequencyList_v2::impl::add (FrequencyItems items) } } -int FrequencyList_v2::impl::rowCount (QModelIndex const& parent) const +int FrequencyList_v2_101::impl::rowCount (QModelIndex const& parent) const { return parent.isValid () ? 0 : frequency_list_.size (); } -int FrequencyList_v2::impl::columnCount (QModelIndex const& parent) const +int FrequencyList_v2_101::impl::columnCount (QModelIndex const& parent) const { return parent.isValid () ? 0 : num_cols; } -Qt::ItemFlags FrequencyList_v2::impl::flags (QModelIndex const& index) const +Qt::ItemFlags FrequencyList_v2_101::impl::flags (QModelIndex const& index) const { auto result = QAbstractTableModel::flags (index) | Qt::ItemIsDropEnabled; auto row = index.row (); @@ -723,7 +723,7 @@ Qt::ItemFlags FrequencyList_v2::impl::flags (QModelIndex const& index) const return result; } -QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const +QVariant FrequencyList_v2_101::impl::data (QModelIndex const& index, int role) const { QVariant item; @@ -819,7 +819,7 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const { auto const& band = bands_->find (frequency_item.frequency_); QString desc_text; - desc_text = frequency_item.description_.isEmpty() ? "" : " \u2016 " + frequency_item.description_; + desc_text = frequency_item.description_.isEmpty() ? "" : " \u2502 " + frequency_item.description_; item = (frequency_item.preferred_ ? "\u2055 " : "") + Radio::pretty_frequency_MHz_string(frequency_item.frequency_) + " MHz (" + (band.isEmpty() ? "OOB" : band) + ")" + @@ -981,7 +981,7 @@ QVariant FrequencyList_v2::impl::data (QModelIndex const& index, int role) const return item; } -void FrequencyList_v2::impl::unprefer_all_but(Item &item, int const item_row, QVector roles) +void FrequencyList_v2_101::impl::unprefer_all_but(Item &item, int const item_row, QVector roles) { // un-prefer all of the other frequencies in this band auto const band = bands_->find (item.frequency_); @@ -1005,7 +1005,7 @@ void FrequencyList_v2::impl::unprefer_all_but(Item &item, int const item_row, QV } } -bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant const& value, int role) +bool FrequencyList_v2_101::impl::setData (QModelIndex const& model_index, QVariant const& value, int role) { bool changed {false}; auto const& row = model_index.row (); @@ -1159,7 +1159,7 @@ bool FrequencyList_v2::impl::setData (QModelIndex const& model_index, QVariant c return changed; } -QVariant FrequencyList_v2::impl::headerData (int section, Qt::Orientation orientation, int role) const +QVariant FrequencyList_v2_101::impl::headerData (int section, Qt::Orientation orientation, int role) const { QVariant header; if (Qt::DisplayRole == role @@ -1186,7 +1186,7 @@ QVariant FrequencyList_v2::impl::headerData (int section, Qt::Orientation orient return header; } -bool FrequencyList_v2::impl::removeRows (int row, int count, QModelIndex const& parent) +bool FrequencyList_v2_101::impl::removeRows (int row, int count, QModelIndex const& parent) { if (0 < count && (row + count) <= rowCount (parent)) { @@ -1201,7 +1201,7 @@ bool FrequencyList_v2::impl::removeRows (int row, int count, QModelIndex const& return false; } -bool FrequencyList_v2::impl::insertRows (int row, int count, QModelIndex const& parent) +bool FrequencyList_v2_101::impl::insertRows (int row, int count, QModelIndex const& parent) { if (0 < count) { @@ -1216,14 +1216,14 @@ bool FrequencyList_v2::impl::insertRows (int row, int count, QModelIndex const& return false; } -QStringList FrequencyList_v2::impl::mimeTypes () const +QStringList FrequencyList_v2_101::impl::mimeTypes () const { QStringList types; types << mime_type; return types; } -QMimeData * FrequencyList_v2::impl::mimeData (QModelIndexList const& items) const +QMimeData * FrequencyList_v2_101::impl::mimeData (QModelIndexList const& items) const { QMimeData * mime_data = new QMimeData {}; QByteArray encoded_data; @@ -1241,43 +1241,43 @@ QMimeData * FrequencyList_v2::impl::mimeData (QModelIndexList const& items) cons return mime_data; } -auto FrequencyList_v2::const_iterator::operator * () const -> Item const& +auto FrequencyList_v2_101::const_iterator::operator * () const -> Item const& { return parent_->frequency_list ().at(parent_->mapToSource (parent_->index (row_, 0)).row ()); } -auto FrequencyList_v2::const_iterator::operator -> () const -> Item const * +auto FrequencyList_v2_101::const_iterator::operator -> () const -> Item const * { return &parent_->frequency_list ().at(parent_->mapToSource (parent_->index (row_, 0)).row ()); } -bool FrequencyList_v2::const_iterator::operator != (const_iterator const& rhs) const +bool FrequencyList_v2_101::const_iterator::operator != (const_iterator const& rhs) const { return parent_ != rhs.parent_ || row_ != rhs.row_; } -bool FrequencyList_v2::const_iterator::operator == (const_iterator const& rhs) const +bool FrequencyList_v2_101::const_iterator::operator == (const_iterator const& rhs) const { return parent_ == rhs.parent_ && row_ == rhs.row_; } -auto FrequencyList_v2::const_iterator::operator ++ () -> const_iterator& +auto FrequencyList_v2_101::const_iterator::operator ++ () -> const_iterator& { ++row_; return *this; } -auto FrequencyList_v2::begin () const -> const_iterator +auto FrequencyList_v2_101::begin () const -> const_iterator { return const_iterator (this, 0); } -auto FrequencyList_v2::end () const -> const_iterator +auto FrequencyList_v2_101::end () const -> const_iterator { return const_iterator (this, rowCount ()); } -auto FrequencyList_v2::find (Frequency f) const -> const_iterator +auto FrequencyList_v2_101::find (Frequency f) const -> const_iterator { int row {0}; for (; row < rowCount (); ++row) @@ -1290,7 +1290,7 @@ auto FrequencyList_v2::find (Frequency f) const -> const_iterator return const_iterator (this, row); } -auto FrequencyList_v2::filtered_bands () const -> BandSet +auto FrequencyList_v2_101::filtered_bands () const -> BandSet { BandSet result; for (auto const& item : *this) @@ -1300,7 +1300,7 @@ auto FrequencyList_v2::filtered_bands () const -> BandSet return result; } -auto FrequencyList_v2::all_bands (Region region, Mode mode) const -> BandSet +auto FrequencyList_v2_101::all_bands (Region region, Mode mode) const -> BandSet { BandSet result; for (auto const& item : m_->frequency_list_) @@ -1317,9 +1317,9 @@ auto FrequencyList_v2::all_bands (Region region, Mode mode) const -> BandSet return result; } -FrequencyList_v2::FrequencyItems FrequencyList_v2::from_json_file(QFile *input_file) +FrequencyList_v2_101::FrequencyItems FrequencyList_v2_101::from_json_file(QFile *input_file) { - FrequencyList_v2::FrequencyItems list; + FrequencyList_v2_101::FrequencyItems list; QJsonDocument doc = QJsonDocument::fromJson(input_file->readAll()); if (doc.isNull()) { @@ -1341,7 +1341,7 @@ FrequencyList_v2::FrequencyItems FrequencyList_v2::from_json_file(QFile *input_f { QString mode_s, region_s; QJsonObject obj = item.toObject(); - FrequencyList_v2::Item freq; + FrequencyList_v2_101::Item freq; region_s = obj["region"].toString(); mode_s = obj["mode"].toString(); @@ -1369,7 +1369,7 @@ FrequencyList_v2::FrequencyItems FrequencyList_v2::from_json_file(QFile *input_f return list; } // write JSON format to a file -void FrequencyList_v2::to_json_file(QFile *output_file, QString magic_s, QString version_s, +void FrequencyList_v2_101::to_json_file(QFile *output_file, QString magic_s, QString version_s, FrequencyItems const &frequency_items) { QJsonObject jobject{ @@ -1390,13 +1390,20 @@ void FrequencyList_v2::to_json_file(QFile *output_file, QString magic_s, QString } // previous version 100 of the FrequencyList_v2 class -QDataStream& operator >> (QDataStream& is, FrequencyList_v2_100::Item& item) +QDataStream& operator >> (QDataStream& is, FrequencyList_v2::Item& item) { return is >> item.frequency_ >> item.mode_ >> item.region_; } +QDataStream& operator << (QDataStream& os, FrequencyList_v2::Item const& item) +{ + return os << item.frequency_ + << item.mode_ + << item.region_; +} + // // Obsolete version of FrequencyList no longer used but needed to // allow loading and saving of old settings contents without damage diff --git a/models/FrequencyList.hpp b/models/FrequencyList.hpp index 4e845bd6d..04b51a863 100644 --- a/models/FrequencyList.hpp +++ b/models/FrequencyList.hpp @@ -42,7 +42,7 @@ class Bands; // Implements the QSortFilterProxyModel interface for a list of spot // frequencies. // -class FrequencyList_v2 final +class FrequencyList_v2_101 final : public QSortFilterProxyModel { Q_OBJECT; @@ -76,7 +76,7 @@ public: class const_iterator { public: - const_iterator (FrequencyList_v2 const * parent, int row) + const_iterator (FrequencyList_v2_101 const * parent, int row) : parent_ {parent} , row_ {row} { @@ -89,13 +89,13 @@ public: const_iterator& operator ++ (); private: - FrequencyList_v2 const * parent_; + FrequencyList_v2_101 const * parent_; int row_; }; - explicit FrequencyList_v2 (Bands const *, QObject * parent = nullptr); + explicit FrequencyList_v2_101 (Bands const *, QObject * parent = nullptr); - ~FrequencyList_v2 (); + ~FrequencyList_v2_101 (); // Load and store underlying items FrequencyItems frequency_list (FrequencyItems); @@ -157,7 +157,7 @@ private: }; inline -bool operator == (FrequencyList_v2::Item const& lhs, FrequencyList_v2::Item const& rhs) +bool operator == (FrequencyList_v2_101::Item const& lhs, FrequencyList_v2_101::Item const& rhs) { return lhs.frequency_ == rhs.frequency_ @@ -170,18 +170,19 @@ bool operator == (FrequencyList_v2::Item const& lhs, FrequencyList_v2::Item cons && lhs.preferred_ == rhs.preferred_; } -QDataStream& operator << (QDataStream&, FrequencyList_v2::Item const&); -QDataStream& operator >> (QDataStream&, FrequencyList_v2::Item&); +QDataStream& operator << (QDataStream&, FrequencyList_v2_101::Item const&); +QDataStream& operator >> (QDataStream&, FrequencyList_v2_101::Item&); #if !defined (QT_NO_DEBUG_STREAM) -QDebug operator << (QDebug, FrequencyList_v2::Item const&); +QDebug operator << (QDebug, FrequencyList_v2_101::Item const&); #endif -Q_DECLARE_METATYPE (FrequencyList_v2::Item); -Q_DECLARE_METATYPE (FrequencyList_v2::FrequencyItems); +Q_DECLARE_METATYPE (FrequencyList_v2_101::Item); +Q_DECLARE_METATYPE (FrequencyList_v2_101::FrequencyItems); -class FrequencyList_v2_100 final +class FrequencyList_v2 final { + public: using Frequency = Radio::Frequency; using Mode = Modes::Mode; @@ -200,11 +201,11 @@ private: FrequencyItems frequency_list_; }; -QDataStream& operator << (QDataStream&, FrequencyList_v2_100::Item const&); -QDataStream& operator >> (QDataStream&, FrequencyList_v2_100::Item&); +QDataStream& operator << (QDataStream&, FrequencyList_v2::Item const&); +QDataStream& operator >> (QDataStream&, FrequencyList_v2::Item&); -Q_DECLARE_METATYPE (FrequencyList_v2_100::Item); -Q_DECLARE_METATYPE (FrequencyList_v2_100::FrequencyItems); +Q_DECLARE_METATYPE (FrequencyList_v2::Item); +Q_DECLARE_METATYPE (FrequencyList_v2::FrequencyItems); // // Obsolete version of FrequencyList no longer used but needed to diff --git a/models/StationList.cpp b/models/StationList.cpp index ff8d153f0..2b5012597 100644 --- a/models/StationList.cpp +++ b/models/StationList.cpp @@ -527,7 +527,7 @@ bool StationList::impl::dropMimeData (QMimeData const * data, Qt::DropAction act QDataStream stream {&encoded_data, QIODevice::ReadOnly}; while (!stream.atEnd ()) { - FrequencyList_v2::Item item; + FrequencyList_v2_101::Item item; stream >> item; auto const& band = bands_->find (item.frequency_); if (stations_.cend () == std::find_if (stations_.cbegin () diff --git a/translations/wsjtx_ca.ts b/translations/wsjtx_ca.ts index 287a45a87..db7c4fe94 100644 --- a/translations/wsjtx_ca.ts +++ b/translations/wsjtx_ca.ts @@ -1477,7 +1477,7 @@ Error: %2 - %3 - FrequencyList_v2 + FrequencyList_v2_100 diff --git a/translations/wsjtx_es.ts b/translations/wsjtx_es.ts index 3a750b2cf..e2cc8caf7 100644 --- a/translations/wsjtx_es.ts +++ b/translations/wsjtx_es.ts @@ -1630,7 +1630,7 @@ Error: %2 - %3 - FrequencyList_v2 + FrequencyList_v2_100 diff --git a/translations/wsjtx_zh_HK.ts b/translations/wsjtx_zh_HK.ts index fc16afbdc..86f599a31 100644 --- a/translations/wsjtx_zh_HK.ts +++ b/translations/wsjtx_zh_HK.ts @@ -1475,7 +1475,7 @@ Error: %2 - %3 - FrequencyList_v2 + FrequencyList_v2_100 diff --git a/translations/wsjtx_zh_TW.ts b/translations/wsjtx_zh_TW.ts index 15c9131de..a4b23d7d3 100644 --- a/translations/wsjtx_zh_TW.ts +++ b/translations/wsjtx_zh_TW.ts @@ -1475,7 +1475,7 @@ Error: %2 - %3 - FrequencyList_v2 + FrequencyList_v2_100 diff --git a/validators/LiveFrequencyValidator.cpp b/validators/LiveFrequencyValidator.cpp index 873224920..70c992a9d 100644 --- a/validators/LiveFrequencyValidator.cpp +++ b/validators/LiveFrequencyValidator.cpp @@ -12,7 +12,7 @@ LiveFrequencyValidator::LiveFrequencyValidator (QComboBox * combo_box , Bands const * bands - , FrequencyList_v2 const * frequencies + , FrequencyList_v2_101 const * frequencies , Frequency const * nominal_frequency , QWidget * parent) : QRegExpValidator { diff --git a/validators/LiveFrequencyValidator.hpp b/validators/LiveFrequencyValidator.hpp index 823f8f745..4224d89a4 100644 --- a/validators/LiveFrequencyValidator.hpp +++ b/validators/LiveFrequencyValidator.hpp @@ -7,7 +7,7 @@ #include "Radio.hpp" class Bands; -class FrequencyList_v2; +class FrequencyList_v2_101; class QComboBox; class QWidget; @@ -35,7 +35,7 @@ public: LiveFrequencyValidator (QComboBox * combo_box // associated combo box , Bands const * bands // bands model - , FrequencyList_v2 const * frequencies // working frequencies model + , FrequencyList_v2_101 const * frequencies // working frequencies model , Frequency const * nominal_frequency , QWidget * parent = nullptr); @@ -46,7 +46,7 @@ public: private: Bands const * bands_; - FrequencyList_v2 const * frequencies_; + FrequencyList_v2_101 const * frequencies_; Frequency const * nominal_frequency_; QComboBox * combo_box_; }; diff --git a/widgets/BandComboBox.cpp b/widgets/BandComboBox.cpp index 0dc8eba61..7dfb77e08 100644 --- a/widgets/BandComboBox.cpp +++ b/widgets/BandComboBox.cpp @@ -15,7 +15,7 @@ BandComboBox::BandComboBox (QWidget * parent) // item text. void BandComboBox::showPopup () { - auto minimum_width = view ()->sizeHintForColumn (FrequencyList_v2::frequency_mhz_column); + auto minimum_width = view ()->sizeHintForColumn (FrequencyList_v2_101::frequency_mhz_column); if (count () > maxVisibleItems ()) { // for some as yet unknown reason, in FT8 mode the scrollbar diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 6de200886..2db7bddf0 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -783,7 +783,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, // Hook up working frequencies. ui->bandComboBox->setModel (m_config.frequencies ()); - ui->bandComboBox->setModelColumn (FrequencyList_v2::frequency_mhz_column); + ui->bandComboBox->setModelColumn (FrequencyList_v2_101::frequency_mhz_column); // Enable live band combo box entry validation and action. auto band_validator = new LiveFrequencyValidator {ui->bandComboBox @@ -7414,7 +7414,7 @@ void MainWindow::on_actionOpen_log_directory_triggered () void MainWindow::on_bandComboBox_currentIndexChanged (int index) { auto const& frequencies = m_config.frequencies (); - auto const& source_index = frequencies->mapToSource (frequencies->index (index, FrequencyList_v2::frequency_column)); + auto const& source_index = frequencies->mapToSource (frequencies->index (index, FrequencyList_v2_101::frequency_column)); Frequency frequency {m_freqNominal}; if (source_index.isValid ()) { @@ -7442,7 +7442,7 @@ void MainWindow::on_bandComboBox_editTextChanged (QString const& text) void MainWindow::on_bandComboBox_activated (int index) { auto const& frequencies = m_config.frequencies (); - auto const& source_index = frequencies->mapToSource (frequencies->index (index, FrequencyList_v2::frequency_column)); + auto const& source_index = frequencies->mapToSource (frequencies->index (index, FrequencyList_v2_101::frequency_column)); Frequency frequency {m_freqNominal}; if (source_index.isValid ()) { diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index dca2e9cbb..9f12f7971 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -477,7 +477,7 @@ private: qint32 m_k0; qint32 m_kdone; qint32 m_nPick; - FrequencyList_v2::const_iterator m_frequency_list_fcal_iter; + FrequencyList_v2_101::const_iterator m_frequency_list_fcal_iter; qint32 m_nTx73; qint32 m_UTCdisk; qint32 m_wait; From 2b08cd9e4bd679506ae728e68505543b8d543361 Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Sat, 12 Nov 2022 17:23:21 -0800 Subject: [PATCH 08/20] manage hound queue; add ability to add hound to top with ALT-double-click; show/manipulate hound QSOs in progress --- widgets/displaytext.cpp | 19 +- widgets/displaytext.h | 7 +- widgets/mainwindow.cpp | 195 +- widgets/mainwindow.h | 5 +- widgets/mainwindow.ui | 132 +- widgets/mainwindow.ui.autosave | 3921 ++++++++++++++++++++++++++++++++ 6 files changed, 4189 insertions(+), 90 deletions(-) create mode 100644 widgets/mainwindow.ui.autosave diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index 65fc1d40b..bdbad0e69 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -86,7 +86,7 @@ void DisplayText::mouseDoubleClickEvent(QMouseEvent *e) void DisplayText::insertLineSpacer(QString const& line) { - appendText (line, "#d3d3d3"); + insertText (line, "#d3d3d3"); } namespace @@ -123,11 +123,11 @@ namespace } } -void DisplayText::appendText(QString const& text, QColor bg, QColor fg - , QString const& call1, QString const& call2) +void DisplayText::insertText(QString const& text, QColor bg, QColor fg + , QString const& call1, QString const& call2, QTextCursor::MoveOperation location) { auto cursor = textCursor (); - cursor.movePosition (QTextCursor::End); + cursor.movePosition (location); auto block_format = cursor.blockFormat (); auto format = cursor.blockCharFormat (); format.setFont (char_font_); @@ -484,7 +484,7 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con } } - appendText (message.trimmed (), bg, fg, decodedText.call (), dxCall); + insertText (message.trimmed (), bg, fg, decodedText.call (), dxCall); } @@ -516,18 +516,19 @@ void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 tx QColor fg; highlight_types types {Highlight::Tx}; set_colours (m_config, &bg, &fg, types); - appendText (t, bg, fg); + insertText (t, bg, fg); } void DisplayText::displayQSY(QString text) { QString t = QDateTime::currentDateTimeUtc().toString("hhmmss") + " " + text; - appendText (t, "hotpink"); + insertText (t, "hotpink"); } -void DisplayText::displayFoxToBeCalled(QString t, QColor bg, QColor fg) +void DisplayText::displayHoundToBeCalled(QString t, bool bAtTop, QColor bg, QColor fg) { - appendText (t, bg, fg); + if (bAtTop) t = t + "\n"; // need a newline when insertion at top + insertText(t, bg, fg, "", "", bAtTop ? QTextCursor::Start : QTextCursor::End); } namespace diff --git a/widgets/displaytext.h b/widgets/displaytext.h index 5810972cd..b0db7ca8b 100644 --- a/widgets/displaytext.h +++ b/widgets/displaytext.h @@ -33,7 +33,7 @@ public: bool haveFSpread = false, float fSpread = 0.0, bool bDisplayPoints=false, int points=-99); void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, bool bFastMode, double TRperiod); void displayQSY(QString text); - void displayFoxToBeCalled(QString t, QColor bg = QColor {}, QColor fg = QColor {}); + void displayHoundToBeCalled(QString t, bool bAtTop=false, QColor bg = QColor {}, QColor fg = QColor {}); void new_period (); QString CQPriority(){return m_CQPriority;}; qint32 m_points; @@ -42,8 +42,8 @@ public: Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers); Q_SIGNAL void erased (); - Q_SLOT void appendText (QString const& text, QColor bg = QColor {}, QColor fg = QColor {} - , QString const& call1 = QString {}, QString const& call2 = QString {}); + Q_SLOT void insertText (QString const& text, QColor bg = QColor {}, QColor fg = QColor {} + , QString const& call1 = QString {}, QString const& call2 = QString {}, QTextCursor::MoveOperation location=QTextCursor::End); Q_SLOT void erase (); Q_SLOT void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_period_only); @@ -62,6 +62,7 @@ private: , QString const& currentMode, QString extra); QFont char_font_; QAction * erase_action_; + QHash> highlighted_calls_; bool high_volume_; QMetaObject::Connection vertical_scroll_connection_; diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 72d370fe5..52b353112 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -655,7 +655,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, connect(txMsgButtonGroup,SIGNAL(buttonClicked(int)),SLOT(set_ntx(int))); connect (ui->decodedTextBrowser, &DisplayText::selectCallsign, this, &MainWindow::doubleClickOnCall2); connect (ui->decodedTextBrowser2, &DisplayText::selectCallsign, this, &MainWindow::doubleClickOnCall); - connect (ui->textBrowser4, &DisplayText::selectCallsign, this, &MainWindow::doubleClickOnFoxQueue); + connect (ui->houndQueueTextBrowser, &DisplayText::selectCallsign, this, &MainWindow::doubleClickOnFoxQueue); + connect (ui->foxTxListTextBrowser, &DisplayText::selectCallsign, this, &MainWindow::doubleClickOnFoxInProgress); connect (ui->decodedTextBrowser, &DisplayText::erased, this, &MainWindow::band_activity_cleared); connect (ui->decodedTextBrowser2, &DisplayText::erased, this, &MainWindow::rx_frequency_activity_cleared); @@ -1425,9 +1426,14 @@ void MainWindow::setDecodedTextFont (QFont const& font) { ui->decodedTextBrowser->setContentFont (font); ui->decodedTextBrowser2->setContentFont (font); - ui->textBrowser4->setContentFont(font); - ui->textBrowser4->displayFoxToBeCalled(" "); - ui->textBrowser4->setText(""); + ui->houndQueueTextBrowser->setContentFont(font); + ui->houndQueueTextBrowser->displayHoundToBeCalled(" "); + ui->houndQueueTextBrowser->setText(""); + + ui->foxTxListTextBrowser->setContentFont(font); + ui->foxTxListTextBrowser->displayHoundToBeCalled(" "); + ui->foxTxListTextBrowser->setText(""); + auto style_sheet = "QLabel {" + font_as_stylesheet (font) + '}'; ui->lh_decodes_headings_label->setStyleSheet (ui->lh_decodes_headings_label->styleSheet () + style_sheet); ui->rh_decodes_headings_label->setStyleSheet (ui->rh_decodes_headings_label->styleSheet () + style_sheet); @@ -1653,7 +1659,7 @@ void MainWindow::dataSink(qint64 frames) t = t.asprintf("%9.6f %5.2f %7d %7.1f %7d %7d %7d %7.1f %7.1f",hour,xlevel, nDopTotal,width,echocom_.nsum,nqual,qRound(dfreq),sigdb,dBerr); t = t0 + t; - if (ui) ui->decodedTextBrowser->appendText(t); + if (ui) ui->decodedTextBrowser->insertText(t); t=t1+t; write_all("Rx",t); } @@ -2093,7 +2099,6 @@ void MainWindow::auto_tx_mode (bool state) void MainWindow::keyPressEvent (QKeyEvent * e) { - if(SpecOp::FOX == m_specOp) { switch (e->key()) { case Qt::Key_Return: @@ -2105,6 +2110,13 @@ void MainWindow::keyPressEvent (QKeyEvent * e) case Qt::Key_Backspace: qDebug() << "Key Backspace"; return; +#ifdef DEBUG_FOX + case Qt::Key_X: + if(e->modifiers() & Qt::AltModifier) { + foxTest(); + return; + } +#endif } QMainWindow::keyPressEvent (e); } @@ -4878,7 +4890,7 @@ void MainWindow::startTx2() t = " Transmitting " + m_mode + " ----------------------- " + m_config.bands ()->find (m_freqNominal); t=beacon_start_time (m_TRperiod / 2) + ' ' + t.rightJustified (66, '-'); - ui->decodedTextBrowser->appendText(t); + ui->decodedTextBrowser->insertText(t); } write_all("Tx",m_currentMessage); } @@ -5157,7 +5169,7 @@ void MainWindow::doubleClickOnCall(Qt::KeyboardModifiers modifiers) if(SpecOp::FOX==m_specOp and m_decodedText2) { if(m_houndQueue.count()<10 and m_nSortedHounds>0) { QString t=cursor.block().text(); - selectHound(t); + selectHound(t, modifiers==(Qt::AltModifier)); // alt double-click gets put at top of queue } return; } @@ -8495,7 +8507,7 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout t = " " + tr ("Receiving") + " " + m_mode + " ----------------------- " + m_config.bands ()->find (m_dialFreqRxWSPR); t=beacon_start_time (-m_TRperiod / 2) + ' ' + t.rightJustified (66, '-'); - ui->decodedTextBrowser->appendText(t); + ui->decodedTextBrowser->insertText(t); } killFileTimer.start (45*1000); //Kill in 45s (for slow modes) } @@ -8569,12 +8581,12 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout QString band; Frequency f=1000000.0*rxFields.at(3).toDouble()+0.5; band = ' ' + m_config.bands ()->find (f); - ui->decodedTextBrowser->appendText(band.rightJustified (71, '-')); + ui->decodedTextBrowser->insertText(band.rightJustified (71, '-')); } m_tBlankLine = rxLine.left(4); } m_nWSPRdecodes += 1; - ui->decodedTextBrowser->appendText(rxLine); + ui->decodedTextBrowser->insertText(rxLine); } } } @@ -9157,7 +9169,9 @@ void MainWindow::on_pbFoxReset_clicked() QFile f(m_config.temp_dir().absoluteFilePath("houndcallers.txt")); f.remove(); ui->decodedTextBrowser->setText(""); - ui->textBrowser4->setText(""); + ui->houndQueueTextBrowser->setText(""); + ui->foxTxListTextBrowser->setText(""); + m_houndQueue.clear(); m_foxQSO.clear(); m_foxQSOinProgress.clear(); @@ -9277,19 +9291,18 @@ QString MainWindow::sortHoundCalls(QString t, int isort, int max_dB) } //------------------------------------------------------------------------------ -void MainWindow::selectHound(QString line) +void MainWindow::selectHound(QString line, bool bTopQueue) { /* Called from doubleClickOnCall() in DXpedition Fox mode. * QString "line" is a user-selected line from left text window. * The line may be selected by double-clicking; alternatively, hitting * is equivalent to double-clicking on the top-most line. */ - if(line.length()==0) return; QString houndCall=line.split(" ",SkipEmptyParts).at(0); // Don't add a call already enqueued or in QSO - if(ui->textBrowser4->toPlainText().indexOf(houndCall) >= 0) return; + if(ui->houndQueueTextBrowser->toPlainText().indexOf(houndCall) >= 0) return; QString houndGrid=line.split(" ",SkipEmptyParts).at(1); // Hound caller's grid QString rpt=line.split(" ",SkipEmptyParts).at(2); // Hound SNR @@ -9299,16 +9312,25 @@ void MainWindow::selectHound(QString line) ui->decodedTextBrowser->setText(m_houndCallers); // Populate left window with Hound callers QString t1=houndCall + " "; QString t2=rpt; + QString t1_with_grid; if(rpt.mid(0,1) != "-" and rpt.mid(0,1) != "+") t2="+" + rpt; if(t2.length()==2) t2=t2.mid(0,1) + "0" + t2.mid(1,1); t1=t1.mid(0,12) + t2; - ui->textBrowser4->displayFoxToBeCalled(t1); // Add hound call and rpt to tb4 - t1=t1 + " " + houndGrid; // Append the grid - m_houndQueue.enqueue(t1); // Put this hound into the queue - writeFoxQSO(" Sel: " + t1); - QTextCursor cursor = ui->textBrowser4->textCursor(); + ui->houndQueueTextBrowser->displayHoundToBeCalled(t1, bTopQueue); // Add hound call and rpt to tb4 + t1_with_grid=t1 + " " + houndGrid; // Append the grid + + if (bTopQueue) + { + m_houndQueue.prepend(t1_with_grid); // Put this hound into the queue at the top + } + else + { + m_houndQueue.enqueue(t1_with_grid); // Put this hound into the queue + } + writeFoxQSO(" Sel: " + t1_with_grid); + QTextCursor cursor = ui->houndQueueTextBrowser->textCursor(); cursor.setPosition(0); // Scroll to top of list - ui->textBrowser4->setTextCursor(cursor); + ui->houndQueueTextBrowser->setTextCursor(cursor); } //------------------------------------------------------------------------------ @@ -9337,7 +9359,7 @@ void MainWindow::houndCallers() houndCall=line.mid(0,i0); paddedHoundCall=houndCall + " "; //Don't list a hound already in the queue - if(!ui->textBrowser4->toPlainText().contains(paddedHoundCall)) { + if(!ui->houndQueueTextBrowser->toPlainText().contains(paddedHoundCall)) { if(m_loggedByFox[houndCall].contains(m_lastBand)) continue; //already logged on this band if(m_foxQSO.contains(houndCall)) continue; //still in the QSO map auto const& entity = m_logBook.countries ()->lookup (houndCall); @@ -9394,6 +9416,19 @@ void MainWindow::foxRxSequencer(QString msg, QString houndCall, QString rptRcvd) } } } +void MainWindow::updateFoxQSOsInProgressDisplay() +{ + + ui->foxTxListTextBrowser->clear(); + for (int i = 0; i < m_foxQSOinProgress.count(); i++) + { + //First do those for QSOs in progress + QString hc = m_foxQSOinProgress.at(i); + QString status = m_foxQSO[hc].ncall > m_maxStrikes ? QString(" (rx) ") : QString(" "); + QString str = (hc + " ").left(13) + QString::number(m_foxQSO[hc].ncall) + status; + ui->foxTxListTextBrowser->displayHoundToBeCalled(str); + } +} void MainWindow::foxTxSequencer() { @@ -9590,13 +9625,14 @@ Transmit: m_foxLogWindow->rate (m_foxRateQueue.size ()); m_foxLogWindow->queued (m_foxQSOinProgress.count ()); } + updateFoxQSOsInProgressDisplay(); } void MainWindow::rm_tb4(QString houndCall) { if(houndCall=="") return; QString t=""; - QString tb4=ui->textBrowser4->toPlainText(); + QString tb4=ui->houndQueueTextBrowser->toPlainText(); QStringList list=tb4.split("\n"); int n=list.size(); int j=0; @@ -9609,24 +9645,78 @@ void MainWindow::rm_tb4(QString houndCall) } } t.replace("\n\n","\n"); - ui->textBrowser4->setText(t); + ui->houndQueueTextBrowser->setText(t); } void MainWindow::doubleClickOnFoxQueue(Qt::KeyboardModifiers modifiers) { if(modifiers==9999) return; //Silence compiler warning - QTextCursor cursor=ui->textBrowser4->textCursor(); + QTextCursor cursor=ui->houndQueueTextBrowser->textCursor(); cursor.setPosition(cursor.selectionStart()); - QString houndCall=cursor.block().text().mid(0,12).trimmed(); - rm_tb4(houndCall); - writeFoxQSO(" Del: " + houndCall); - QQueue tmpQueue; - while(!m_houndQueue.isEmpty()) { - QString t=m_houndQueue.dequeue(); - QString hc=t.mid(0,12).trimmed(); - if(hc != houndCall) tmpQueue.enqueue(t); - } - m_houndQueue.swap(tmpQueue); + QString houndLine=cursor.block().text(); + QString houndCall=houndLine.mid(0,12).trimmed(); + + if (modifiers == (Qt::AltModifier)) + { + //Alt-click on a Fox queue entry - put on top of queue + // remove + for(auto i=0; ihoundQueueTextBrowser->clear(); + for (QString line: m_houndQueue) + { + ui->houndQueueTextBrowser->displayHoundToBeCalled(line.mid(0,16), false); + } + } else + { + rm_tb4(houndCall); + writeFoxQSO(" Del: " + houndCall); + QQueue tmpQueue; + while (!m_houndQueue.isEmpty()) + { + QString t = m_houndQueue.dequeue(); + QString hc = t.mid(0, 12).trimmed(); + if (hc != houndCall) tmpQueue.enqueue(t); + } + m_houndQueue.swap(tmpQueue); + } +} + +void MainWindow::doubleClickOnFoxInProgress(Qt::KeyboardModifiers modifiers) +{ + if (modifiers == 9999) return; //Silence compiler warning + QTextCursor cursor = ui->foxTxListTextBrowser->textCursor(); + cursor.setPosition(cursor.selectionStart()); + QString houndLine = cursor.block().text(); + QString houndCall = houndLine.mid(0, 12).trimmed(); + + if (modifiers == 0) + { + m_foxQSO[houndCall].ncall = m_maxStrikes + 1; // time them out + updateFoxQSOsInProgressDisplay(); + } +} + +void MainWindow::foxQueueTopCallCommand() +{ + m_decodedText2 = true; + if(SpecOp::FOX==m_specOp && m_decodedText2 && m_houndQueue.count() < 10) + { + + QTextCursor cursor = ui->decodedTextBrowser->textCursor(); + cursor.setPosition(cursor.selectionStart()); + QString houndCallLine = cursor.block().text(); + + writeFoxQSO(" QTop: " + houndCallLine); + selectHound(houndCallLine, true); // alt double-click gets put at top of queue + } } void MainWindow::foxGenWaveform(int i,QString fm) @@ -9680,14 +9770,29 @@ void MainWindow::writeFoxQSO(QString const& msg) /*################################################################################### */ void MainWindow::foxTest() { - QFile f("steps.txt"); - if(!f.open(QIODevice::ReadOnly | QIODevice::Text)) return; + QString curdir = QDir::currentPath(); + bool b_hounds_written = false; - QFile fdiag("diag.txt"); + QFile fdiag(m_config.writeable_data_dir ().absoluteFilePath("diag.txt")); if(!fdiag.open(QIODevice::WriteOnly | QIODevice::Text)) return; + QFile f(m_config.writeable_data_dir ().absoluteFilePath("steps.txt")); + if(!f.open(QIODevice::ReadOnly | QIODevice::Text)) { + fdiag.write("Cannot open steps.txt"); + return; + } + QTextStream s(&f); QTextStream sdiag(&fdiag); + + QFile fhounds(m_config.temp_dir().absoluteFilePath("houndcallers.txt")); + if(!fhounds.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) + { + sdiag << "can't write to houndcallers.txt"; + return; + } + QTextStream houndstream(&fhounds); + QString line; QString t; QString msg; @@ -9705,7 +9810,14 @@ void MainWindow::foxTest() } if(line.contains("Sel:")) { t=line.mid(43,6) + " " + line.mid(54,4) + " " + line.mid(50,3); - selectHound(t); + selectHound(t, false); + } + auto line_trimmed = line.trimmed(); + if(line_trimmed.startsWith("Hound:")) { + t=line_trimmed.mid(6,-1).trimmed(); + b_hounds_written = true; + //sdiag << t << Qt::endl; + houndstream << t << Qt::endl; } if(line.contains("Del:")) { @@ -9745,6 +9857,11 @@ void MainWindow::foxTest() sdiag << t << line.mid(37).trimmed() << "\n"; } } + if (b_hounds_written) + { + fhounds.close(); + houndCallers(); + } } void MainWindow::write_all(QString txRx, QString message) diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index d9e738920..80fbce9e5 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -127,6 +127,7 @@ public slots: void doubleClickOnCall (Qt::KeyboardModifiers); void doubleClickOnCall2(Qt::KeyboardModifiers); void doubleClickOnFoxQueue(Qt::KeyboardModifiers); + void doubleClickOnFoxInProgress(Qt::KeyboardModifiers modifiers); void readFromStdout(); void p1ReadFromStdout(); void setXIT(int n, Frequency base = 0u); @@ -832,8 +833,10 @@ private: void displayWidgets(qint64 n); QChar current_submode () const; // returns QChar {0} if submode is not appropriate void write_transmit_entry (QString const& file_name); - void selectHound(QString t); + void selectHound(QString t, bool bTopQueue); void houndCallers(); + void updateFoxQSOsInProgressDisplay(); + void foxQueueTopCallCommand(); void foxRxSequencer(QString msg, QString houndCall, QString rptRcvd); void foxTxSequencer(); void foxGenWaveform(int i,QString fm); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 733dc4dc9..0d027f31b 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -6,7 +6,7 @@ 0 0 - 901 + 1015 665 @@ -1018,7 +1018,7 @@ Yellow when too low 0 - + 0 @@ -1661,7 +1661,7 @@ When not checked you can view the calibration results. QTabWidget::Triangular - 0 + 1 @@ -2004,8 +2004,8 @@ Double-click to reset to the standard 73 message 2 - - + + @@ -2201,6 +2201,26 @@ Double-click to reset to the standard 73 message + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + More CQs + + + @@ -2248,47 +2268,84 @@ Double-click to reset to the standard 73 message - - - - Qt::Vertical + + + + + + 0 + + + -1 + + + + + true - + + + 0 + 0 + + + - 20 - 40 + 16777215 + 16777215 - + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + - - + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + + + + + + + 13 + + - More CQs + Queue + + + Qt::AlignCenter + + + + + + + In-QSO + + + Qt::AlignCenter - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - QAbstractScrollArea::AdjustToContentsOnFirstShow - - - @@ -3076,8 +3133,8 @@ QPushButton[state="ok"] { 0 0 - 901 - 22 + 1015 + 37 @@ -3836,7 +3893,6 @@ QPushButton[state="ok"] { tx6 txrb6 txb6 - textBrowser4 comboBoxHoundSort sbNlist sbMax_dB diff --git a/widgets/mainwindow.ui.autosave b/widgets/mainwindow.ui.autosave new file mode 100644 index 000000000..a328548fb --- /dev/null +++ b/widgets/mainwindow.ui.autosave @@ -0,0 +1,3921 @@ + + + MainWindow + + + + 0 + 0 + 1114 + 665 + + + + WSJT-X by K1JT + + + + + + + + + + Qt::Horizontal + + + + + + + + 500 + 16777215 + + + + + 10 + false + + + + Band Activity + + + Qt::AlignCenter + + + + + + + + 300 + 20 + + + + + 16777215 + 20 + + + + + + + + + 252 + 252 + 252 + + + + + + + 170 + 170 + 170 + + + + + + + + + 252 + 252 + 252 + + + + + + + 170 + 170 + 170 + + + + + + + + + 170 + 170 + 170 + + + + + + + 170 + 170 + 170 + + + + + + + + true + + + UTC dB DT Freq Dr + + + Qt::PlainText + + + 5 + + + + + + + QFrame::StyledPanel + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + 0 + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 10 + false + + + + Rx Frequency + + + Qt::AlignCenter + + + + + + + + 300 + 20 + + + + + 16777215 + 20 + + + + + + + + + 252 + 252 + 252 + + + + + + + 170 + 170 + 170 + + + + + + + + + 252 + 252 + 252 + + + + + + + 170 + 170 + 170 + + + + + + + + + 170 + 170 + 170 + + + + + + + 170 + 170 + 170 + + + + + + + + true + + + UTC dB DT Freq Dr + + + Qt::PlainText + + + 5 + + + + + + + true + + + Qt::ScrollBarAlwaysOn + + + 0 + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + CQ only + + + + + + + + 50 + 0 + + + + Enter this QSO in log + + + Log &QSO + + + + + + + + 50 + 0 + + + + Stop monitoring + + + &Stop + + + + + + + + 50 + 0 + + + + Toggle monitoring On/Off + + + QPushButton:checked { + color: #000000; + background-color: #00ff00; + border-style: outset; + border-width: 1px; + border-radius: 5px; + border-color: black; + min-width: 5em; + padding: 3px; +} + + + &Monitor + + + true + + + false + + + + + + + + 50 + 0 + + + + <html><head/><body><p>Erase right window. Double-click to erase both windows.</p></body></html> + + + Erase right window. Double-click to erase both windows. + + + &Erase + + + + + + + true + + + <html><head/><body><p>Clear the accumulating message average.</p></body></html> + + + Clear the accumulating message average. + + + Clear Avg + + + + + + + Avg + + + 1 + + + 100 + + + 10 + + + + + + + + 50 + 0 + + + + <html><head/><body><p>Decode most recent Rx period at QSO Frequency</p></body></html> + + + Decode most recent Rx period at QSO Frequency + + + QPushButton:checked { + color: rgb(0, 0, 0); + background-color: cyan; + border-style: outset; + border-width: 1px; + border-radius: 5px; + border-color: black; + min-width: 5em; + padding: 3px; +} + + + &Decode + + + true + + + + + + + + 50 + 0 + + + + <html><head/><body><p>Toggle Auto-Tx On/Off</p></body></html> + + + Toggle Auto-Tx On/Off + + + QPushButton:checked { + color: rgb(0, 0, 0); + background-color: red; + border-style: outset; + border-width: 1px; + border-radius: 5px; + border-color: black; + min-width: 5em; + padding: 3px; +} + + + E&nable Tx + + + true + + + + + + + + 50 + 0 + + + + Stop transmitting immediately + + + &Halt Tx + + + + + + + <html><head/><body><p>Toggle a pure Tx tone On/Off</p></body></html> + + + Toggle a pure Tx tone On/Off + + + QPushButton:checked { + color: rgb(0, 0, 0); + background-color: red; + border-style: outset; + border-width: 1px; + border-radius: 5px; + border-color: black; + min-width: 5em; + padding: 3px; +} + + + &Tune + + + true + + + + + + + Menus + + + true + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 159 + 175 + 213 + + + + + + + 159 + 175 + 213 + + + + + + + + true + + + DX Call + + + Qt::AlignCenter + + + 5 + + + 2 + + + dxCallEntry + + + + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 252 + 252 + 252 + + + + + + + 159 + 175 + 213 + + + + + + + + + 159 + 175 + 213 + + + + + + + 159 + 175 + 213 + + + + + + + + true + + + DX Grid + + + Qt::AlignCenter + + + 5 + + + 2 + + + dxGridEntry + + + + + + + + 0 + 0 + + + + Callsign of station to be worked + + + 11 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + Locator of station to be worked + + + ` + + + 6 + + + Qt::AlignCenter + + + + + + + + + Search for callsign in database + + + &Lookup + + + + + + + Add callsign and locator to database + + + Add + + + + + + + true + + + Az: 251 16553 km + + + Qt::AlignCenter + + + 4 + + + + + + + + + + + + Adjust Tx audio level + + + 450 + + + 0 + + + Qt::Vertical + + + true + + + true + + + QSlider::TicksBelow + + + 50 + + + + + + + Pwr + + + + + + + 6 + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Qt::AlignCenter + + + % + + + NB + + + -2 + + + 25 + + + + + + + 0 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> + + + Rx Signal + + + 30dB recommended when only noise present +Green when good +Red when clipping may occur +Yellow when too low + + + QFrame::Panel + + + QFrame::Sunken + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + + + + + 0 + 0 + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + false + + + <html><head/><body><p>Frequency to call CQ on in kHz above the current MHz</p></body></html> + + + Frequency to call CQ on in kHz above the current MHz + + + Tx CQ + + + 1 + + + 999 + + + 260 + + + + + + + false + + + <html><head/><body><p>Check this to call CQ on the &quot;Tx CQ&quot; frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on.</p><p>Not available to nonstandard callsign holders.</p></body></html> + + + Check this to call CQ on the "Tx CQ" frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on. +Not available to nonstandard callsign holders. + + + + + + + + + + Decode other Hounds calling above 1000 Hz audio offset + + + Rx All Freqs + + + + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Fox + + + Qt::AlignCenter + + + + + + + <html><head/><body><p>Check to monitor Sh messages.</p></body></html> + + + Check to monitor Sh messages. + + + SWL + + + + + + + Enable auto response to the first decode from a new DXCC or new call on the current band. + + + QPushButton:checked { + color: rgb(0, 0, 0); + background-color: red; + border-style: outset; + border-width: 1px; + border-radius: 5px; + border-color: black; + min-width: 5em; + padding: 3px; +} + + + Best S+P + + + true + + + + + + + <html><head/><body><p>Check this to start recording calibration data.<br/>While measuring calibration correction is disabled.<br/>When not checked you can view the calibration results.</p></body></html> + + + Check this to start recording calibration data. +While measuring calibration correction is disabled. +When not checked you can view the calibration results. + + + Measure + + + + + + + + + + + <html><head/><body><p>Check to use short-format messages.</p></body></html> + + + Check to use short-format messages. + + + Sh + + + + + + + <html><head/><body><p>Check to enable JT9 fast modes</p></body></html> + + + Check to enable JT9 fast modes + + + Fast + + + + + + + <html><head/><body><p>Check to enable automatic sequencing of Tx messages based on received messages.</p></body></html> + + + Check to enable automatic sequencing of Tx messages based on received messages. + + + Auto Seq + + + + + + + <html><head/><body><p>Select <span style=" font-weight:600;">CQ: First</span> to respond automatically to the first decoded reply to your CQ. </p><p>Select <span style=" font-weight:600;">CQ: Max Dist</span> to respond automatically to the reply yielding most points in the ARRL International Digital Contest.</p><p>Select <span style=" font-weight:600;">CQ: None</span> to choose callers manually.</p></body></html> + + + + + + -1 + + + 3 + + + + + + + false + + + Check to generate "@1250 (SEND MSGS)" in Tx6. + + + Tx6 + + + + + + + + + + + <html><head/><body><p>Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences.</p></body></html> + + + Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences. + + + Tx even/1st + + + + + + + Audio Tx frequency + + + Qt::AlignCenter + + + Hz + + + Tx + + + 200 + + + 5000 + + + 1500 + + + + + + + + + + 0 + 0 + + + + + 35 + 0 + + + + Set Tx frequency to Rx Frequency + + + Set Tx frequency to Rx Frequency + + + â–² + + + + + + + Frequency tolerance (Hz) + + + Qt::AlignCenter + + + F Tol + + + 1 + + + 1000 + + + 10 + + + + + + + + 0 + 0 + + + + + 35 + 0 + + + + Set Rx frequency to Tx Frequency + + + Set Rx frequency to Tx Frequency + + + â–¼ + + + + + + + + + Audio Rx frequency + + + Qt::AlignCenter + + + Hz + + + Rx + + + 200 + + + 5000 + + + 1500 + + + + + + + <html><head/><body><p>Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB).</p></body></html> + + + Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB). + + + Qt::AlignCenter + + + Report + + + -50 + + + 49 + + + -15 + + + + + + + <html><head/><body><p>Tx/Rx or Frequency calibration sequence length</p></body></html> + + + Tx/Rx or Frequency calibration sequence length + + + Qt::AlignCenter + + + s + + + T/R + + + 5 + + + 1800 + + + 30 + + + + + + + + + + + <html><head/><body><p>Check to keep Tx frequency fixed when double-clicking on decoded text.</p></body></html> + + + Check to keep Tx frequency fixed when double-clicking on decoded text. + + + Hold Tx Freq + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Tx# + + + 1 + + + 4095 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::AlignCenter + + + F Low + + + 100 + + + 5000 + + + 50 + + + 600 + + + + + + + Qt::AlignCenter + + + + + + F High + + + 100 + + + 5000 + + + 50 + + + 1400 + + + + + + + + + + + <html><head/><body><p>Submode determines tone spacing; A is narrowest.</p></body></html> + + + Submode determines tone spacing; A is narrowest. + + + Qt::AlignCenter + + + Submode + + + 0 + + + 7 + + + + + + + <html><head/><body><p>Synchronizing threshold. Lower numbers accept weaker sync signals.</p></body></html> + + + Synchronizing threshold. Lower numbers accept weaker sync signals. + + + Qt::AlignCenter + + + Sync + + + -1 + + + 10 + + + 1 + + + + + + + Maximum drift rate in units of symbol rate per transmission. + + + Max Drift + + + 50 + + + 5 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + QTabWidget::West + + + QTabWidget::Triangular + + + 1 + + + + 1 + + + + + + + + Send this message in next Tx interval + + + margin-left: 10%; margin-right: 0% + + + + + + Ctrl+6 + + + true + + + + + + + Queue up the next Tx message + + + Next + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + + Send this message in next Tx interval +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + + + margin-left: 10%; margin-right: 0% + + + + + + Ctrl+4 + + + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + + Send this message in next Tx interval +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + + + margin-left: 10%; margin-right: 0% + + + + + + Ctrl+1 + + + + + + + + 0 + 0 + + + + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to reset to the standard 73 message</p></body></html> + + + Switch to this Tx message NOW +Double-click to reset to the standard 73 message + + + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% + + + Tx &5 + + + Alt+5 + + + + + + + Switch to this Tx message NOW + + + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% + + + Tx &2 + + + Alt+2 + + + + + + + + 0 + 0 + + + + + + + + Switch to this Tx message NOW + + + Now + + + Qt::AlignCenter + + + + + + + Send this message in next Tx interval + + + margin-left: 10%; margin-right: 0% + + + + + + Ctrl+2 + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + Generate standard messages for minimal QSO + + + Generate Std Msgs + + + + + + + Switch to this Tx message NOW + + + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% + + + Tx &3 + + + Alt+3 + + + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + + Switch to this Tx message NOW +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + + + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% + + + Tx &4 + + + Alt+4 + + + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + + Switch to this Tx message NOW +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + + + Qt::LeftToRight + + + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% + + + Tx &1 + + + Alt+1 + + + + + + + Switch to this Tx message NOW + + + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% + + + Tx &6 + + + Alt+6 + + + + + + + Send this message in next Tx interval + + + margin-left: 10%; margin-right: 0% + + + + + + Ctrl+3 + + + + + + + Enter a free text message (maximum 13 characters) +or select a predefined macro from the dropdown list. +Press ENTER to add the current text to the predefined +list. The list can be maintained in Settings (F2). + + + true + + + QComboBox::InsertAtBottom + + + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to reset to the standard 73 message</p></body></html> + + + Send this message in next Tx interval +Double-click to reset to the standard 73 message + + + margin-left: 10%; margin-right: 0% + + + + + + Ctrl+5 + + + + + + + + + + 2 + + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Max dB + + + -15 + + + 70 + + + 30 + + + + + + + CQ + + + + CQ + + + + + CQ AF + + + + + CQ AN + + + + + CQ AS + + + + + CQ EU + + + + + CQ NA + + + + + CQ OC + + + + + CQ SA + + + + + CQ 0 + + + + + CQ 1 + + + + + CQ 2 + + + + + CQ 3 + + + + + CQ 4 + + + + + CQ 5 + + + + + CQ 6 + + + + + CQ 7 + + + + + CQ 8 + + + + + CQ 9 + + + + + + + + Reset + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + N List + + + 5 + + + 100 + + + 12 + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + N Slots + + + 1 + + + 5 + + + 1 + + + 10 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + More CQs + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Random + + + 5 + + + + Random + + + + + Call + + + + + Grid + + + + + S/N (dB) + + + + + Distance + + + + + + + + + + 0 + + + -1 + + + + + true + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + + + + + + + 13 + + + + Queue + + + Qt::AlignCenter + + + + + + + In-QSO + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Qt::AlignCenter + + + Hz + + + Tx + + + 1400 + + + 1600 + + + 1500 + + + + + + + Qt::AlignCenter + + + Hz + + + Rx + + + 100 + + + 4900 + + + 100 + + + 1500 + + + + + + + Qt::AlignCenter + + + Hz + + + F Tol + + + 100 + + + 500 + + + 100 + + + + + + + true + + + 0 + + + + Random + + + + + 1/2 + + + + + 2/2 + + + + + 1/3 + + + + + 2/3 + + + + + 3/3 + + + + + 1/4 + + + + + 2/4 + + + + + 3/4 + + + + + 4/4 + + + + + 1/5 + + + + + 2/5 + + + + + 3/5 + + + + + 4/5 + + + + + 5/5 + + + + + 1/6 + + + + + 2/6 + + + + + 3/6 + + + + + 4/6 + + + + + 5/6 + + + + + 6/6 + + + + + + + + Percentage of minute sequences devoted to transmitting. + + + QSpinBox:enabled[notx="true"] { + color: rgb(0, 0, 0); + background-color: rgb(255, 255, 0); +} + + + Qt::AlignCenter + + + % + + + Tx Pct + + + 100 + + + + + + + Qt::AlignCenter + + + s + + + T/R + + + 15 + + + 1800 + + + + + + + Band Hopping + + + true + + + + + + Choose bands and times of day for band-hopping. + + + Schedule ... + + + + + + + + + + + + + + + + + + Upload decoded messages to WSPRnet.org. + + + QCheckBox:unchecked { + color: rgb(0, 0, 0); + background-color: rgb(255, 255, 0); +} + + + Upload spots + + + + + + + + + <html><head/><body><p>6 digit locators cause 2 different messages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol.</p></body></html> + + + 6 digit locators cause 2 different messages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol. + + + Prefer Type 1 messages + + + true + + + + + + + No own call decodes + + + + + + + + + <html><head/><body><p>Transmit during the next sequence.</p></body></html> + + + QPushButton:checked { + color: rgb(0, 0, 0); + background-color: red; + border-style: outset; + border-width: 1px; + border-radius: 5px; + border-color: black; + min-width: 5em; + padding: 3px; +} + + + Tx Next + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Set Tx power in dBm (dB above 1 mW) as part of your WSPR message. + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + USB dial frequency + + + QLabel { + font-family: MS Shell Dlg 2; + font-size: 16pt; + color : yellow; + background-color : black; +} +QLabel[oob="true"] { + background-color: red; +} + + + 14.078 000 + + + Qt::AlignCenter + + + 5 + + + + + + + + + + 32 + 0 + + + + + 16777215 + 16777215 + + + + Toggle FT8 hound mode On/Off + + + H + + + true + + + + + + + + 32 + 0 + + + + + 16777215 + 16777215 + + + + Switch to FT8 mode + + + FT8 + + + + + + + + 32 + 0 + + + + + 16777215 + 16777215 + + + + Switch to FT4 mode + + + FT4 + + + + + + + + 32 + 0 + + + + + 16777215 + 16777215 + + + + Switch to MSK144 mode + + + MSK + + + + + + + + 32 + 0 + + + + + 16777215 + 16777215 + + + + Switch to Q65 mode + + + Q65 + + + + + + + + 32 + 0 + + + + + 16777215 + 16777215 + + + + Switch to JT65 mode + + + JT65 + + + + + + + + + + 0 + 0 + + + + QLabel { + font-family: MS Shell Dlg 2; + font-size: 16pt; + background-color : black; + color : yellow; +} + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 2 + + + 0 + + + <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> + + + Qt::AlignCenter + + + 5 + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> + + + Frequency entry + + + Select operating band or enter frequency in MHz or enter kHz increment followed by k. + + + true + + + QComboBox::NoInsert + + + QComboBox::AdjustToMinimumContentsLengthWithIcon + + + + + + + false + + + <html><head/><body><p>If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode.</p></body></html> + + + If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode. + + + QPushButton { + font-family: helvetica; + font-size: 9pt; + font-weight: bold; + background-color: white; + color: black; + border-style: solid; + border-width:1px; + border-radius:10px; + border-color: gray; + max-width:20px; + max-height:20px; + min-width:20px; + min-height:20px; +} +QPushButton[state="error"] { + background-color: red; +} +QPushButton[state="warning"] { + background-color: orange; +} +QPushButton[state="ok"] { + background-color: #00ff00; +} + + + ? + + + + + + + + + + + + + + + + 0 + 0 + 1114 + 37 + + + + + File + + + + + + + + + + + + + + + + + + + + + View + + + + + + + + + + + + + + + Decode + + + + + + + + + + + + + + + Save + + + + + + + + + + + + + Help + + + + + + + + + + + + + + + + + + + + + Mode + + + + + + + + + + + + + + + + + + + + + Configurations + + + + + Tools + + + + + + + + + + + + + + + + + + + + + + + Exit + + + QAction::QuitRole + + + + + About WSJT-X + + + QAction::AboutRole + + + + + Waterfall + + + + + Open + + + Ctrl+O + + + + + Open next in directory + + + + + Decode remaining files in directory + + + Shift+F6 + + + + + Delete all *.wav && *.c2 files in SaveDir + + + + + true + + + false + + + Fast + + + + + true + + + true + + + None + + + + + true + + + Save all + + + + + Online User Guide + + + + + Keyboard shortcuts + + + + + Special mouse commands + + + + + true + + + true + + + JT9 + + + + + true + + + true + + + Save decoded + + + + + true + + + false + + + Normal + + + + + true + + + true + + + Deep + + + + + Erase ALL.TXT + + + + + Erase wsjtx_log.adi + + + + + true + + + JT65 + + + + + true + + + Astronomical data + + + + + List of Type 1 prefixes and suffixes + + + + + Settings... + + + QAction::PreferencesRole + + + + + Local User Guide + + + + + Open log directory + + + + + true + + + JT4 + + + + + Message averaging + + + F7 + + + + + true + + + Enable averaging + + + + + true + + + Enable deep search + + + + + true + + + WSPR + + + + + Echo Graph + + + F8 + + + + + true + + + Echo + + + EME Echo mode + + + + + true + + + ISCAT + + + + + Fast Graph + + + F9 + + + + + &Download Samples ... + + + <html><head/><body><p>Download sample audio files demonstrating the various modes.</p></body></html> + + + + + true + + + MSK144 + + + + + true + + + QRA64 + + + + + Release Notes + + + + + true + + + Enable AP for DX Call + + + + + true + + + FreqCal + + + + + Measure reference spectrum + + + + + Measure phase response + + + + + Erase reference spectrum + + + + + true + + + Execute frequency calibration cycle + + + + + Equalization tools ... + + + + + true + + + true + + + FT8 + + + + + true + + + Enable AP + + + + + true + + + Enable AP + + + + + Solve for calibration parameters + + + + + Copyright notice + + + Shift+F1 + + + + + false + + + Fox log + + + + + FT8 DXpedition Mode User Guide + + + + + Reset Cabrillo log ... + + + + + Color highlighting scheme + + + + + Export Cabrillo log ... + + + + + Quick-Start Guide to FST4 and FST4W + + + + + Contest log + + + + + Erase WSPR hashtable + + + + + true + + + FT4 + + + + + true + + + FST4 + + + + + true + + + FST4W + + + + + true + + + Q65 + + + + + true + + + SWL Mode + + + Hide lower panel controls to maximize deocde windows + + + + + Quick-Start Guide to Q65 + + + + + true + + + Auto Clear Avg after decode + + + + + Quick-Start Guide to WSJT-X 2.5.0 and MAP65 3.0 + + + + + true + + + true + + + Don't split ALL.TXT + + + + + true + + + Split ALL.TXT yearly + + + + + true + + + Split ALL.TXT monthly + + + + + true + + + Disable writing of ALL.TXT + + + + + Active Stations + + + + + + + DisplayText + QTextBrowser +
widgets/displaytext.h
+
+ + LettersSpinBox + QSpinBox +
widgets/LettersSpinBox.hpp
+
+ + SignalMeter + QFrame +
widgets/signalmeter.h
+ 1 +
+ + HintedSpinBox + QSpinBox +
widgets/HintedSpinBox.hpp
+
+ + RestrictedSpinBox + QSpinBox +
widgets/RestrictedSpinBox.hpp
+
+ + DoubleClickableRadioButton + QRadioButton +
widgets/DoubleClickableRadioButton.hpp
+
+ + DoubleClickablePushButton + QPushButton +
widgets/DoubleClickablePushButton.hpp
+
+ + BandComboBox + QComboBox +
widgets/BandComboBox.hpp
+
+
+ + decodedTextBrowser + decodedTextBrowser2 + cbCQonly + logQSOButton + stopButton + monitorButton + EraseButton + ClrAvgButton + DecodeButton + autoButton + stopTxButton + tuneButton + cbMenus + sbNB + dxCallEntry + dxGridEntry + txFirstCheckBox + TxFreqSpinBox + pbR2T + sbFtol + pbT2R + RxFreqSpinBox + rptSpinBox + sbTR + cbHoldTxFreq + sbF_Low + sbF_High + sbSubmode + syncSpinBox + sbCQTxFreq + cbCQTx + cbRxAll + cbShMsgs + cbFast9 + cbAutoSeq + cbTx6 + cbSWL + pbBestSP + measure_check_box + tabWidget + genStdMsgsPushButton + tx1 + txrb1 + txb1 + tx2 + txrb2 + txb2 + tx3 + txrb3 + txb3 + tx4 + txrb4 + txb4 + tx5 + txrb5 + txb5 + tx6 + txrb6 + txb6 + comboBoxHoundSort + sbNlist + sbMax_dB + sbNslots + comboBoxCQ + cbMoreCQs + pbFoxReset + WSPRfreqSpinBox + sbFST4W_RxFreq + sbFST4W_FTol + RoundRobin + sbTxPercent + sbTR_FST4W + band_hopping_group_box + band_hopping_schedule_push_button + cbUploadWSPR_Spots + WSPR_prefer_type_1_check_box + cbNoOwnCall + pbTxNext + TxPowerComboBox + outAttenuation + sbSerialNumber + + + +
From 940b26e6ea5a9bb063dc36ef2494762c013d5fea Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Sun, 13 Nov 2022 09:49:43 +0100 Subject: [PATCH 09/20] Fix a compilation error with Qt 5.15.x. --- widgets/mainwindow.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 52b353112..1ec62e6ca 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -9816,8 +9816,13 @@ void MainWindow::foxTest() if(line_trimmed.startsWith("Hound:")) { t=line_trimmed.mid(6,-1).trimmed(); b_hounds_written = true; - //sdiag << t << Qt::endl; - houndstream << t << Qt::endl; + houndstream << t +#if QT_VERSION >= QT_VERSION_CHECK (5, 15, 0) + << Qt::endl +#else + << endl +#endif + ; } if(line.contains("Del:")) { From fcc10c1f699dab2cdd4aea7c4a050b1d0f3f6c1a Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Sun, 13 Nov 2022 16:38:56 +0100 Subject: [PATCH 10/20] Some GUI adjustments. --- widgets/mainwindow.ui | 262 +-- widgets/mainwindow.ui.autosave | 3921 -------------------------------- 2 files changed, 133 insertions(+), 4050 deletions(-) delete mode 100644 widgets/mainwindow.ui.autosave diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 0d027f31b..8a1a5138f 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 1015 - 665 + 991 + 690 @@ -1018,7 +1018,7 @@ Yellow when too low 0 - + 0 @@ -1454,7 +1454,7 @@ When not checked you can view the calibration results. - 0 + 1 @@ -1661,7 +1661,7 @@ When not checked you can view the calibration results. QTabWidget::Triangular - 1 + 0 @@ -2004,11 +2004,32 @@ Double-click to reset to the standard 73 message 2 - - - - - + + + 4 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + 0 + + + 6 + + + 0 @@ -2021,21 +2042,62 @@ Double-click to reset to the standard 73 message 16777215 - - Max dB + + Random - - -15 + + 5 - - 70 + + + Random + + + + + Call + + + + + Grid + + + + + S/N (dB) + + + + + Distance + + + + + + + + + 9 + - - 30 + + Queue + + + Qt::AlignCenter - + + + + More CQs + + + + CQ @@ -2132,14 +2194,7 @@ Double-click to reset to the standard 73 message - - - - Reset - - - - + @@ -2167,7 +2222,35 @@ Double-click to reset to the standard 73 message - + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Max dB + + + -15 + + + 70 + + + 30 + + + + @@ -2201,7 +2284,24 @@ Double-click to reset to the standard 73 message - + + + + Reset + + + + + + + In-QSO + + + Qt::AlignCenter + + + + Qt::Vertical @@ -2214,71 +2314,7 @@ Double-click to reset to the standard 73 message - - - - More CQs - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Random - - - 5 - - - - Random - - - - - Call - - - - - Grid - - - - - S/N (dB) - - - - - Distance - - - - - - - - - - 0 - - - -1 - - + true @@ -2300,7 +2336,7 @@ Double-click to reset to the standard 73 message - + @@ -2319,31 +2355,6 @@ Double-click to reset to the standard 73 message - - - - - 13 - - - - Queue - - - Qt::AlignCenter - - - - - - - In-QSO - - - Qt::AlignCenter - - - @@ -3133,8 +3144,8 @@ QPushButton[state="ok"] { 0 0 - 1015 - 37 + 991 + 22 @@ -3893,13 +3904,6 @@ QPushButton[state="ok"] { tx6 txrb6 txb6 - comboBoxHoundSort - sbNlist - sbMax_dB - sbNslots - comboBoxCQ - cbMoreCQs - pbFoxReset WSPRfreqSpinBox sbFST4W_RxFreq sbFST4W_FTol diff --git a/widgets/mainwindow.ui.autosave b/widgets/mainwindow.ui.autosave deleted file mode 100644 index a328548fb..000000000 --- a/widgets/mainwindow.ui.autosave +++ /dev/null @@ -1,3921 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1114 - 665 - - - - WSJT-X by K1JT - - - - - - - - - - Qt::Horizontal - - - - - - - - 500 - 16777215 - - - - - 10 - false - - - - Band Activity - - - Qt::AlignCenter - - - - - - - - 300 - 20 - - - - - 16777215 - 20 - - - - - - - - - 252 - 252 - 252 - - - - - - - 170 - 170 - 170 - - - - - - - - - 252 - 252 - 252 - - - - - - - 170 - 170 - 170 - - - - - - - - - 170 - 170 - 170 - - - - - - - 170 - 170 - 170 - - - - - - - - true - - - UTC dB DT Freq Dr - - - Qt::PlainText - - - 5 - - - - - - - QFrame::StyledPanel - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - 0 - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 10 - false - - - - Rx Frequency - - - Qt::AlignCenter - - - - - - - - 300 - 20 - - - - - 16777215 - 20 - - - - - - - - - 252 - 252 - 252 - - - - - - - 170 - 170 - 170 - - - - - - - - - 252 - 252 - 252 - - - - - - - 170 - 170 - 170 - - - - - - - - - 170 - 170 - 170 - - - - - - - 170 - 170 - 170 - - - - - - - - true - - - UTC dB DT Freq Dr - - - Qt::PlainText - - - 5 - - - - - - - true - - - Qt::ScrollBarAlwaysOn - - - 0 - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - CQ only - - - - - - - - 50 - 0 - - - - Enter this QSO in log - - - Log &QSO - - - - - - - - 50 - 0 - - - - Stop monitoring - - - &Stop - - - - - - - - 50 - 0 - - - - Toggle monitoring On/Off - - - QPushButton:checked { - color: #000000; - background-color: #00ff00; - border-style: outset; - border-width: 1px; - border-radius: 5px; - border-color: black; - min-width: 5em; - padding: 3px; -} - - - &Monitor - - - true - - - false - - - - - - - - 50 - 0 - - - - <html><head/><body><p>Erase right window. Double-click to erase both windows.</p></body></html> - - - Erase right window. Double-click to erase both windows. - - - &Erase - - - - - - - true - - - <html><head/><body><p>Clear the accumulating message average.</p></body></html> - - - Clear the accumulating message average. - - - Clear Avg - - - - - - - Avg - - - 1 - - - 100 - - - 10 - - - - - - - - 50 - 0 - - - - <html><head/><body><p>Decode most recent Rx period at QSO Frequency</p></body></html> - - - Decode most recent Rx period at QSO Frequency - - - QPushButton:checked { - color: rgb(0, 0, 0); - background-color: cyan; - border-style: outset; - border-width: 1px; - border-radius: 5px; - border-color: black; - min-width: 5em; - padding: 3px; -} - - - &Decode - - - true - - - - - - - - 50 - 0 - - - - <html><head/><body><p>Toggle Auto-Tx On/Off</p></body></html> - - - Toggle Auto-Tx On/Off - - - QPushButton:checked { - color: rgb(0, 0, 0); - background-color: red; - border-style: outset; - border-width: 1px; - border-radius: 5px; - border-color: black; - min-width: 5em; - padding: 3px; -} - - - E&nable Tx - - - true - - - - - - - - 50 - 0 - - - - Stop transmitting immediately - - - &Halt Tx - - - - - - - <html><head/><body><p>Toggle a pure Tx tone On/Off</p></body></html> - - - Toggle a pure Tx tone On/Off - - - QPushButton:checked { - color: rgb(0, 0, 0); - background-color: red; - border-style: outset; - border-width: 1px; - border-radius: 5px; - border-color: black; - min-width: 5em; - padding: 3px; -} - - - &Tune - - - true - - - - - - - Menus - - - true - - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 159 - 175 - 213 - - - - - - - 159 - 175 - 213 - - - - - - - - true - - - DX Call - - - Qt::AlignCenter - - - 5 - - - 2 - - - dxCallEntry - - - - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 252 - 252 - 252 - - - - - - - 159 - 175 - 213 - - - - - - - - - 159 - 175 - 213 - - - - - - - 159 - 175 - 213 - - - - - - - - true - - - DX Grid - - - Qt::AlignCenter - - - 5 - - - 2 - - - dxGridEntry - - - - - - - - 0 - 0 - - - - Callsign of station to be worked - - - 11 - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - Locator of station to be worked - - - ` - - - 6 - - - Qt::AlignCenter - - - - - - - - - Search for callsign in database - - - &Lookup - - - - - - - Add callsign and locator to database - - - Add - - - - - - - true - - - Az: 251 16553 km - - - Qt::AlignCenter - - - 4 - - - - - - - - - - - - Adjust Tx audio level - - - 450 - - - 0 - - - Qt::Vertical - - - true - - - true - - - QSlider::TicksBelow - - - 50 - - - - - - - Pwr - - - - - - - 6 - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Qt::AlignCenter - - - % - - - NB - - - -2 - - - 25 - - - - - - - 0 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> - - - Rx Signal - - - 30dB recommended when only noise present -Green when good -Red when clipping may occur -Yellow when too low - - - QFrame::Panel - - - QFrame::Sunken - - - - - - - Qt::Horizontal - - - - 0 - 20 - - - - - - - - - - - - - 0 - 0 - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - false - - - <html><head/><body><p>Frequency to call CQ on in kHz above the current MHz</p></body></html> - - - Frequency to call CQ on in kHz above the current MHz - - - Tx CQ - - - 1 - - - 999 - - - 260 - - - - - - - false - - - <html><head/><body><p>Check this to call CQ on the &quot;Tx CQ&quot; frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on.</p><p>Not available to nonstandard callsign holders.</p></body></html> - - - Check this to call CQ on the "Tx CQ" frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on. -Not available to nonstandard callsign holders. - - - - - - - - - - Decode other Hounds calling above 1000 Hz audio offset - - - Rx All Freqs - - - - - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Fox - - - Qt::AlignCenter - - - - - - - <html><head/><body><p>Check to monitor Sh messages.</p></body></html> - - - Check to monitor Sh messages. - - - SWL - - - - - - - Enable auto response to the first decode from a new DXCC or new call on the current band. - - - QPushButton:checked { - color: rgb(0, 0, 0); - background-color: red; - border-style: outset; - border-width: 1px; - border-radius: 5px; - border-color: black; - min-width: 5em; - padding: 3px; -} - - - Best S+P - - - true - - - - - - - <html><head/><body><p>Check this to start recording calibration data.<br/>While measuring calibration correction is disabled.<br/>When not checked you can view the calibration results.</p></body></html> - - - Check this to start recording calibration data. -While measuring calibration correction is disabled. -When not checked you can view the calibration results. - - - Measure - - - - - - - - - - - <html><head/><body><p>Check to use short-format messages.</p></body></html> - - - Check to use short-format messages. - - - Sh - - - - - - - <html><head/><body><p>Check to enable JT9 fast modes</p></body></html> - - - Check to enable JT9 fast modes - - - Fast - - - - - - - <html><head/><body><p>Check to enable automatic sequencing of Tx messages based on received messages.</p></body></html> - - - Check to enable automatic sequencing of Tx messages based on received messages. - - - Auto Seq - - - - - - - <html><head/><body><p>Select <span style=" font-weight:600;">CQ: First</span> to respond automatically to the first decoded reply to your CQ. </p><p>Select <span style=" font-weight:600;">CQ: Max Dist</span> to respond automatically to the reply yielding most points in the ARRL International Digital Contest.</p><p>Select <span style=" font-weight:600;">CQ: None</span> to choose callers manually.</p></body></html> - - - - - - -1 - - - 3 - - - - - - - false - - - Check to generate "@1250 (SEND MSGS)" in Tx6. - - - Tx6 - - - - - - - - - - - <html><head/><body><p>Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences.</p></body></html> - - - Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences. - - - Tx even/1st - - - - - - - Audio Tx frequency - - - Qt::AlignCenter - - - Hz - - - Tx - - - 200 - - - 5000 - - - 1500 - - - - - - - - - - 0 - 0 - - - - - 35 - 0 - - - - Set Tx frequency to Rx Frequency - - - Set Tx frequency to Rx Frequency - - - â–² - - - - - - - Frequency tolerance (Hz) - - - Qt::AlignCenter - - - F Tol - - - 1 - - - 1000 - - - 10 - - - - - - - - 0 - 0 - - - - - 35 - 0 - - - - Set Rx frequency to Tx Frequency - - - Set Rx frequency to Tx Frequency - - - â–¼ - - - - - - - - - Audio Rx frequency - - - Qt::AlignCenter - - - Hz - - - Rx - - - 200 - - - 5000 - - - 1500 - - - - - - - <html><head/><body><p>Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB).</p></body></html> - - - Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB). - - - Qt::AlignCenter - - - Report - - - -50 - - - 49 - - - -15 - - - - - - - <html><head/><body><p>Tx/Rx or Frequency calibration sequence length</p></body></html> - - - Tx/Rx or Frequency calibration sequence length - - - Qt::AlignCenter - - - s - - - T/R - - - 5 - - - 1800 - - - 30 - - - - - - - - - - - <html><head/><body><p>Check to keep Tx frequency fixed when double-clicking on decoded text.</p></body></html> - - - Check to keep Tx frequency fixed when double-clicking on decoded text. - - - Hold Tx Freq - - - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - Tx# - - - 1 - - - 4095 - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::AlignCenter - - - F Low - - - 100 - - - 5000 - - - 50 - - - 600 - - - - - - - Qt::AlignCenter - - - - - - F High - - - 100 - - - 5000 - - - 50 - - - 1400 - - - - - - - - - - - <html><head/><body><p>Submode determines tone spacing; A is narrowest.</p></body></html> - - - Submode determines tone spacing; A is narrowest. - - - Qt::AlignCenter - - - Submode - - - 0 - - - 7 - - - - - - - <html><head/><body><p>Synchronizing threshold. Lower numbers accept weaker sync signals.</p></body></html> - - - Synchronizing threshold. Lower numbers accept weaker sync signals. - - - Qt::AlignCenter - - - Sync - - - -1 - - - 10 - - - 1 - - - - - - - Maximum drift rate in units of symbol rate per transmission. - - - Max Drift - - - 50 - - - 5 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - QTabWidget::West - - - QTabWidget::Triangular - - - 1 - - - - 1 - - - - - - - - Send this message in next Tx interval - - - margin-left: 10%; margin-right: 0% - - - - - - Ctrl+6 - - - true - - - - - - - Queue up the next Tx message - - - Next - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - - - - <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> - - - Send this message in next Tx interval -Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders) -RR73 messages should only be used when you are reasonably confident that no message repetitions will be required - - - margin-left: 10%; margin-right: 0% - - - - - - Ctrl+4 - - - - - - - <html><head/><body><p>Send this message in next Tx interval</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> - - - Send this message in next Tx interval -Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) - - - margin-left: 10%; margin-right: 0% - - - - - - Ctrl+1 - - - - - - - - 0 - 0 - - - - - - - - <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to reset to the standard 73 message</p></body></html> - - - Switch to this Tx message NOW -Double-click to reset to the standard 73 message - - - padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% - - - Tx &5 - - - Alt+5 - - - - - - - Switch to this Tx message NOW - - - padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% - - - Tx &2 - - - Alt+2 - - - - - - - - 0 - 0 - - - - - - - - Switch to this Tx message NOW - - - Now - - - Qt::AlignCenter - - - - - - - Send this message in next Tx interval - - - margin-left: 10%; margin-right: 0% - - - - - - Ctrl+2 - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - - - - - Generate standard messages for minimal QSO - - - Generate Std Msgs - - - - - - - Switch to this Tx message NOW - - - padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% - - - Tx &3 - - - Alt+3 - - - - - - - <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> - - - Switch to this Tx message NOW -Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders) -RR73 messages should only be used when you are reasonably confident that no message repetitions will be required - - - padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% - - - Tx &4 - - - Alt+4 - - - - - - - <html><head/><body><p>Switch to this Tx message NOW</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> - - - Switch to this Tx message NOW -Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) - - - Qt::LeftToRight - - - padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% - - - Tx &1 - - - Alt+1 - - - - - - - Switch to this Tx message NOW - - - padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% - - - Tx &6 - - - Alt+6 - - - - - - - Send this message in next Tx interval - - - margin-left: 10%; margin-right: 0% - - - - - - Ctrl+3 - - - - - - - Enter a free text message (maximum 13 characters) -or select a predefined macro from the dropdown list. -Press ENTER to add the current text to the predefined -list. The list can be maintained in Settings (F2). - - - true - - - QComboBox::InsertAtBottom - - - - - - - <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to reset to the standard 73 message</p></body></html> - - - Send this message in next Tx interval -Double-click to reset to the standard 73 message - - - margin-left: 10%; margin-right: 0% - - - - - - Ctrl+5 - - - - - - - - - - 2 - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Max dB - - - -15 - - - 70 - - - 30 - - - - - - - CQ - - - - CQ - - - - - CQ AF - - - - - CQ AN - - - - - CQ AS - - - - - CQ EU - - - - - CQ NA - - - - - CQ OC - - - - - CQ SA - - - - - CQ 0 - - - - - CQ 1 - - - - - CQ 2 - - - - - CQ 3 - - - - - CQ 4 - - - - - CQ 5 - - - - - CQ 6 - - - - - CQ 7 - - - - - CQ 8 - - - - - CQ 9 - - - - - - - - Reset - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - N List - - - 5 - - - 100 - - - 12 - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - N Slots - - - 1 - - - 5 - - - 1 - - - 10 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - More CQs - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Random - - - 5 - - - - Random - - - - - Call - - - - - Grid - - - - - S/N (dB) - - - - - Distance - - - - - - - - - - 0 - - - -1 - - - - - true - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - QAbstractScrollArea::AdjustToContentsOnFirstShow - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - QAbstractScrollArea::AdjustToContentsOnFirstShow - - - - - - - - 13 - - - - Queue - - - Qt::AlignCenter - - - - - - - In-QSO - - - Qt::AlignCenter - - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::AlignCenter - - - Hz - - - Tx - - - 1400 - - - 1600 - - - 1500 - - - - - - - Qt::AlignCenter - - - Hz - - - Rx - - - 100 - - - 4900 - - - 100 - - - 1500 - - - - - - - Qt::AlignCenter - - - Hz - - - F Tol - - - 100 - - - 500 - - - 100 - - - - - - - true - - - 0 - - - - Random - - - - - 1/2 - - - - - 2/2 - - - - - 1/3 - - - - - 2/3 - - - - - 3/3 - - - - - 1/4 - - - - - 2/4 - - - - - 3/4 - - - - - 4/4 - - - - - 1/5 - - - - - 2/5 - - - - - 3/5 - - - - - 4/5 - - - - - 5/5 - - - - - 1/6 - - - - - 2/6 - - - - - 3/6 - - - - - 4/6 - - - - - 5/6 - - - - - 6/6 - - - - - - - - Percentage of minute sequences devoted to transmitting. - - - QSpinBox:enabled[notx="true"] { - color: rgb(0, 0, 0); - background-color: rgb(255, 255, 0); -} - - - Qt::AlignCenter - - - % - - - Tx Pct - - - 100 - - - - - - - Qt::AlignCenter - - - s - - - T/R - - - 15 - - - 1800 - - - - - - - Band Hopping - - - true - - - - - - Choose bands and times of day for band-hopping. - - - Schedule ... - - - - - - - - - - - - - - - - - - Upload decoded messages to WSPRnet.org. - - - QCheckBox:unchecked { - color: rgb(0, 0, 0); - background-color: rgb(255, 255, 0); -} - - - Upload spots - - - - - - - - - <html><head/><body><p>6 digit locators cause 2 different messages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol.</p></body></html> - - - 6 digit locators cause 2 different messages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol. - - - Prefer Type 1 messages - - - true - - - - - - - No own call decodes - - - - - - - - - <html><head/><body><p>Transmit during the next sequence.</p></body></html> - - - QPushButton:checked { - color: rgb(0, 0, 0); - background-color: red; - border-style: outset; - border-width: 1px; - border-radius: 5px; - border-color: black; - min-width: 5em; - padding: 3px; -} - - - Tx Next - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Set Tx power in dBm (dB above 1 mW) as part of your WSPR message. - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - USB dial frequency - - - QLabel { - font-family: MS Shell Dlg 2; - font-size: 16pt; - color : yellow; - background-color : black; -} -QLabel[oob="true"] { - background-color: red; -} - - - 14.078 000 - - - Qt::AlignCenter - - - 5 - - - - - - - - - - 32 - 0 - - - - - 16777215 - 16777215 - - - - Toggle FT8 hound mode On/Off - - - H - - - true - - - - - - - - 32 - 0 - - - - - 16777215 - 16777215 - - - - Switch to FT8 mode - - - FT8 - - - - - - - - 32 - 0 - - - - - 16777215 - 16777215 - - - - Switch to FT4 mode - - - FT4 - - - - - - - - 32 - 0 - - - - - 16777215 - 16777215 - - - - Switch to MSK144 mode - - - MSK - - - - - - - - 32 - 0 - - - - - 16777215 - 16777215 - - - - Switch to Q65 mode - - - Q65 - - - - - - - - 32 - 0 - - - - - 16777215 - 16777215 - - - - Switch to JT65 mode - - - JT65 - - - - - - - - - - 0 - 0 - - - - QLabel { - font-family: MS Shell Dlg 2; - font-size: 16pt; - background-color : black; - color : yellow; -} - - - QFrame::StyledPanel - - - QFrame::Sunken - - - 2 - - - 0 - - - <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> - - - Qt::AlignCenter - - - 5 - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> - - - Frequency entry - - - Select operating band or enter frequency in MHz or enter kHz increment followed by k. - - - true - - - QComboBox::NoInsert - - - QComboBox::AdjustToMinimumContentsLengthWithIcon - - - - - - - false - - - <html><head/><body><p>If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode.</p></body></html> - - - If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode. - - - QPushButton { - font-family: helvetica; - font-size: 9pt; - font-weight: bold; - background-color: white; - color: black; - border-style: solid; - border-width:1px; - border-radius:10px; - border-color: gray; - max-width:20px; - max-height:20px; - min-width:20px; - min-height:20px; -} -QPushButton[state="error"] { - background-color: red; -} -QPushButton[state="warning"] { - background-color: orange; -} -QPushButton[state="ok"] { - background-color: #00ff00; -} - - - ? - - - - - - - - - - - - - - - - 0 - 0 - 1114 - 37 - - - - - File - - - - - - - - - - - - - - - - - - - - - View - - - - - - - - - - - - - - - Decode - - - - - - - - - - - - - - - Save - - - - - - - - - - - - - Help - - - - - - - - - - - - - - - - - - - - - Mode - - - - - - - - - - - - - - - - - - - - - Configurations - - - - - Tools - - - - - - - - - - - - - - - - - - - - - - - Exit - - - QAction::QuitRole - - - - - About WSJT-X - - - QAction::AboutRole - - - - - Waterfall - - - - - Open - - - Ctrl+O - - - - - Open next in directory - - - - - Decode remaining files in directory - - - Shift+F6 - - - - - Delete all *.wav && *.c2 files in SaveDir - - - - - true - - - false - - - Fast - - - - - true - - - true - - - None - - - - - true - - - Save all - - - - - Online User Guide - - - - - Keyboard shortcuts - - - - - Special mouse commands - - - - - true - - - true - - - JT9 - - - - - true - - - true - - - Save decoded - - - - - true - - - false - - - Normal - - - - - true - - - true - - - Deep - - - - - Erase ALL.TXT - - - - - Erase wsjtx_log.adi - - - - - true - - - JT65 - - - - - true - - - Astronomical data - - - - - List of Type 1 prefixes and suffixes - - - - - Settings... - - - QAction::PreferencesRole - - - - - Local User Guide - - - - - Open log directory - - - - - true - - - JT4 - - - - - Message averaging - - - F7 - - - - - true - - - Enable averaging - - - - - true - - - Enable deep search - - - - - true - - - WSPR - - - - - Echo Graph - - - F8 - - - - - true - - - Echo - - - EME Echo mode - - - - - true - - - ISCAT - - - - - Fast Graph - - - F9 - - - - - &Download Samples ... - - - <html><head/><body><p>Download sample audio files demonstrating the various modes.</p></body></html> - - - - - true - - - MSK144 - - - - - true - - - QRA64 - - - - - Release Notes - - - - - true - - - Enable AP for DX Call - - - - - true - - - FreqCal - - - - - Measure reference spectrum - - - - - Measure phase response - - - - - Erase reference spectrum - - - - - true - - - Execute frequency calibration cycle - - - - - Equalization tools ... - - - - - true - - - true - - - FT8 - - - - - true - - - Enable AP - - - - - true - - - Enable AP - - - - - Solve for calibration parameters - - - - - Copyright notice - - - Shift+F1 - - - - - false - - - Fox log - - - - - FT8 DXpedition Mode User Guide - - - - - Reset Cabrillo log ... - - - - - Color highlighting scheme - - - - - Export Cabrillo log ... - - - - - Quick-Start Guide to FST4 and FST4W - - - - - Contest log - - - - - Erase WSPR hashtable - - - - - true - - - FT4 - - - - - true - - - FST4 - - - - - true - - - FST4W - - - - - true - - - Q65 - - - - - true - - - SWL Mode - - - Hide lower panel controls to maximize deocde windows - - - - - Quick-Start Guide to Q65 - - - - - true - - - Auto Clear Avg after decode - - - - - Quick-Start Guide to WSJT-X 2.5.0 and MAP65 3.0 - - - - - true - - - true - - - Don't split ALL.TXT - - - - - true - - - Split ALL.TXT yearly - - - - - true - - - Split ALL.TXT monthly - - - - - true - - - Disable writing of ALL.TXT - - - - - Active Stations - - - - - - - DisplayText - QTextBrowser -
widgets/displaytext.h
-
- - LettersSpinBox - QSpinBox -
widgets/LettersSpinBox.hpp
-
- - SignalMeter - QFrame -
widgets/signalmeter.h
- 1 -
- - HintedSpinBox - QSpinBox -
widgets/HintedSpinBox.hpp
-
- - RestrictedSpinBox - QSpinBox -
widgets/RestrictedSpinBox.hpp
-
- - DoubleClickableRadioButton - QRadioButton -
widgets/DoubleClickableRadioButton.hpp
-
- - DoubleClickablePushButton - QPushButton -
widgets/DoubleClickablePushButton.hpp
-
- - BandComboBox - QComboBox -
widgets/BandComboBox.hpp
-
-
- - decodedTextBrowser - decodedTextBrowser2 - cbCQonly - logQSOButton - stopButton - monitorButton - EraseButton - ClrAvgButton - DecodeButton - autoButton - stopTxButton - tuneButton - cbMenus - sbNB - dxCallEntry - dxGridEntry - txFirstCheckBox - TxFreqSpinBox - pbR2T - sbFtol - pbT2R - RxFreqSpinBox - rptSpinBox - sbTR - cbHoldTxFreq - sbF_Low - sbF_High - sbSubmode - syncSpinBox - sbCQTxFreq - cbCQTx - cbRxAll - cbShMsgs - cbFast9 - cbAutoSeq - cbTx6 - cbSWL - pbBestSP - measure_check_box - tabWidget - genStdMsgsPushButton - tx1 - txrb1 - txb1 - tx2 - txrb2 - txb2 - tx3 - txrb3 - txb3 - tx4 - txrb4 - txb4 - tx5 - txrb5 - txb5 - tx6 - txrb6 - txb6 - comboBoxHoundSort - sbNlist - sbMax_dB - sbNslots - comboBoxCQ - cbMoreCQs - pbFoxReset - WSPRfreqSpinBox - sbFST4W_RxFreq - sbFST4W_FTol - RoundRobin - sbTxPercent - sbTR_FST4W - band_hopping_group_box - band_hopping_schedule_push_button - cbUploadWSPR_Spots - WSPR_prefer_type_1_check_box - cbNoOwnCall - pbTxNext - TxPowerComboBox - outAttenuation - sbSerialNumber - - - -
From bed89042988acf09af758d9ebe49e3fc7cdaa7e7 Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Wed, 16 Nov 2022 22:05:01 +0100 Subject: [PATCH 11/20] Ensure that also late a7 decodes from the previous band are suppressed. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 17acca44c..4ed7f7615 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -7484,7 +7484,7 @@ void MainWindow::band_changed (Frequency f) { // Don't allow a7 decodes during the first period because they can be leftovers from the previous band no_a7_decodes = true; - QTimer::singleShot ((int(1000.0*m_TRperiod)), [=] {no_a7_decodes = false;}); + QTimer::singleShot ((int(1500.0*m_TRperiod)), [=] {no_a7_decodes = false;}); // Set the attenuation value if options are checked if (m_config.pwrBandTxMemory() && !m_tune) { From a247bcae94201e271b851acb72f8fc16bd7f5cac Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Sat, 19 Nov 2022 07:20:17 -0800 Subject: [PATCH 12/20] change column title from In-QSO to In Progress --- widgets/mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index 8a1a5138f..07ea2fb0a 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2294,7 +2294,7 @@ Double-click to reset to the standard 73 message - In-QSO + In Progress Qt::AlignCenter From 11db3eb1f38761deb25dc67385441941a636204c Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Sat, 19 Nov 2022 20:04:52 +0100 Subject: [PATCH 13/20] Some more time to test RC5. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index dc91b9953..2135cfb39 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1049,7 +1049,7 @@ void MainWindow::not_GA_warning_message () MessageBox::critical_message (this, "This is a pre-release version of WSJT-X 2.6.0 made\n" "available for testing purposes. By design it will\n" - "be nonfunctional after Dec 31, 2022."); + "be nonfunctional after Mar 31, 2023."); auto now = QDateTime::currentDateTimeUtc (); if (now >= QDateTime {{2022, 12, 31}, {23, 59, 59, 999}, Qt::UTC}) { Q_EMIT finished (); From d380be4ab493bc8898243bec638da1a7a0f2e563 Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Sat, 19 Nov 2022 20:06:41 +0100 Subject: [PATCH 14/20] Some more time to test RC5, part2. --- widgets/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 2135cfb39..6d14852b5 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -1051,7 +1051,7 @@ void MainWindow::not_GA_warning_message () "available for testing purposes. By design it will\n" "be nonfunctional after Mar 31, 2023."); auto now = QDateTime::currentDateTimeUtc (); - if (now >= QDateTime {{2022, 12, 31}, {23, 59, 59, 999}, Qt::UTC}) { + if (now >= QDateTime {{2023, 03, 31}, {23, 59, 59, 999}, Qt::UTC}) { Q_EMIT finished (); } } From 94aec3766e4ca1565c7ed20a7ff9571ff083abdf Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Sun, 20 Nov 2022 10:21:59 +0100 Subject: [PATCH 15/20] Disable log warnings on dropped audio for now, as detection is not reliable enough. --- Audio/soundin.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Audio/soundin.cpp b/Audio/soundin.cpp index 81d323d54..ecab8e052 100644 --- a/Audio/soundin.cpp +++ b/Audio/soundin.cpp @@ -180,13 +180,15 @@ void SoundInput::reset (bool report_dropped_frames) if (cummulative_lost_usec_ != std::numeric_limits::min () && report_dropped_frames) { auto lost_usec = elapsed_usecs - m_stream->processedUSecs () - cummulative_lost_usec_; - if (std::abs (lost_usec) > 48000 / 5) - { - LOG_WARN ("Detected dropped audio source samples: " - << m_stream->format ().framesForDuration (lost_usec) - << " (" << std::setprecision (4) << lost_usec / 1.e6 << " S)"); - } - else if (std::abs (lost_usec) > 5 * 48000) + // disable log warnings on dropped audio for now, as detection is not reliable +// if (std::abs (lost_usec) > 48000 / 5) +// { +// LOG_WARN ("Detected dropped audio source samples: " +// << m_stream->format ().framesForDuration (lost_usec) +// << " (" << std::setprecision (4) << lost_usec / 1.e6 << " S)"); +// } +// else if (std::abs (lost_usec) > 5 * 48000) + if (std::abs (lost_usec) > 5 * 48000) { LOG_ERROR ("Detected excessive dropped audio source samples: " << m_stream->format ().framesForDuration (lost_usec) From b3f6d41f4be0dba5800ca23094b8ae5183cb1375 Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Sun, 20 Nov 2022 10:24:55 +0100 Subject: [PATCH 16/20] Fix a bug in Hound mode for decodes without a grid or 3rd part of the message. Patch by Mike W9MDB. --- widgets/mainwindow.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 6d14852b5..6910cbea8 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -3895,8 +3895,13 @@ void MainWindow::readFromStdout() //readFromStdout bool bProcessMsgNormally=ui->respondComboBox->currentText()=="CQ: First" or (ui->respondComboBox->currentText()=="CQ: Max Dist" and m_ActiveStationsWidget==NULL) or (m_ActiveStationsWidget!=NULL and !m_ActiveStationsWidget->isVisible()); - QString t=decodedtext.messageWords()[4]; - if(t.contains("R+") or t.contains("R-") or t=="R" or t=="RRR" or t=="RR73") bProcessMsgNormally=true; + if (decodedtext.messageWords().length() >= 2) { + QString t=decodedtext.messageWords()[2]; + if(t.contains("R+") or t.contains("R-") or t=="R" or t=="RRR" or t=="RR73") bProcessMsgNormally=true; + } + else { + bProcessMsgNormally=true; + } if(bProcessMsgNormally) { m_bDoubleClicked=true; m_bAutoReply = true; @@ -3907,6 +3912,9 @@ void MainWindow::readFromStdout() //readFromStdout QString deCall; QString deGrid; decodedtext.deCallAndGrid(/*out*/deCall,deGrid); + // if they dont' send their grid we'll use ours and assume dx=0 + if (deGrid.length() == 0) deGrid = m_config.my_grid(); + if(deGrid.contains(grid_regexp) or (deGrid.contains("+") or deGrid.contains("-"))) { int points=0; From e443cb27c60483305aaf911f3c76c3b76a265171 Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Mon, 21 Nov 2022 11:49:03 +0100 Subject: [PATCH 17/20] Preparations for v2.6.0-rc5. --- CMakeLists.txt | 2 +- NEWS | 97 ++++++++++++++++++++++++++++++++++++++++++++++- Release_Notes.txt | 97 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 193 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b07964a7c..c47d51eca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ set (wsjtx_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_ set (PROJECT_BUNDLE_NAME "WSJT-X") set (PROJECT_VENDOR "Joe Taylor, K1JT") set (PROJECT_CONTACT "Joe Taylor ") -set (PROJECT_COPYRIGHT "Copyright (C) 2001-2021 by Joe Taylor, K1JT") +set (PROJECT_COPYRIGHT "Copyright (C) 2001-2022 by Joe Taylor, K1JT") set (PROJECT_HOMEPAGE https://www.physics.princeton.edu/pulsar/K1JT/wsjtx.html) set (PROJECT_MANUAL wsjtx-main) set (PROJECT_MANUAL_DIRECTORY_URL https://www.physics.princeton.edu/pulsar/K1JT/wsjtx-doc/) diff --git a/NEWS b/NEWS index 9381bd0b2..9a32f1642 100644 --- a/NEWS +++ b/NEWS @@ -11,11 +11,106 @@ Copyright 2001 - 2022 by Joe Taylor, K1JT, and the WSJT Development Team + Release: WSJT-X 2.6.0-rc5 + November 29, 2022 + ------------------------- + +WSJT-X 2.6.0 Release Candidate 5 brings a number of improvements as +well as some bug fixes. + +In program WSJT-X: + + - Our FT8 decoder has been further improved, resulting in more decodes + especially on crowded bands, and in an improved sync + for early decodes. + + - The Working frequency table now offers the following options: + - Better handling of more than one frequency per band. + - Set your prefered frequencies, wsjt-x_improved always comes back + to these QRGs when changing band or mode. + - You can label your frequencies with discriptions (e.g. DXp AB0YXZ). + - Option to set Start and End Date/Time, so that the frequencies + automatically appear and disappear. Useful for contest or + DXpedition QRGs. + - Load a frequency table from a file to easily get all such data + implemented. + + - In Fox mode, there are now a few additional functions that allow + operators to react even better to different QSO situations: + - A new two-column table in Tab 2 provides a better overview of + the queue and of the callsigns in QSO. + - The operator can now change the order of QSOs in the queue so + that he can react if there is only a narrow time slot for a + particular QSO due to propagation. + - The Fox now responds for another two cycles to stations whose + report was not received, increasing the success rate for a QSO. + + - Correct a flaw in Hound mode that sometimes prevented QSOs with + non-standard calls. + + - Correct a flaw that prevented WSJT-X from always initializing + correctly when special operating activities were enabled. + + - Correct a flaw that caused wrong frequencies to be written to + ALL.TXT for Tx. + + - The GUI has been improved regarding some details. The controls now + scale better at different font sizes and on different operating + systems. + + - When in Hound mode and click the "H" button again, the frequency + is now kept. This gives the user the following two options to return + to normal FT8 mode: + - Click the "H" button again. Then you will stay on the QRG. + - Click the "FT8" button (or use the Settings menu). It brings + you back to the default FT8 QRG. + + - A7 decodes are now disabled when "Enable AP" is not checked, and + during the first period after a band change. + + - The network address of the UDP server is now checked for errors + before accepting it. + + - Some improvements to the DX Lab Suite Commander interface. + + - Correct some possible flaws that could cause segfault errors in + certain situations. + + - Warnings on dropped audio have been disabled for now, as detection + has turned out to be not reliable enough. + + - Correct a long-standing flaw which caused the "Transmit digital gain" + overlay toappear somewhere on the screen. + + - Highlight DX Call now also works when the other station is <...>. + + - Further improvements to Echo mode: + - Some improvements on the Echo-mode averaging. + - Single-echo SNR measurement has been added. + - On the Wide Graph, a total-power plot has been added. + - Don't allow decoding depth to be changed just because Echo mode + was entered. + - Adjust the UTC wrap-around problem to yield time difference + within +/- 12 hours. + - New MAP65 feature: read wsjtx.log to recognize EME contest dupes. + + - Some other minor corrections (tool tips, etc.). + +In program MAP65 (Windows only): + + - Update to version 3.0.1. + - A feature for measuring antenna pointing errors has been added. + - Writing an invalid datetime to map65_rx.log is now prevented. + - Correct a flaw in the definition of the variable nts_jt65. + - Use "Force center freq" also for data read from disk. + + Release: WSJT-X 2.6.0-rc4 September 8, 2022 ------------------------- -WSJT-X 2.6.0 Release Candidate 4 provides further improvements to Echo mode, a new File menu item, and several bug fixes. +WSJT-X 2.6.0 Release Candidate 4 provides further improvements to Echo +mode, a new File menu item, and several bug fixes. - New features and fixes for Echo mode - Created a new simulator echosim[.exe] diff --git a/Release_Notes.txt b/Release_Notes.txt index f18beaccd..a595f3776 100644 --- a/Release_Notes.txt +++ b/Release_Notes.txt @@ -11,11 +11,106 @@ Copyright 2001 - 2022 by Joe Taylor, K1JT, and the WSJT Development Team + Release: WSJT-X 2.6.0-rc5 + November 29, 2022 + ------------------------- + +WSJT-X 2.6.0 Release Candidate 5 brings a number of improvements as +well as some bug fixes. + +In program WSJT-X: + + - Our FT8 decoder has been further improved, resulting in more decodes + especially on crowded bands, and in an improved sync + for early decodes. + + - The Working frequency table now offers the following options: + - Better handling of more than one frequency per band. + - Set your prefered frequencies, wsjt-x_improved always comes back + to these QRGs when changing band or mode. + - You can label your frequencies with discriptions (e.g. DXp AB0YXZ). + - Option to set Start and End Date/Time, so that the frequencies + automatically appear and disappear. Useful for contest or + DXpedition QRGs. + - Load a frequency table from a file to easily get all such data + implemented. + + - In Fox mode, there are now a few additional functions that allow + operators to react even better to different QSO situations: + - A new two-column table in Tab 2 provides a better overview of + the queue and of the callsigns in QSO. + - The operator can now change the order of QSOs in the queue so + that he can react if there is only a narrow time slot for a + particular QSO due to propagation. + - The Fox now responds for another two cycles to stations whose + report was not received, increasing the success rate for a QSO. + + - Correct a flaw in Hound mode that sometimes prevented QSOs with + non-standard calls. + + - Correct a flaw that prevented WSJT-X from always initializing + correctly when special operating activities were enabled. + + - Correct a flaw that caused wrong frequencies to be written to + ALL.TXT for Tx. + + - The GUI has been improved regarding some details. The controls now + scale better at different font sizes and on different operating + systems. + + - When in Hound mode and click the "H" button again, the frequency + is now kept. This gives the user the following two options to return + to normal FT8 mode: + - Click the "H" button again. Then you will stay on the QRG. + - Click the "FT8" button (or use the Settings menu). It brings + you back to the default FT8 QRG. + + - A7 decodes are now disabled when "Enable AP" is not checked, and + during the first period after a band change. + + - The network address of the UDP server is now checked for errors + before accepting it. + + - Some improvements to the DX Lab Suite Commander interface. + + - Correct some possible flaws that could cause segfault errors in + certain situations. + + - Warnings on dropped audio have been disabled for now, as detection + has turned out to be not reliable enough. + + - Correct a long-standing flaw which caused the "Transmit digital gain" + overlay toappear somewhere on the screen. + + - Highlight DX Call now also works when the other station is <...>. + + - Further improvements to Echo mode: + - Some improvements on the Echo-mode averaging. + - Single-echo SNR measurement has been added. + - On the Wide Graph, a total-power plot has been added. + - Don't allow decoding depth to be changed just because Echo mode + was entered. + - Adjust the UTC wrap-around problem to yield time difference + within +/- 12 hours. + - New MAP65 feature: read wsjtx.log to recognize EME contest dupes. + + - Some other minor corrections (tool tips, etc.). + +In program MAP65 (Windows only): + + - Update to version 3.0.1. + - A feature for measuring antenna pointing errors has been added. + - Writing an invalid datetime to map65_rx.log is now prevented. + - Correct a flaw in the definition of the variable nts_jt65. + - Use "Force center freq" also for data read from disk. + + Release: WSJT-X 2.6.0-rc4 September 8, 2022 ------------------------- -WSJT-X 2.6.0 Release Candidate 4 provides further improvements to Echo mode, a new File menu item, and several bug fixes. +WSJT-X 2.6.0 Release Candidate 4 provides further improvements to Echo +mode, a new File menu item, and several bug fixes. - New features and fixes for Echo mode - Created a new simulator echosim[.exe] From 119c838629f91f6d8f2c5537d160cdde9c80a198 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Mon, 21 Nov 2022 07:18:56 -0600 Subject: [PATCH 18/20] Edits to Release Notes. --- Release_Notes.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Release_Notes.txt b/Release_Notes.txt index a595f3776..21b8ab799 100644 --- a/Release_Notes.txt +++ b/Release_Notes.txt @@ -20,9 +20,9 @@ well as some bug fixes. In program WSJT-X: - - Our FT8 decoder has been further improved, resulting in more decodes - especially on crowded bands, and in an improved sync - for early decodes. + - Better calibration for FST4/W SNR estimates. + + - Improved FT8 decoding on crowded bands. - The Working frequency table now offers the following options: - Better handling of more than one frequency per band. From d37e887eb9b61c5427d5aa0271ab181ff02aca81 Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Mon, 21 Nov 2022 14:39:19 +0100 Subject: [PATCH 19/20] Some more edits to Release Notes and NEWS. --- NEWS | 12 +++++++----- Release_Notes.txt | 6 ++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 9a32f1642..b6d3bc5d7 100644 --- a/NEWS +++ b/NEWS @@ -20,14 +20,14 @@ well as some bug fixes. In program WSJT-X: - - Our FT8 decoder has been further improved, resulting in more decodes - especially on crowded bands, and in an improved sync - for early decodes. + - Better calibration for FST4/W SNR estimates. + + - Improved FT8 decoding on crowded bands. - The Working frequency table now offers the following options: - Better handling of more than one frequency per band. - - Set your prefered frequencies, wsjt-x_improved always comes back - to these QRGs when changing band or mode. + - Set your prefered frequencies, WSJT-X always comes back to these + QRGs when changing band or mode. - You can label your frequencies with discriptions (e.g. DXp AB0YXZ). - Option to set Start and End Date/Time, so that the frequencies automatically appear and disappear. Useful for contest or @@ -84,6 +84,8 @@ In program WSJT-X: - Highlight DX Call now also works when the other station is <...>. + - CQ messages without a grid are now sent to PSK reporter. + - Further improvements to Echo mode: - Some improvements on the Echo-mode averaging. - Single-echo SNR measurement has been added. diff --git a/Release_Notes.txt b/Release_Notes.txt index 21b8ab799..fcb2f450d 100644 --- a/Release_Notes.txt +++ b/Release_Notes.txt @@ -26,8 +26,8 @@ In program WSJT-X: - The Working frequency table now offers the following options: - Better handling of more than one frequency per band. - - Set your prefered frequencies, wsjt-x_improved always comes back - to these QRGs when changing band or mode. + - Set your prefered frequencies, WSJT-X always comes back to these + QRGs when changing band or mode. - You can label your frequencies with discriptions (e.g. DXp AB0YXZ). - Option to set Start and End Date/Time, so that the frequencies automatically appear and disappear. Useful for contest or @@ -84,6 +84,8 @@ In program WSJT-X: - Highlight DX Call now also works when the other station is <...>. + - CQ messages without a grid are now sent to PSK reporter. + - Further improvements to Echo mode: - Some improvements on the Echo-mode averaging. - Single-echo SNR measurement has been added. From fb01223768b6574210938ad3fdf87cb2e69ae383 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Mon, 21 Nov 2022 11:02:26 -0500 Subject: [PATCH 20/20] Final (?) edits to Release Notes in advance of the 2.6.0-rc5 release. --- NEWS | 65 ++++++++++++++++++++++------------------------- Release_Notes.txt | 65 ++++++++++++++++++++++------------------------- 2 files changed, 60 insertions(+), 70 deletions(-) diff --git a/NEWS b/NEWS index b6d3bc5d7..9d428ff57 100644 --- a/NEWS +++ b/NEWS @@ -26,7 +26,7 @@ In program WSJT-X: - The Working frequency table now offers the following options: - Better handling of more than one frequency per band. - - Set your prefered frequencies, WSJT-X always comes back to these + - Set your preferred frequencies, WSJT-X always comes back to these QRGs when changing band or mode. - You can label your frequencies with discriptions (e.g. DXp AB0YXZ). - Option to set Start and End Date/Time, so that the frequencies @@ -38,21 +38,29 @@ In program WSJT-X: - In Fox mode, there are now a few additional functions that allow operators to react even better to different QSO situations: - A new two-column table in Tab 2 provides a better overview of - the queue and of the callsigns in QSO. - - The operator can now change the order of QSOs in the queue so - that he can react if there is only a narrow time slot for a - particular QSO due to propagation. - - The Fox now responds for another two cycles to stations whose - report was not received, increasing the success rate for a QSO. + the queue and of the callsigns with QSOs in progress. + - Fox operator can now change the ordering of callsigns in the + queue so that he can react if there is only a narrow time slot + for a particular QSO due to propagation. + - Fox now responds for another two cycles to stations whose + report was not received, increasing the success rate for a + difficult QSO. - - Correct a flaw in Hound mode that sometimes prevented QSOs with - non-standard calls. + - Correct a flaw in Hound mode that sometimes prevented completion of + QSOs with non-standard calls. + + - Improvements to EME Echo mode: + - New control "Avg" sets the number of Echo cycles to be averaged. + - New capability to display measurements of wideband noise power as + a function of time. This can be useful for measuring Sun noise, + antenna tracking errors, and the like. + - Several minor bug fixes - Correct a flaw that prevented WSJT-X from always initializing correctly when special operating activities were enabled. - - Correct a flaw that caused wrong frequencies to be written to - ALL.TXT for Tx. + - Correct a flaw that caused wrong Tx frequencies to be written to + ALL.TXT. - The GUI has been improved regarding some details. The controls now scale better at different font sizes and on different operating @@ -65,16 +73,16 @@ In program WSJT-X: - Click the "FT8" button (or use the Settings menu). It brings you back to the default FT8 QRG. - - A7 decodes are now disabled when "Enable AP" is not checked, and - during the first period after a band change. + - Decodes flagged as 'a7' are now disabled when "Enable AP" is not + checked, and during the first period after a band change. - The network address of the UDP server is now checked for errors - before accepting it. + before being accepted. - Some improvements to the DX Lab Suite Commander interface. - Correct some possible flaws that could cause segfault errors in - certain situations. + certain unusual situations. - Warnings on dropped audio have been disabled for now, as detection has turned out to be not reliable enough. @@ -82,30 +90,17 @@ In program WSJT-X: - Correct a long-standing flaw which caused the "Transmit digital gain" overlay toappear somewhere on the screen. - - Highlight DX Call now also works when the other station is <...>. + - "Highlight DX Call" now also works when the other station is <...>. - CQ messages without a grid are now sent to PSK reporter. - - Further improvements to Echo mode: - - Some improvements on the Echo-mode averaging. - - Single-echo SNR measurement has been added. - - On the Wide Graph, a total-power plot has been added. - - Don't allow decoding depth to be changed just because Echo mode - was entered. - - Adjust the UTC wrap-around problem to yield time difference - within +/- 12 hours. - - New MAP65 feature: read wsjtx.log to recognize EME contest dupes. - - - Some other minor corrections (tool tips, etc.). - -In program MAP65 (Windows only): - - - Update to version 3.0.1. - - A feature for measuring antenna pointing errors has been added. - - Writing an invalid datetime to map65_rx.log is now prevented. - - Correct a flaw in the definition of the variable nts_jt65. - - Use "Force center freq" also for data read from disk. + - Several other minor corrections (tool tips, etc.). +Program MAP65 (Windows only) includes several minor bug fixes and two +tentative new features: + - an aid for measuring antenna pointing errors + - an ability to read the file wsjtx.log (kept by WSJT-X) to recognize + EME contest dupes. Release: WSJT-X 2.6.0-rc4 September 8, 2022 diff --git a/Release_Notes.txt b/Release_Notes.txt index fcb2f450d..bfcbf0d76 100644 --- a/Release_Notes.txt +++ b/Release_Notes.txt @@ -26,7 +26,7 @@ In program WSJT-X: - The Working frequency table now offers the following options: - Better handling of more than one frequency per band. - - Set your prefered frequencies, WSJT-X always comes back to these + - Set your preferred frequencies, WSJT-X always comes back to these QRGs when changing band or mode. - You can label your frequencies with discriptions (e.g. DXp AB0YXZ). - Option to set Start and End Date/Time, so that the frequencies @@ -38,21 +38,29 @@ In program WSJT-X: - In Fox mode, there are now a few additional functions that allow operators to react even better to different QSO situations: - A new two-column table in Tab 2 provides a better overview of - the queue and of the callsigns in QSO. - - The operator can now change the order of QSOs in the queue so - that he can react if there is only a narrow time slot for a - particular QSO due to propagation. - - The Fox now responds for another two cycles to stations whose - report was not received, increasing the success rate for a QSO. + the queue and of the callsigns with QSOs in progress. + - Fox operator can now change the ordering of callsigns in the + queue so that he can react if there is only a narrow time slot + for a particular QSO due to propagation. + - Fox now responds for another two cycles to stations whose + report was not received, increasing the success rate for a + difficult QSO. - - Correct a flaw in Hound mode that sometimes prevented QSOs with - non-standard calls. + - Correct a flaw in Hound mode that sometimes prevented completion of + QSOs with non-standard calls. + + - Improvements to EME Echo mode: + - New control "Avg" sets the number of Echo cycles to be averaged. + - New capability to display measurements of wideband noise power as + a function of time. This can be useful for measuring Sun noise, + antenna tracking errors, and the like. + - Several minor bug fixes - Correct a flaw that prevented WSJT-X from always initializing correctly when special operating activities were enabled. - - Correct a flaw that caused wrong frequencies to be written to - ALL.TXT for Tx. + - Correct a flaw that caused wrong Tx frequencies to be written to + ALL.TXT. - The GUI has been improved regarding some details. The controls now scale better at different font sizes and on different operating @@ -65,16 +73,16 @@ In program WSJT-X: - Click the "FT8" button (or use the Settings menu). It brings you back to the default FT8 QRG. - - A7 decodes are now disabled when "Enable AP" is not checked, and - during the first period after a band change. + - Decodes flagged as 'a7' are now disabled when "Enable AP" is not + checked, and during the first period after a band change. - The network address of the UDP server is now checked for errors - before accepting it. + before being accepted. - Some improvements to the DX Lab Suite Commander interface. - Correct some possible flaws that could cause segfault errors in - certain situations. + certain unusual situations. - Warnings on dropped audio have been disabled for now, as detection has turned out to be not reliable enough. @@ -82,30 +90,17 @@ In program WSJT-X: - Correct a long-standing flaw which caused the "Transmit digital gain" overlay toappear somewhere on the screen. - - Highlight DX Call now also works when the other station is <...>. + - "Highlight DX Call" now also works when the other station is <...>. - CQ messages without a grid are now sent to PSK reporter. - - Further improvements to Echo mode: - - Some improvements on the Echo-mode averaging. - - Single-echo SNR measurement has been added. - - On the Wide Graph, a total-power plot has been added. - - Don't allow decoding depth to be changed just because Echo mode - was entered. - - Adjust the UTC wrap-around problem to yield time difference - within +/- 12 hours. - - New MAP65 feature: read wsjtx.log to recognize EME contest dupes. - - - Some other minor corrections (tool tips, etc.). - -In program MAP65 (Windows only): - - - Update to version 3.0.1. - - A feature for measuring antenna pointing errors has been added. - - Writing an invalid datetime to map65_rx.log is now prevented. - - Correct a flaw in the definition of the variable nts_jt65. - - Use "Force center freq" also for data read from disk. + - Several other minor corrections (tool tips, etc.). +Program MAP65 (Windows only) includes several minor bug fixes and two +tentative new features: + - an aid for measuring antenna pointing errors + - an ability to read the file wsjtx.log (kept by WSJT-X) to recognize + EME contest dupes. Release: WSJT-X 2.6.0-rc4 September 8, 2022