From 9520eb130924ad4f2959d0ee8461798d70d0b30f Mon Sep 17 00:00:00 2001 From: Brian Moran Date: Wed, 28 Sep 2022 08:07:12 -0700 Subject: [PATCH 01/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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 9d28082cc12083af0f120cd93feccdba8375828c Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Wed, 16 Nov 2022 10:57:07 -0600 Subject: [PATCH 08/10] FST4/W: Improve calibration for SNR estimates. --- lib/fst4_decode.f90 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/fst4_decode.f90 b/lib/fst4_decode.f90 index 38e8a15bb..5d9ccc827 100644 --- a/lib/fst4_decode.f90 +++ b/lib/fst4_decode.f90 @@ -586,13 +586,26 @@ contains xsig=xsig+s4(itone(i),i) enddo base=candidates(icand,5) - arg=600.0*(xsig/base)-1.0 + select case(ntrperiod) + case(15) + snr_calfac=800.0 + case(30) + snr_calfac=600.0 + case(60) + snr_calfac=430.0 + case(120) + snr_calfac=390.0 + case(300) + snr_calfac=340.0 + case(900) + snr_calfac=320.0 + case(1800) + snr_calfac=320.0 + case default + end select + arg=snr_calfac*xsig/base - 1.0 if(arg.gt.0.0) then - xsnr=10*log10(arg)-35.5-12.5*log10(nsps/8200.0) - if(ntrperiod.eq. 15) xsnr=xsnr+2 - if(ntrperiod.eq. 30) xsnr=xsnr+1 - if(ntrperiod.eq. 900) xsnr=xsnr+1 - if(ntrperiod.eq.1800) xsnr=xsnr+2 + xsnr=10*log10(arg)+10*log10(1.46/2500)+10*log10(8200.0/nsps) else xsnr=-99.9 endif From bb756db817782e4d1fbc729503dc7e8ee00dd458 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 16 Nov 2022 15:11:57 -0500 Subject: [PATCH 09/10] Report the total number of map65 decodes, and display in status bar. --- map65/libm65/decode0.f90 | 5 +++-- map65/libm65/map65a.f90 | 4 ++++ map65/libm65/q65b.f90 | 2 ++ map65/mainwindow.cpp | 2 ++ map65/mainwindow.h | 1 - 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/map65/libm65/decode0.f90 b/map65/libm65/decode0.f90 index 7401c509a..ba167cddf 100644 --- a/map65/libm65/decode0.f90 +++ b/map65/libm65/decode0.f90 @@ -14,6 +14,7 @@ subroutine decode0(dd,ss,savg,nstandalone) mcall3,nkeep,ntol,nxant,nrxlog,nfsample,nxpol,nmode, & nfast,nsave,max_drift,nhsym,mycall,mygrid,hiscall,hisgrid,datetime common/early/nhsym1,nhsym2,ldecoded(32768) + common/decodes/ndecodes data neme0/-99/,mcall3b/1/ save @@ -62,8 +63,8 @@ subroutine decode0(dd,ss,savg,nstandalone) call sec0(1,tdec) if(nhsym.eq.nhsym1) write(*,1010) nsum,nsave,nstandalone,nhsym,tdec 1010 format('',3i4,i6,f6.2) - if(nhsym.eq.nhsym2) write(*,1012) nsum,nsave,nstandalone,nhsym,tdec -1012 format('',3i4,i6,f6.2) + if(nhsym.eq.nhsym2) write(*,1012) nsum,nsave,nstandalone,nhsym,tdec,ndecodes +1012 format('',3i4,i6,f6.2,i5) flush(6) return diff --git a/map65/libm65/map65a.f90 b/map65/libm65/map65a.f90 index 25eae0aef..87afa48cd 100644 --- a/map65/libm65/map65a.f90 +++ b/map65/libm65/map65a.f90 @@ -34,12 +34,15 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, & common/c3com/ mcall3a common/testcom/ifreq common/early/nhsym1,nhsym2,ldecoded(32768) + common/decodes/ndecodes data blank/' '/,cm/'#'/ data shmsg0/'ATT','RO ','RRR','73 '/ data nfile/0/,nutc0/-999/,nid/0/,ip000/1/,ip001/1/,mousefqso0/-999/ save + ndecodes=0 + ! Clean start for Q65 at early decode if(nhsym.eq.nhsym1 .or. nagain.ne.0) ldecoded=.false. if(ndiskdat.eq.1) ldecoded=.false. @@ -499,6 +502,7 @@ subroutine map65a(dd,ss,savg,newdat,nutc,fcenter,ntol,idphi,nfa,nfb, & write(26,1014) f0,ndf,ndf0,ndf1,ndf2,dt,npol,nsync1, & nsync2,nutc,decoded,cp,cmode 1014 format(f8.3,i5,3i3,f5.1,i4,i3,i4,i5.4,4x,a22,2x,a1,3x,a2) + ndecodes=ndecodes+1 write(21,1100) f0,ndf,dt,npol,nsync2,nutc,decoded,cp, & cmode(1:1),cmode(2:2) 1100 format(f8.3,i5,f5.1,2i4,i5.4,2x,a22,2x,a1,3x,a1,1x,a1) diff --git a/map65/libm65/q65b.f90 b/map65/libm65/q65b.f90 index 3366694d5..92be6528a 100644 --- a/map65/libm65/q65b.f90 +++ b/map65/libm65/q65b.f90 @@ -35,6 +35,7 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, & character*1 cp,cmode*2 common/cacb/ca,cb common/early/nhsym1,nhsym2,ldecoded(32768) + common/decodes/ndecodes data nutc00/-1/,msg00/' '/ save @@ -179,6 +180,7 @@ subroutine q65b(nutc,nqd,nxant,fcenter,nfcal,nfsample,ikhz,mousedf,ntol,xpol, & ! to map65_rx.log if(nutc.ne.nutc00 .or. msg0(1:28).ne.msg00 .or. freq1.ne.freq1_00) then ! Write to file map65_rx.log: + ndecodes=ndecodes+1 write(21,1110) freq1,ndf,xdt0,npol,nsnr0,nutc,msg0(1:28),cq0 1110 format(f8.3,i5,f5.1,2i4,i5.4,2x,a28,': A',2x,a3) nutc00=nutc diff --git a/map65/mainwindow.cpp b/map65/mainwindow.cpp index 99dd59527..4ab500f65 100644 --- a/map65/mainwindow.cpp +++ b/map65/mainwindow.cpp @@ -1416,6 +1416,8 @@ void MainWindow::readFromStdout() //readFromStdout QFile lockFile(m_appDir + "/.lock"); lockFile.open(QIODevice::ReadWrite); if(t.indexOf("") >= 0) { + int ndecodes=t.mid(40,5).toInt(); + lab5->setText(QString::number(ndecodes)); m_map65RxLog=0; m_startAnother=m_loopall; } diff --git a/map65/mainwindow.h b/map65/mainwindow.h index bbf3e707c..ebee97403 100644 --- a/map65/mainwindow.h +++ b/map65/mainwindow.h @@ -194,7 +194,6 @@ private: qint32 m_RxState; qint32 m_dB; - double m_fAdd; // double m_IQamp; // double m_IQphase; From bed89042988acf09af758d9ebe49e3fc7cdaa7e7 Mon Sep 17 00:00:00 2001 From: Uwe Risse Date: Wed, 16 Nov 2022 22:05:01 +0100 Subject: [PATCH 10/10] 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) {