From c1a3f9220c6da00cd4ddbe327f262e0e95b68764 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Wed, 31 Jul 2024 09:37:09 -0500 Subject: [PATCH 01/26] DX Filter Added options for tolerance for time and frequency offset for DeDupelication of spots. --- .gitignore | 2 ++ ui/DxFilterDialog.cpp | 6 ++++ ui/DxFilterDialog.ui | 74 +++++++++++++++++++++++++++++++++---------- ui/DxWidget.cpp | 25 +++++++++++++-- ui/DxWidget.h | 5 +++ 5 files changed, 93 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 0d53acad..a36ac251 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ compile_commands.json # QtCreator local machine specific files for imported projects *creator.user* +/build +.DS_Store diff --git a/ui/DxFilterDialog.cpp b/ui/DxFilterDialog.cpp index 3b90bef2..13fe480e 100644 --- a/ui/DxFilterDialog.cpp +++ b/ui/DxFilterDialog.cpp @@ -102,6 +102,10 @@ DxFilterDialog::DxFilterDialog(QWidget *parent) : /*****************/ bool deduplication = settings.value("dxc/filter_deduplication", false).toBool(); ui->deduplicationcheckbox->setChecked(deduplication); + int duplicationtime = settings.value("dxc/filter_duplicationtime", 360).toInt(); + ui->time_spinBox_dupe->setValue(duplicationtime); + int duplicationfreq = settings.value("dxc/filter_deduplicationfreq", 1).toInt(); + ui->freq_spinBox_dupe->setValue(duplicationfreq); /**********/ /* MEMBER */ @@ -185,6 +189,8 @@ void DxFilterDialog::accept() /* Deduplication */ /*****************/ settings.setValue("dxc/filter_deduplication", ui->deduplicationcheckbox->isChecked()); + settings.setValue("dxc/filter_duplicationtime",ui->time_spinBox_dupe->value() ); + settings.setValue("dxc/filter_deduplicationfreq", ui->freq_spinBox_dupe->value()); /**********/ /* MEMBER */ diff --git a/ui/DxFilterDialog.ui b/ui/DxFilterDialog.ui index 4709dd1a..e8f1e764 100644 --- a/ui/DxFilterDialog.ui +++ b/ui/DxFilterDialog.ui @@ -54,7 +54,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -350,6 +350,48 @@ + + + + + + Time Difference (secs) + + + + + + + 9999 + + + 360 + + + + + + + + + + + Frequency +/- khz + + + + + + + 100 + + + 5 + + + + + @@ -368,23 +410,23 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + @@ -396,10 +438,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok diff --git a/ui/DxWidget.cpp b/ui/DxWidget.cpp index 37233cc8..aa5d8fb0 100644 --- a/ui/DxWidget.cpp +++ b/ui/DxWidget.cpp @@ -119,7 +119,6 @@ bool DxTableModel::addEntry(DxSpot entry, bool deduplicate, qint16 dedup_interval, double dedup_freq_tolerance) { bool shouldInsert = true; - if ( deduplicate ) { for (const DxSpot &record : qAsConst(dxData)) @@ -128,7 +127,7 @@ bool DxTableModel::addEntry(DxSpot entry, bool deduplicate, break; if ( record.callsign == entry.callsign - && qAbs(record.freq - entry.freq) < dedup_freq_tolerance ) + && qAbs(record.freq*1000 - entry.freq*1000) < dedup_freq_tolerance ) { qCDebug(runtime) << "Duplicate spot" << record.callsign << record.freq << entry.callsign << entry.freq; shouldInsert = false; @@ -682,6 +681,24 @@ uint DxWidget::dxccStatusFilterValue() return settings.value("dxc/filter_dxcc_status", DxccStatus::All).toUInt(); } +int DxWidget::getDedupTimeValue() +{ + FCT_IDENTIFICATION; + + QSettings settings; + return settings.value("dxc/filter_duplicationtime", 360).toInt(); + +} + +int DxWidget::getDedupFreqValue() +{ + FCT_IDENTIFICATION; + + QSettings settings; + return settings.value("dxc/filter_duplicationfreq", 5).toInt(); + +} + bool DxWidget::spotDedupValue() { FCT_IDENTIFICATION; @@ -1244,6 +1261,8 @@ void DxWidget::reloadSetting() bandregexp.setPattern(bandFilterRegExp()); dxccStatusFilter = dxccStatusFilterValue(); deduplicateSpots = spotDedupValue(); + deduplicatetime = getDedupTimeValue(); + deduplicatefreq = getDedupFreqValue(); QStringList tmp = dxMemberList(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) dxMemberFilter = QSet(tmp.begin(), tmp.end()); @@ -1504,7 +1523,7 @@ void DxWidget::processDxSpot(const QString &spotter, || (dxMemberFilter.size() && spot.memberList2Set().intersects(dxMemberFilter))) ) { - if ( dxTableModel->addEntry(spot, deduplicateSpots) ) + if ( dxTableModel->addEntry(spot, deduplicateSpots, deduplicatetime, deduplicatefreq) ) emit newFilteredSpot(spot); } } diff --git a/ui/DxWidget.h b/ui/DxWidget.h index aa7ecf38..15c948a7 100644 --- a/ui/DxWidget.h +++ b/ui/DxWidget.h @@ -178,6 +178,9 @@ private slots: QRegularExpression bandregexp; uint dxccStatusFilter; bool deduplicateSpots; + int deduplicatetime; + int deduplicatefreq; + QSet dxMemberFilter; QSqlRecord lastQSO; quint8 reconnectAttempts; @@ -194,6 +197,8 @@ private slots: QString bandFilterRegExp(); uint dxccStatusFilterValue(); bool spotDedupValue(); + int getDedupTimeValue(); + int getDedupFreqValue(); QStringList dxMemberList(); bool getAutoconnectServer(); void saveAutoconnectServer(bool); From 3446edb384f91961b93c326437bd9a70ba5d2d0d Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:26:01 -0500 Subject: [PATCH 02/26] Fix for MacOS Layout Geometry Restore For MacOS the restore of the window geometry needs to occur after the window is shown. --- .gitignore | 2 ++ core/main.cpp | 4 +++- ui/MainWindow.h | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0d53acad..7fbb7d13 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ compile_commands.json # QtCreator local machine specific files for imported projects *creator.user* +.DS_Store +/build diff --git a/core/main.cpp b/core/main.cpp index 57f79eb3..e7bb75e3 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -562,6 +562,8 @@ int main(int argc, char* argv[]) w.setWindowIcon(icon); w.show(); - +#ifdef Q_OS_OSX + w.setLayoutGeometry(); +#endif return app.exec(); } diff --git a/ui/MainWindow.h b/ui/MainWindow.h index d458d71a..19622f74 100644 --- a/ui/MainWindow.h +++ b/ui/MainWindow.h @@ -42,6 +42,7 @@ public slots: void rotErrorHandler(const QString &error, const QString &errorDetail); void cwKeyerErrorHandler(const QString &error, const QString &errorDetail); void stationProfileChanged(); + void setLayoutGeometry(); private slots: void rigConnect(); @@ -75,7 +76,7 @@ private slots: void shortcutALTBackslash(); void setManualContact(bool); void showEditLayout(); - void setLayoutGeometry(); + void saveProfileLayoutGeometry(); void setEquipmentKeepOptions(bool); From a378b1bc605bd27eee6e96e7251e3ee51f5700bf Mon Sep 17 00:00:00 2001 From: Ladislav Foldyna Date: Fri, 2 Aug 2024 11:52:59 +0200 Subject: [PATCH 03/26] DX Filter: Spot Dedup setting - using default macros and units for TIME and FREQ --- rig/macros.h | 3 +++ ui/DxFilterDialog.cpp | 5 +++-- ui/DxWidget.cpp | 8 +++----- ui/DxWidget.h | 5 ++++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/rig/macros.h b/rig/macros.h index f1c09d68..b6f81cac 100644 --- a/rig/macros.h +++ b/rig/macros.h @@ -9,5 +9,8 @@ #ifndef MHz #define MHz(f) ((double)((f)*(double)1000000)) #endif +#ifndef kHz +#define kHz(f) ((double)((f)*(double)1000)) +#endif #endif // RIG_MACROS_H diff --git a/ui/DxFilterDialog.cpp b/ui/DxFilterDialog.cpp index 13fe480e..4489bba9 100644 --- a/ui/DxFilterDialog.cpp +++ b/ui/DxFilterDialog.cpp @@ -11,6 +11,7 @@ #include "core/debug.h" #include "data/Dxcc.h" #include "core/MembershipQE.h" +#include "DxWidget.h" MODULE_IDENTIFICATION("qlog.ui.dxfilterdialog"); @@ -102,9 +103,9 @@ DxFilterDialog::DxFilterDialog(QWidget *parent) : /*****************/ bool deduplication = settings.value("dxc/filter_deduplication", false).toBool(); ui->deduplicationcheckbox->setChecked(deduplication); - int duplicationtime = settings.value("dxc/filter_duplicationtime", 360).toInt(); + int duplicationtime = settings.value("dxc/filter_duplicationtime", DEDUPLICATION_TIME).toInt(); ui->time_spinBox_dupe->setValue(duplicationtime); - int duplicationfreq = settings.value("dxc/filter_deduplicationfreq", 1).toInt(); + int duplicationfreq = settings.value("dxc/filter_deduplicationfreq", DEDUPLICATION_FREQ_TOLERANCE).toInt(); ui->freq_spinBox_dupe->setValue(duplicationfreq); /**********/ diff --git a/ui/DxWidget.cpp b/ui/DxWidget.cpp index aa5d8fb0..198d7be8 100644 --- a/ui/DxWidget.cpp +++ b/ui/DxWidget.cpp @@ -127,7 +127,7 @@ bool DxTableModel::addEntry(DxSpot entry, bool deduplicate, break; if ( record.callsign == entry.callsign - && qAbs(record.freq*1000 - entry.freq*1000) < dedup_freq_tolerance ) + && qAbs(MHz(record.freq) - MHz(entry.freq)) < kHz(dedup_freq_tolerance) ) { qCDebug(runtime) << "Duplicate spot" << record.callsign << record.freq << entry.callsign << entry.freq; shouldInsert = false; @@ -686,8 +686,7 @@ int DxWidget::getDedupTimeValue() FCT_IDENTIFICATION; QSettings settings; - return settings.value("dxc/filter_duplicationtime", 360).toInt(); - + return settings.value("dxc/filter_duplicationtime", DEDUPLICATION_TIME).toInt(); } int DxWidget::getDedupFreqValue() @@ -695,8 +694,7 @@ int DxWidget::getDedupFreqValue() FCT_IDENTIFICATION; QSettings settings; - return settings.value("dxc/filter_duplicationfreq", 5).toInt(); - + return settings.value("dxc/filter_duplicationfreq", DEDUPLICATION_FREQ_TOLERANCE).toInt(); } bool DxWidget::spotDedupValue() diff --git a/ui/DxWidget.h b/ui/DxWidget.h index 15c948a7..8f2c6cce 100644 --- a/ui/DxWidget.h +++ b/ui/DxWidget.h @@ -16,8 +16,11 @@ #include "core/LogLocale.h" #include "core/DxServerString.h" +// in sec #define DEDUPLICATION_TIME 3 -#define DEDUPLICATION_FREQ_TOLERANCE 0.005 + +// in kHz +#define DEDUPLICATION_FREQ_TOLERANCE 5 namespace Ui { class DxWidget; From 42d09939ef0399532356c2691cfb24b8de1f9150 Mon Sep 17 00:00:00 2001 From: Ladislav Foldyna Date: Fri, 2 Aug 2024 13:49:15 +0200 Subject: [PATCH 04/26] DX Filter: Improved Time and Freq Settings --- ui/DxFilterDialog.cpp | 12 ++-- ui/DxFilterDialog.ui | 155 ++++++++++++++++++++++-------------------- 2 files changed, 89 insertions(+), 78 deletions(-) diff --git a/ui/DxFilterDialog.cpp b/ui/DxFilterDialog.cpp index 4489bba9..fc7f2fca 100644 --- a/ui/DxFilterDialog.cpp +++ b/ui/DxFilterDialog.cpp @@ -102,11 +102,11 @@ DxFilterDialog::DxFilterDialog(QWidget *parent) : /* Deduplication */ /*****************/ bool deduplication = settings.value("dxc/filter_deduplication", false).toBool(); - ui->deduplicationcheckbox->setChecked(deduplication); + ui->deduplicationGroupBox->setChecked(deduplication); int duplicationtime = settings.value("dxc/filter_duplicationtime", DEDUPLICATION_TIME).toInt(); - ui->time_spinBox_dupe->setValue(duplicationtime); + ui->dedupTimeDiffSpinbox->setValue(duplicationtime); int duplicationfreq = settings.value("dxc/filter_deduplicationfreq", DEDUPLICATION_FREQ_TOLERANCE).toInt(); - ui->freq_spinBox_dupe->setValue(duplicationfreq); + ui->dedupFreqDiffSpinbox->setValue(duplicationfreq); /**********/ /* MEMBER */ @@ -189,9 +189,9 @@ void DxFilterDialog::accept() /*****************/ /* Deduplication */ /*****************/ - settings.setValue("dxc/filter_deduplication", ui->deduplicationcheckbox->isChecked()); - settings.setValue("dxc/filter_duplicationtime",ui->time_spinBox_dupe->value() ); - settings.setValue("dxc/filter_deduplicationfreq", ui->freq_spinBox_dupe->value()); + settings.setValue("dxc/filter_deduplication", ui->deduplicationGroupBox->isChecked()); + settings.setValue("dxc/filter_duplicationtime",ui->dedupTimeDiffSpinbox->value() ); + settings.setValue("dxc/filter_deduplicationfreq", ui->dedupFreqDiffSpinbox->value()); /**********/ /* MEMBER */ diff --git a/ui/DxFilterDialog.ui b/ui/DxFilterDialog.ui index e8f1e764..7d3da130 100644 --- a/ui/DxFilterDialog.ui +++ b/ui/DxFilterDialog.ui @@ -54,7 +54,7 @@ - Qt::Orientation::Vertical + Qt::Vertical @@ -331,66 +331,77 @@ - + + + Do not show the following spots when they have the same Callsign and their time difference is lower than Time Diff and their frequency difference is lower than Freq Diff + - Others + Spots Dedup - - - - - - - Spots Deduplication - - - Spots Dedup - - - - + + true + + + + 4 + + + 4 + + + 6 + + + 6 + + + 6 + + + 6 + + + + + Time difference + + - - - - - - Time Difference (secs) - - - - - - - 9999 - - - 360 - - - - + + + + s + + + 1 + + + 9999 + + - - - - - - Frequency +/- khz - - - - - - - 100 - - - 5 - - - - + + + + Frequency difference + + + + + + + kHz + + + ± + + + 1 + + + 100 + + @@ -410,23 +421,23 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + - - - - Qt::Orientation::Vertical - - - - 20 - 40 - - - - @@ -438,10 +449,10 @@ - Qt::Orientation::Horizontal + Qt::Horizontal - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Ok From 26733b5301c5b9e375659c32347ed1c20f49eafa Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Wed, 31 Jul 2024 09:44:15 -0500 Subject: [PATCH 05/26] Awards Added simple stats similar to IOTA for POTA Hunter, POTA Activator, SOTA and WWFF --- .gitignore | 2 ++ ui/AwardsDialog.cpp | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0d53acad..7fbb7d13 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,5 @@ compile_commands.json # QtCreator local machine specific files for imported projects *creator.user* +.DS_Store +/build diff --git a/ui/AwardsDialog.cpp b/ui/AwardsDialog.cpp index f99be35f..9de0d07e 100644 --- a/ui/AwardsDialog.cpp +++ b/ui/AwardsDialog.cpp @@ -38,9 +38,11 @@ AwardsDialog::AwardsDialog(QWidget *parent) : ui->awardComboBox->addItem(tr("WAS"), QVariant("was")); ui->awardComboBox->addItem(tr("WPX"), QVariant("wpx")); ui->awardComboBox->addItem(tr("IOTA"), QVariant("iota")); - + ui->awardComboBox->addItem(tr("POTA Hunter"),QVariant("potah")); + ui->awardComboBox->addItem(tr("POTA Activator"),QVariant("potaa")); + ui->awardComboBox->addItem(tr("SOTA"),QVariant("sota")); + ui->awardComboBox->addItem(tr("WWFF"),QVariant("wwff")); ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Done")); - ui->awardTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->awardTableView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); @@ -151,7 +153,37 @@ void AwardsDialog::refreshTable(int) uniqColumns = "c.iota"; excludePart = " AND c.iota is not NULL "; } - + else if ( awardSelected == "potah" ) + { + headersColumns = "p.reference col1, translate_to_locale(p.name) col2 "; + uniqColumns = "c.pota_ref"; + sqlPart = " FROM pota_directory p " + " INNER JOIN contacts c ON p.reference = c.pota_ref " + " LEFT OUTER JOIN modes m on c.mode = m.name "; + } + else if ( awardSelected == "potaa" ) + { + headersColumns = "p.reference col1, translate_to_locale(p.name) col2 "; + uniqColumns = "c.my_pota_ref"; + sqlPart = " FROM pota_directory p " + " INNER JOIN contacts c ON p.reference = c.my_pota_ref " + " LEFT OUTER JOIN modes m on c.mode = m.name "; + } else if ( awardSelected == "sota" ) + { + headersColumns = "s.summit_code col1, NULL col2 "; + uniqColumns = "c.sota_ref"; + sqlPart = " FROM sota_summits s " + " INNER JOIN contacts c ON s.summit_code = c.sota_ref " + " LEFT OUTER JOIN modes m on c.mode = m.name "; + } + else if ( awardSelected == "wwff" ) + { + headersColumns = "w.reference col1, translate_to_locale(w.name) col2 "; + uniqColumns = "c.wwff_ref"; + sqlPart = " FROM wwff_directory w " + " INNER JOIN contacts c ON w.reference = c.wwff_ref " + " LEFT OUTER JOIN modes m on c.mode = m.name "; + } if ( ui->eqslCheckBox->isChecked() ) { confirmed << " eqsl_qsl_rcvd = 'Y' "; From 939eaf2e0db897b9c530e0a69c8bcd81188456c0 Mon Sep 17 00:00:00 2001 From: Ladislav Foldyna Date: Fri, 9 Aug 2024 10:16:19 +0200 Subject: [PATCH 06/26] Awards: SOTA/POTA/WWFF modifications - improved the WHERE part of the SQL - despite the fact that POTA/SOTA/WWFF should be connected with callsign, the statistics are generated based on the entire log. This is a bit of a simplification, as situations involving a portable callsign would also need to be addressed, which would complicate the process significantly. - Added doubleClick event - code cleanup --- ui/AwardsDialog.cpp | 157 +++++++++++++++++++++++++++----------------- ui/AwardsDialog.h | 6 +- 2 files changed, 100 insertions(+), 63 deletions(-) diff --git a/ui/AwardsDialog.cpp b/ui/AwardsDialog.cpp index 9de0d07e..8b04f138 100644 --- a/ui/AwardsDialog.cpp +++ b/ui/AwardsDialog.cpp @@ -38,10 +38,11 @@ AwardsDialog::AwardsDialog(QWidget *parent) : ui->awardComboBox->addItem(tr("WAS"), QVariant("was")); ui->awardComboBox->addItem(tr("WPX"), QVariant("wpx")); ui->awardComboBox->addItem(tr("IOTA"), QVariant("iota")); - ui->awardComboBox->addItem(tr("POTA Hunter"),QVariant("potah")); - ui->awardComboBox->addItem(tr("POTA Activator"),QVariant("potaa")); - ui->awardComboBox->addItem(tr("SOTA"),QVariant("sota")); - ui->awardComboBox->addItem(tr("WWFF"),QVariant("wwff")); + ui->awardComboBox->addItem(tr("POTA Hunter"), QVariant("potah")); + ui->awardComboBox->addItem(tr("POTA Activator"), QVariant("potaa")); + ui->awardComboBox->addItem(tr("SOTA"), QVariant("sota")); + ui->awardComboBox->addItem(tr("WWFF"), QVariant("wwff")); + ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Done")); ui->awardTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->awardTableView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); @@ -62,100 +63,119 @@ void AwardsDialog::refreshTable(int) { FCT_IDENTIFICATION; + const QList& dxccBands = BandPlan::bandsList(true, true); + + if ( dxccBands.size() == 0 ) + return; + QStringList confirmed("1=2 "); QStringList modes("'NONE'"); QString headersColumns; QString uniqColumns; - QString excludePart; + QString addWherePart; + QString sqlPart; - QString awardSelected = getSelectedAward(); - QString entitySelected = getSelectedEntity(); - - QString sqlPart = "FROM contacts c, modes m " - "WHERE c.mode = m.name" - " AND c.my_dxcc = '" + entitySelected + "' "; + const QString &awardSelected = getSelectedAward(); if ( ui->cwCheckBox->isChecked() ) - { modes << "'CW'"; - } if ( ui->phoneCheckBox->isChecked() ) - { modes << "'PHONE'"; - } if ( ui->digiCheckBox->isChecked() ) - { modes << "'DIGITAL'"; - } - if ( awardSelected == "dxcc" ) { + setEntityInputEnabled(true); + const QString &entitySelected = getSelectedEntity(); headersColumns = "translate_to_locale(d.name) col1, d.prefix col2 "; uniqColumns = "c.dxcc"; sqlPart = " FROM dxcc_entities d " " LEFT OUTER JOIN contacts c ON d.id = c.dxcc " " LEFT OUTER JOIN modes m on c.mode = m.name " "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; + addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; } else if ( awardSelected == "waz" ) { + setEntityInputEnabled(true); + const QString &entitySelected = getSelectedEntity(); headersColumns = "d.n col1, null col2 "; uniqColumns = "c.cqz"; sqlPart = " FROM cqzCTE d " " LEFT OUTER JOIN contacts c ON d.n = c.cqz " " LEFT OUTER JOIN modes m on c.mode = m.name " "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; + addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; } else if ( awardSelected == "itu" ) { + setEntityInputEnabled(true); + const QString &entitySelected = getSelectedEntity(); headersColumns = "d.n col1, null col2 "; uniqColumns = "c.ituz"; sqlPart = " FROM ituzCTE d " " LEFT OUTER JOIN contacts c ON d.n = c.ituz " " LEFT OUTER JOIN modes m on c.mode = m.name " "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; + addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; } else if ( awardSelected == "wac" ) { + setEntityInputEnabled(true); + const QString &entitySelected = getSelectedEntity(); headersColumns = "d.column2 col1, d.column1 col2 "; uniqColumns = "c.cont"; sqlPart = " FROM continents d " " LEFT OUTER JOIN contacts c ON d.column1 = c.cont " " LEFT OUTER JOIN modes m on c.mode = m.name " "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; + addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; } else if ( awardSelected == "was" ) { + setEntityInputEnabled(true); + const QString &entitySelected = getSelectedEntity(); headersColumns = "d.subdivision_name col1, d.code col2 "; uniqColumns = "c.state"; sqlPart = " FROM adif_enum_primary_subdivision d " " LEFT OUTER JOIN contacts c ON d.dxcc = c.dxcc AND d.code = c.state " " LEFT OUTER JOIN modes m on c.mode = m.name " "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "' AND d.dxcc in (6, 110, 291)) "; + addWherePart = " AND (c.id is NULL or c.my_dxcc = '" + entitySelected + "' AND c.dxcc in (6, 110, 291)) "; } else if ( awardSelected == "wpx" ) { + setEntityInputEnabled(true); + const QString &entitySelected = getSelectedEntity(); headersColumns = "c.pfx col1, null col2 "; uniqColumns = "c.pfx"; sqlPart = "FROM contacts c, modes m " "WHERE c.mode = m.name" " AND c.pfx is not null" " AND c.my_dxcc = '" + entitySelected + "'"; + addWherePart = " AND c.my_dxcc = '" + entitySelected + "' "; } else if ( awardSelected == "iota" ) { + setEntityInputEnabled(true); + const QString &entitySelected = getSelectedEntity(); headersColumns = "c.iota col1, NULL col2 "; uniqColumns = "c.iota"; - excludePart = " AND c.iota is not NULL "; + sqlPart = "FROM contacts c, modes m " + "WHERE c.mode = m.name" + " AND c.my_dxcc = '" + entitySelected + "' "; + addWherePart = " AND c.iota is not NULL " + " AND c.my_dxcc = '" + entitySelected + "' "; } else if ( awardSelected == "potah" ) { - headersColumns = "p.reference col1, translate_to_locale(p.name) col2 "; + setEntityInputEnabled(false); + headersColumns = "p.reference col1, p.name col2 "; uniqColumns = "c.pota_ref"; sqlPart = " FROM pota_directory p " " INNER JOIN contacts c ON p.reference = c.pota_ref " @@ -163,13 +183,16 @@ void AwardsDialog::refreshTable(int) } else if ( awardSelected == "potaa" ) { - headersColumns = "p.reference col1, translate_to_locale(p.name) col2 "; + setEntityInputEnabled(false); + headersColumns = "p.reference col1, p.name col2 "; uniqColumns = "c.my_pota_ref"; sqlPart = " FROM pota_directory p " " INNER JOIN contacts c ON p.reference = c.my_pota_ref " " LEFT OUTER JOIN modes m on c.mode = m.name "; - } else if ( awardSelected == "sota" ) + } + else if ( awardSelected == "sota" ) { + setEntityInputEnabled(false); headersColumns = "s.summit_code col1, NULL col2 "; uniqColumns = "c.sota_ref"; sqlPart = " FROM sota_summits s " @@ -178,35 +201,24 @@ void AwardsDialog::refreshTable(int) } else if ( awardSelected == "wwff" ) { - headersColumns = "w.reference col1, translate_to_locale(w.name) col2 "; + setEntityInputEnabled(false); + headersColumns = "w.reference col1, w.name col2 "; uniqColumns = "c.wwff_ref"; sqlPart = " FROM wwff_directory w " " INNER JOIN contacts c ON w.reference = c.wwff_ref " " LEFT OUTER JOIN modes m on c.mode = m.name "; } + if ( ui->eqslCheckBox->isChecked() ) - { confirmed << " eqsl_qsl_rcvd = 'Y' "; - } if ( ui->lotwCheckBox->isChecked() ) - { confirmed << " lotw_qsl_rcvd = 'Y' "; - } if ( ui->paperCheckBox->isChecked() ) - { confirmed << " qsl_rcvd = 'Y' "; - } - - QString innerCase = " CASE WHEN (" + confirmed.join("or") + ") THEN 2 ELSE 1 END "; - const QList& dxccBands = BandPlan::bandsList(true, true); - - if ( dxccBands.size() == 0 ) - { - return; - } + const QString &innerCase = " CASE WHEN (" + confirmed.join("or") + ") THEN 2 ELSE 1 END "; QStringList stmt_max_part; QStringList stmt_total_padding; @@ -214,14 +226,15 @@ void AwardsDialog::refreshTable(int) QStringList stmt_sum_worked; QStringList stmt_sum_total; - for ( int i = 0; i < dxccBands.size(); i++ ) + for ( const Band& band : dxccBands ) { - stmt_max_part << QString(" MAX(CASE WHEN band = '%1' AND m.dxcc IN (" + modes.join(",") + ") THEN " + innerCase + " ELSE 0 END) as '%2'").arg(dxccBands[i].name, dxccBands[i].name); - stmt_total_padding << QString(" NULL '%1'").arg(dxccBands[i].name); - stmt_sum_confirmed << QString("SUM(CASE WHEN a.'%1' > 1 THEN 1 ELSE 0 END) '%2'").arg(dxccBands[i].name, dxccBands[i].name); - stmt_sum_worked << QString("SUM(CASE WHEN a.'%1' > 0 THEN 1 ELSE 0 END) '%2'").arg(dxccBands[i].name, dxccBands[i].name); - stmt_sum_total << QString("SUM(d.'%1') '%2'").arg(dxccBands[i].name, dxccBands[i].name); + stmt_max_part << QString(" MAX(CASE WHEN band = '%1' AND m.dxcc IN (" + modes.join(",") + ") THEN " + innerCase + " ELSE 0 END) as '%2'").arg(band.name, band.name); + stmt_total_padding << QString(" NULL '%1'").arg(band.name); + stmt_sum_confirmed << QString("SUM(CASE WHEN a.'%1' > 1 THEN 1 ELSE 0 END) '%2'").arg(band.name, band.name); + stmt_sum_worked << QString("SUM(CASE WHEN a.'%1' > 0 THEN 1 ELSE 0 END) '%2'").arg(band.name, band.name); + stmt_sum_total << QString("SUM(d.'%1') '%2'").arg(band.name, band.name); } + detailedViewModel->setQuery( "WITH dxcc_summary AS ( " "SELECT " + headersColumns +", " @@ -229,7 +242,7 @@ void AwardsDialog::refreshTable(int) " MAX(CASE WHEN prop_mode = 'SAT' AND m.dxcc IN (" + modes.join(",") + ") THEN " + innerCase + " ELSE 0 END) as 'SAT', " " MAX(CASE WHEN prop_mode = 'EME' AND m.dxcc IN (" + modes.join(",") + ") THEN " + innerCase + " ELSE 0 END) as 'EME' " + sqlPart - + excludePart + + + addWherePart + "GROUP BY 1,2), " " ituzCTE AS ( " " SELECT 1 AS n, 1 AS value " @@ -254,9 +267,8 @@ void AwardsDialog::refreshTable(int) " NULL 'EME' " "FROM contacts c, modes m " "WHERE c.mode = m.name " - " AND c.my_dxcc = '" + entitySelected + "' " " AND m.dxcc IN (" + modes.join(",") + ") " - + excludePart + + + addWherePart + "UNION ALL " "SELECT 0 column_idx, " " '" + tr("TOTAL Confirmed") + "', " @@ -268,8 +280,7 @@ void AwardsDialog::refreshTable(int) "WHERE (" + confirmed.join("or") + ") " " AND c.mode = m.name " " AND m.dxcc IN (" + modes.join(",") + ") " - " AND c.my_dxcc = '" + entitySelected + "' " - + excludePart + + + addWherePart + "UNION ALL " "SELECT 1 column_idx, " " '" + tr("Confirmed") + "', NULL prefix, " @@ -310,13 +321,13 @@ void AwardsDialog::awardTableDoubleClicked(QModelIndex idx) { FCT_IDENTIFICATION; - QString myEntitySelected = getSelectedEntity(); - QString awardSelected = getSelectedAward(); + const QString &awardSelected = getSelectedAward(); QStringList addlFilters; QString band; QString country; - addlFilters << QString("my_dxcc='%1'").arg(myEntitySelected); + if ( ui->myEntityComboBox->isEnabled() ) + addlFilters << QString("my_dxcc='%1'").arg(getSelectedEntity()); if ( idx.row() > 3 ) { @@ -324,30 +335,46 @@ void AwardsDialog::awardTableDoubleClicked(QModelIndex idx) { country = detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString(); } - if ( awardSelected == "itu" ) + else if ( awardSelected == "itu" ) { addlFilters << QString("ituz = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); } - if ( awardSelected == "iota" ) + else if ( awardSelected == "iota" ) { addlFilters << QString("upper(iota) = upper('%1')").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); } - if ( awardSelected == "wac" ) + else if ( awardSelected == "wac" ) { addlFilters << QString("cont = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),2),Qt::DisplayRole).toString()); } - if ( awardSelected == "was" ) + else if ( awardSelected == "was" ) { addlFilters << QString("state = '%1' and dxcc in (6, 110, 291)").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),2),Qt::DisplayRole).toString()); } - if ( awardSelected == "waz" ) + else if ( awardSelected == "waz" ) { addlFilters << QString("cqz = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); } - if ( awardSelected == "wpx" ) + else if ( awardSelected == "wpx" ) { addlFilters << QString("pfx = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); } + else if ( awardSelected == "potah" ) + { + addlFilters << QString("pota_ref = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); + } + else if ( awardSelected == "potaa" ) + { + addlFilters << QString("my_pota_ref = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); + } + else if ( awardSelected == "sota" ) + { + addlFilters << QString("sota_ref = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); + } + else if ( awardSelected == "wwff" ) + { + addlFilters << QString("wwff_ref = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); + } if ( idx.column() > 2 ) { @@ -358,20 +385,20 @@ void AwardsDialog::awardTableDoubleClicked(QModelIndex idx) } } -QString AwardsDialog::getSelectedEntity() +const QString AwardsDialog::getSelectedEntity() const { FCT_IDENTIFICATION; int row = ui->myEntityComboBox->currentIndex(); - QModelIndex idx = ui->myEntityComboBox->model()->index(row,0); - QVariant comboData = ui->myEntityComboBox->model()->data(idx); + const QModelIndex &idx = ui->myEntityComboBox->model()->index(row,0); + const QVariant &comboData = ui->myEntityComboBox->model()->data(idx); qCDebug(runtime) << comboData.toString(); return comboData.toString(); } -QString AwardsDialog::getSelectedAward() +const QString AwardsDialog::getSelectedAward() const { FCT_IDENTIFICATION; @@ -379,3 +406,11 @@ QString AwardsDialog::getSelectedAward() qCDebug(runtime) << ret; return ret; } + +void AwardsDialog::setEntityInputEnabled(bool enabled) +{ + FCT_IDENTIFICATION; + + ui->myEntityComboBox->setEnabled(enabled); + ui->myEntityLabel->setEnabled(enabled); +} diff --git a/ui/AwardsDialog.h b/ui/AwardsDialog.h index 38a59312..b94a9080 100644 --- a/ui/AwardsDialog.h +++ b/ui/AwardsDialog.h @@ -29,9 +29,11 @@ public slots: Ui::AwardsDialog *ui; AwardsTableModel *detailedViewModel; SqlListModel* entityCallsignModel; + QString selectedAward; - QString getSelectedEntity(); - QString getSelectedAward(); + const QString getSelectedEntity() const; + const QString getSelectedAward() const; + void setEntityInputEnabled(bool); }; #endif // QLOG_UI_AWARDSDIALOG_H From c3b487d81c3c78b9a4ab5fdf36772f7858d99404 Mon Sep 17 00:00:00 2001 From: Ladislav Foldyna Date: Fri, 9 Aug 2024 14:44:25 +0200 Subject: [PATCH 07/26] Awards: Reworked Dynamic SQL statement; POTA supports list of POTAs and @-notification --- ui/AwardsDialog.cpp | 352 +++++++++++++++++++++++++------------------- ui/AwardsDialog.ui | 68 ++++++++- 2 files changed, 268 insertions(+), 152 deletions(-) diff --git a/ui/AwardsDialog.cpp b/ui/AwardsDialog.cpp index 8b04f138..c7867ce1 100644 --- a/ui/AwardsDialog.cpp +++ b/ui/AwardsDialog.cpp @@ -73,7 +73,14 @@ void AwardsDialog::refreshTable(int) QString headersColumns; QString uniqColumns; QString addWherePart; - QString sqlPart; + QString sourceContactsTable; + QString sqlPartDetailTable; + QStringList stmt_max_part; + QStringList stmt_total_padding; + QStringList stmt_sum_confirmed; + QStringList stmt_sum_worked; + QStringList stmt_sum_total; + QStringList addlCTEs; const QString &awardSelected = getSelectedAward(); @@ -86,16 +93,54 @@ void AwardsDialog::refreshTable(int) if ( ui->digiCheckBox->isChecked() ) modes << "'DIGITAL'"; + if ( ui->eqslCheckBox->isChecked() ) + confirmed << " eqsl_qsl_rcvd = 'Y' "; + + if ( ui->lotwCheckBox->isChecked() ) + confirmed << " lotw_qsl_rcvd = 'Y' "; + + if ( ui->paperCheckBox->isChecked() ) + confirmed << " qsl_rcvd = 'Y' "; + + const QString innerConfirmedCase(QLatin1String(" CASE WHEN (%1) THEN 2 ELSE 1 END ").arg(confirmed.join("or"))); + + for ( const Band& band : dxccBands ) + { + stmt_max_part << QString(" MAX(CASE WHEN band = '%1' AND m.dxcc IN (%2) THEN %3 ELSE 0 END) as '%4'").arg(band.name, + modes.join(","), + innerConfirmedCase, + band.name); + stmt_total_padding << QString(" NULL '%1'").arg(band.name); + stmt_sum_confirmed << QString("SUM(CASE WHEN a.'%1' > 1 THEN 1 ELSE 0 END) '%2'").arg(band.name, band.name); + stmt_sum_worked << QString("SUM(CASE WHEN a.'%1' > 0 THEN 1 ELSE 0 END) '%2'").arg(band.name, band.name); + stmt_sum_total << QString("SUM(d.'%1') '%2'").arg(band.name, band.name); + } + + stmt_max_part << QString(" MAX(CASE WHEN prop_mode = 'SAT' AND m.dxcc IN (%1) THEN %2 ELSE 0 END) as 'SAT' ").arg(modes.join(","), innerConfirmedCase) + << QString(" MAX(CASE WHEN prop_mode = 'EME' AND m.dxcc IN (%1) THEN %2 ELSE 0 END) as 'EME' ").arg(modes.join(","), innerConfirmedCase); + stmt_total_padding << " NULL 'SAT' " + << " NULL 'EME' "; + stmt_sum_confirmed << " SUM(CASE WHEN a.'SAT' > 1 THEN 1 ELSE 0 END) 'SAT' " + << " SUM(CASE WHEN a.'EME' > 1 THEN 1 ELSE 0 END) 'EME' "; + stmt_sum_worked << " SUM(CASE WHEN a.'SAT' > 0 THEN 1 ELSE 0 END) 'SAT' " + << " SUM(CASE WHEN a.'EME' > 0 THEN 1 ELSE 0 END) 'EME' "; + stmt_sum_total << " SUM(d.'SAT') 'SAT' " + << " SUM(d.'EME') 'EME' "; + + sourceContactsTable = " source_contacts AS (" + " SELECT * " + " FROM contacts )"; + if ( awardSelected == "dxcc" ) { setEntityInputEnabled(true); const QString &entitySelected = getSelectedEntity(); headersColumns = "translate_to_locale(d.name) col1, d.prefix col2 "; uniqColumns = "c.dxcc"; - sqlPart = " FROM dxcc_entities d " - " LEFT OUTER JOIN contacts c ON d.id = c.dxcc " - " LEFT OUTER JOIN modes m on c.mode = m.name " - "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; + sqlPartDetailTable = " FROM dxcc_entities d" + " LEFT OUTER JOIN source_contacts c ON d.id = c.dxcc" + " LEFT OUTER JOIN modes m on c.mode = m.name" + " WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; } else if ( awardSelected == "waz" ) @@ -104,11 +149,17 @@ void AwardsDialog::refreshTable(int) const QString &entitySelected = getSelectedEntity(); headersColumns = "d.n col1, null col2 "; uniqColumns = "c.cqz"; - sqlPart = " FROM cqzCTE d " - " LEFT OUTER JOIN contacts c ON d.n = c.cqz " - " LEFT OUTER JOIN modes m on c.mode = m.name " - "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; - addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; + addlCTEs<< " cqzCTE AS ( " + " SELECT 1 AS n, 1 AS value" + " UNION ALL" + " SELECT n + 1, value + 1" + " FROM cqzCTE" + " WHERE n < 40 )"; + sqlPartDetailTable = " FROM cqzCTE d " + " LEFT OUTER JOIN source_contacts c ON d.n = c.cqz" + " LEFT OUTER JOIN modes m on c.mode = m.name " + " WHERE (c.id IS NULL OR c.my_dxcc = '" + entitySelected + "') "; + addWherePart = " AND (c.id IS NULL OR c.my_dxcc = '" + entitySelected + "') "; } else if ( awardSelected == "itu" ) { @@ -116,10 +167,16 @@ void AwardsDialog::refreshTable(int) const QString &entitySelected = getSelectedEntity(); headersColumns = "d.n col1, null col2 "; uniqColumns = "c.ituz"; - sqlPart = " FROM ituzCTE d " - " LEFT OUTER JOIN contacts c ON d.n = c.ituz " - " LEFT OUTER JOIN modes m on c.mode = m.name " - "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; + addlCTEs << " ituzCTE AS (" + " SELECT 1 AS n, 1 AS value" + " UNION ALL" + " SELECT n + 1, value + 1" + " FROM ituzCTE" + " WHERE n < 90 )"; + sqlPartDetailTable = " FROM ituzCTE d " + " LEFT OUTER JOIN source_contacts c ON d.n = c.ituz" + " LEFT OUTER JOIN modes m on c.mode = m.name" + " WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; } @@ -129,10 +186,18 @@ void AwardsDialog::refreshTable(int) const QString &entitySelected = getSelectedEntity(); headersColumns = "d.column2 col1, d.column1 col2 "; uniqColumns = "c.cont"; - sqlPart = " FROM continents d " - " LEFT OUTER JOIN contacts c ON d.column1 = c.cont " - " LEFT OUTER JOIN modes m on c.mode = m.name " - "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; + addlCTEs << " continents as " + " (values ('NA', '" + tr("North America") + "')," + " ('SA', '" + tr("South America") + "')," + " ('EU', '" + tr("Europe") + "')," + " ('AF', '" + tr("Africa") + "')," + " ('OC', '" + tr("Oceania") + "')," + " ('AS', '" + tr("Asia") + "')," + " ('AN', '" + tr("Antarctica") + "'))"; + sqlPartDetailTable = " FROM continents d " + " LEFT OUTER JOIN source_contacts c ON d.column1 = c.cont " + " LEFT OUTER JOIN modes m on c.mode = m.name " + " WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "') "; addWherePart = " AND (c.id is NULL OR c.my_dxcc = '" + entitySelected + "') "; } @@ -142,10 +207,10 @@ void AwardsDialog::refreshTable(int) const QString &entitySelected = getSelectedEntity(); headersColumns = "d.subdivision_name col1, d.code col2 "; uniqColumns = "c.state"; - sqlPart = " FROM adif_enum_primary_subdivision d " - " LEFT OUTER JOIN contacts c ON d.dxcc = c.dxcc AND d.code = c.state " - " LEFT OUTER JOIN modes m on c.mode = m.name " - "WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "' AND d.dxcc in (6, 110, 291)) "; + sqlPartDetailTable = " FROM adif_enum_primary_subdivision d" + " LEFT OUTER JOIN source_contacts c ON d.dxcc = c.dxcc AND d.code = c.state" + " LEFT OUTER JOIN modes m on c.mode = m.name" + " WHERE (c.id is NULL or c.my_dxcc = '" + entitySelected + "' AND d.dxcc in (6, 110, 291)) "; addWherePart = " AND (c.id is NULL or c.my_dxcc = '" + entitySelected + "' AND c.dxcc in (6, 110, 291)) "; } else if ( awardSelected == "wpx" ) @@ -154,10 +219,10 @@ void AwardsDialog::refreshTable(int) const QString &entitySelected = getSelectedEntity(); headersColumns = "c.pfx col1, null col2 "; uniqColumns = "c.pfx"; - sqlPart = "FROM contacts c, modes m " - "WHERE c.mode = m.name" - " AND c.pfx is not null" - " AND c.my_dxcc = '" + entitySelected + "'"; + sqlPartDetailTable = " FROM source_contacts c" + " INNER JOIN modes m ON c.mode = m.name" + " WHERE c.pfx is not null" + " AND c.my_dxcc = '" + entitySelected + "'"; addWherePart = " AND c.my_dxcc = '" + entitySelected + "' "; } else if ( awardSelected == "iota" ) @@ -166,153 +231,142 @@ void AwardsDialog::refreshTable(int) const QString &entitySelected = getSelectedEntity(); headersColumns = "c.iota col1, NULL col2 "; uniqColumns = "c.iota"; - sqlPart = "FROM contacts c, modes m " - "WHERE c.mode = m.name" - " AND c.my_dxcc = '" + entitySelected + "' "; - addWherePart = " AND c.iota is not NULL " + sqlPartDetailTable = " FROM source_contacts c" + " INNER JOIN modes m ON c.mode = m.name" + " WHERE c.my_dxcc = '" + entitySelected + "' "; + addWherePart = " AND c.iota is not NULL" " AND c.my_dxcc = '" + entitySelected + "' "; } else if ( awardSelected == "potah" ) { setEntityInputEnabled(false); headersColumns = "p.reference col1, p.name col2 "; - uniqColumns = "c.pota_ref"; - sqlPart = " FROM pota_directory p " - " INNER JOIN contacts c ON p.reference = c.pota_ref " - " LEFT OUTER JOIN modes m on c.mode = m.name "; + uniqColumns = "c.pota"; + sqlPartDetailTable = " FROM pota_directory p " + " INNER JOIN source_contacts c ON SUBSTR(c.pota, 1, COALESCE(NULLIF(INSTR(c.pota, '@'), 0) - 1, LENGTH(c.pota))) = p.reference" + " INNER JOIN modes m on c.mode = m.name "; + addlCTEs << " split(id, callsign, station_callsign, my_dxcc, band, dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd,prop_mode,mode, pota, str) AS (" + " SELECT id, callsign, station_callsign, my_dxcc, band, " + " dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd,prop_mode,mode, " + " '', pota_ref||',' " + " FROM contacts " + " UNION ALL " + " SELECT id, callsign, station_callsign, my_dxcc, band, " + " dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd,prop_mode,mode, " + " substr(str, 0, instr(str, ',')), substr(str, instr(str, ',') + 1) " + " FROM split " + " WHERE str != '') "; + sourceContactsTable = " source_contacts AS (" + " SELECT id, callsign, station_callsign, my_dxcc, band, dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd,prop_mode,mode, pota " + " FROM split " + " WHERE pota != '' ) "; + addWherePart = " AND c.pota is not NULL "; } else if ( awardSelected == "potaa" ) { setEntityInputEnabled(false); headersColumns = "p.reference col1, p.name col2 "; - uniqColumns = "c.my_pota_ref"; - sqlPart = " FROM pota_directory p " - " INNER JOIN contacts c ON p.reference = c.my_pota_ref " - " LEFT OUTER JOIN modes m on c.mode = m.name "; + uniqColumns = "c.my_pota_ref_str"; + sqlPartDetailTable = " FROM pota_directory p " + " INNER JOIN source_contacts c ON SUBSTR(c.my_pota_ref_str, 1, COALESCE(NULLIF(INSTR(c.my_pota_ref_str, '@'), 0) - 1, LENGTH(c.my_pota_ref_str))) = p.reference" + " INNER JOIN modes m on c.mode = m.name "; + addlCTEs << " split(id, callsign, station_callsign, my_dxcc, band, dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd, prop_mode, mode, my_pota_ref_str, str) AS (" + " SELECT id, callsign, station_callsign, my_dxcc, band, " + " dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd,prop_mode,mode, " + " '', my_pota_ref||',' " + " FROM contacts " + " UNION ALL " + " SELECT id, callsign, station_callsign, my_dxcc, band, " + " dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd, prop_mode, mode, " + " substr(str, 0, instr(str, ',')), substr(str, instr(str, ',') + 1) " + " FROM split " + " WHERE str != '') "; + sourceContactsTable = " source_contacts AS (" + " SELECT id, callsign, station_callsign, my_dxcc, band, dxcc, eqsl_qsl_rcvd, lotw_qsl_rcvd, qsl_rcvd,prop_mode, mode, my_pota_ref_str " + " FROM split " + " WHERE my_pota_ref_str != '' ) "; + addWherePart = " AND c.my_pota_ref_str is not NULL "; } else if ( awardSelected == "sota" ) { setEntityInputEnabled(false); headersColumns = "s.summit_code col1, NULL col2 "; uniqColumns = "c.sota_ref"; - sqlPart = " FROM sota_summits s " - " INNER JOIN contacts c ON s.summit_code = c.sota_ref " - " LEFT OUTER JOIN modes m on c.mode = m.name "; + + sqlPartDetailTable = " FROM sota_summits s " + " INNER JOIN source_contacts c ON c.sota_ref = s.summit_code " + " INNER JOIN modes m on c.mode = m.name "; } else if ( awardSelected == "wwff" ) { setEntityInputEnabled(false); headersColumns = "w.reference col1, w.name col2 "; uniqColumns = "c.wwff_ref"; - sqlPart = " FROM wwff_directory w " - " INNER JOIN contacts c ON w.reference = c.wwff_ref " - " LEFT OUTER JOIN modes m on c.mode = m.name "; + sqlPartDetailTable = " FROM wwff_directory w " + " INNER JOIN source_contacts c ON c.wwff_ref = w.reference " + " INNER JOIN modes m on c.mode = m.name "; } - if ( ui->eqslCheckBox->isChecked() ) - confirmed << " eqsl_qsl_rcvd = 'Y' "; - - if ( ui->lotwCheckBox->isChecked() ) - confirmed << " lotw_qsl_rcvd = 'Y' "; - - if ( ui->paperCheckBox->isChecked() ) - confirmed << " qsl_rcvd = 'Y' "; - - const QString &innerCase = " CASE WHEN (" + confirmed.join("or") + ") THEN 2 ELSE 1 END "; - - QStringList stmt_max_part; - QStringList stmt_total_padding; - QStringList stmt_sum_confirmed; - QStringList stmt_sum_worked; - QStringList stmt_sum_total; - - for ( const Band& band : dxccBands ) - { - stmt_max_part << QString(" MAX(CASE WHEN band = '%1' AND m.dxcc IN (" + modes.join(",") + ") THEN " + innerCase + " ELSE 0 END) as '%2'").arg(band.name, band.name); - stmt_total_padding << QString(" NULL '%1'").arg(band.name); - stmt_sum_confirmed << QString("SUM(CASE WHEN a.'%1' > 1 THEN 1 ELSE 0 END) '%2'").arg(band.name, band.name); - stmt_sum_worked << QString("SUM(CASE WHEN a.'%1' > 0 THEN 1 ELSE 0 END) '%2'").arg(band.name, band.name); - stmt_sum_total << QString("SUM(d.'%1') '%2'").arg(band.name, band.name); - } - - detailedViewModel->setQuery( - "WITH dxcc_summary AS ( " - "SELECT " + headersColumns +", " - + stmt_max_part.join(",") + ", " - " MAX(CASE WHEN prop_mode = 'SAT' AND m.dxcc IN (" + modes.join(",") + ") THEN " + innerCase + " ELSE 0 END) as 'SAT', " - " MAX(CASE WHEN prop_mode = 'EME' AND m.dxcc IN (" + modes.join(",") + ") THEN " + innerCase + " ELSE 0 END) as 'EME' " - + sqlPart - + addWherePart + - "GROUP BY 1,2), " - " ituzCTE AS ( " - " SELECT 1 AS n, 1 AS value " - " UNION ALL " - " SELECT n + 1, value + 1 " - " FROM ituzCTE " - " WHERE n < 90 ), " - " cqzCTE AS ( " - " SELECT 1 AS n, 1 AS value " - " UNION ALL " - " SELECT n + 1, value + 1 " - " FROM cqzCTE " - " WHERE n < 40 ), " - "continents as " - "(values ('NA', '" + tr("North America") + "'),('SA','" + tr("South America") + "'),('EU', '" + tr("Europe") + "'),('AF', '" + tr("Africa") + "'),('OC', '" + tr("Oceania") + "'),('AS', '" + tr("Asia") + "'),('AN', '" + tr("Antarctica") + "')) " - "SELECT * FROM ( " - "SELECT 0 column_idx, " - " '" + tr("TOTAL Worked") + "', " - " count(DISTINCT " + uniqColumns + "), " - + stmt_total_padding.join(",") + ", " + - " NULL 'SAT', " - " NULL 'EME' " - "FROM contacts c, modes m " - "WHERE c.mode = m.name " - " AND m.dxcc IN (" + modes.join(",") + ") " - + addWherePart + - "UNION ALL " - "SELECT 0 column_idx, " - " '" + tr("TOTAL Confirmed") + "', " - " count(DISTINCT " + uniqColumns + "), " - + stmt_total_padding.join(",") + ", " + - " NULL 'SAT', " - " NULL 'EME' " - "FROM contacts c, modes m " - "WHERE (" + confirmed.join("or") + ") " - " AND c.mode = m.name " - " AND m.dxcc IN (" + modes.join(",") + ") " - + addWherePart + - "UNION ALL " - "SELECT 1 column_idx, " - " '" + tr("Confirmed") + "', NULL prefix, " - + stmt_sum_confirmed.join(",") + ", " + - " SUM(CASE WHEN a.'SAT' > 1 THEN 1 ELSE 0 END) 'SAT', " - " SUM(CASE WHEN a.'EME' > 1 THEN 1 ELSE 0 END) 'EME' " - "FROM dxcc_summary a " - "GROUP BY 1 " - "UNION ALL " - "SELECT 2 column_idx, " - " '" + tr("Worked") + "', NULL prefix, " - + stmt_sum_worked.join(",") + ", " + - " SUM(CASE WHEN a.'SAT' > 0 THEN 1 ELSE 0 END) 'SAT', " - " SUM(CASE WHEN a.'EME' > 0 THEN 1 ELSE 0 END) 'EME' " - "FROM dxcc_summary a " - "GROUP BY 1 " - "UNION ALL " - "SELECT 3 column_idx, " - " col1, col2, " - + stmt_sum_total.join(",") + ", " + - " SUM(d.'SAT') 'SAT', " - " SUM(d.'EME') 'EME' " - " from dxcc_summary d " - "GROUP BY 2,3 " - ") " - "ORDER BY 1,2 COLLATE LOCALEAWARE ASC "); - - qDebug(runtime) << detailedViewModel->query().lastQuery(); - + addlCTEs.append(sourceContactsTable); + + QString finalSQL(QString( + "WITH " + " %1, " + " detail_table AS ( " + " SELECT %2, %3 " + " %4" + " %5" + " GROUP BY 1,2) " + "SELECT * FROM ( " + " SELECT 0 column_idx, '%6', COUNT(DISTINCT %7), %8" + " FROM source_contacts c INNER JOIN modes m ON c.mode = m.name" + " WHERE m.dxcc IN (%9)" + " %10" + " UNION ALL " + " SELECT 0 column_idx, '%11', COUNT(DISTINCT %12), %13" + " FROM source_contacts c INNER JOIN modes m ON c.mode = m.name " + " WHERE (%14)" + " AND m.dxcc IN (%15)" + " %16" + " UNION ALL " + " SELECT 1 column_idx, '%17', NULL prefix, %18" + " FROM detail_table a " + " GROUP BY 1 " + " UNION ALL " + " SELECT 2 column_idx, '%19', NULL prefix, %20" + " FROM detail_table a " + " GROUP BY 1 " + " UNION ALL " + " SELECT 3 column_idx, col1, col2, %21" + " FROM detail_table d " + " GROUP BY 2,3 " + ") " + "ORDER BY 1,2 COLLATE LOCALEAWARE ASC ").arg(addlCTEs.join(","), + headersColumns, + stmt_max_part.join(","), + sqlPartDetailTable, + addWherePart, + tr("TOTAL Worked"), + uniqColumns, + stmt_total_padding.join(","), + modes.join(","), + addWherePart, + tr("TOTAL Confirmed"), + uniqColumns, + stmt_total_padding.join(","), + confirmed.join("or"), + modes.join(","), + addWherePart, + tr("Confirmed"), + stmt_sum_confirmed.join(","), + tr("Worked"), + stmt_sum_worked.join(","), + stmt_sum_total.join(","))); + qDebug(runtime) << finalSQL; + + detailedViewModel->setQuery(finalSQL); detailedViewModel->setHeaderData(1, Qt::Horizontal, ""); detailedViewModel->setHeaderData(2, Qt::Horizontal, ""); - ui->awardTableView->setModel(detailedViewModel); ui->awardTableView->setColumnHidden(0,true); } @@ -341,7 +395,7 @@ void AwardsDialog::awardTableDoubleClicked(QModelIndex idx) } else if ( awardSelected == "iota" ) { - addlFilters << QString("upper(iota) = upper('%1')").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); + addlFilters << QString("iota = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); } else if ( awardSelected == "wac" ) { @@ -361,11 +415,11 @@ void AwardsDialog::awardTableDoubleClicked(QModelIndex idx) } else if ( awardSelected == "potah" ) { - addlFilters << QString("pota_ref = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); + addlFilters << QString("pota_ref LIKE '%%1%'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); } else if ( awardSelected == "potaa" ) { - addlFilters << QString("my_pota_ref = '%1'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); + addlFilters << QString("my_pota_ref LIKE = '%%1%'").arg(detailedViewModel->data(detailedViewModel->index(idx.row(),1),Qt::DisplayRole).toString()); } else if ( awardSelected == "sota" ) { diff --git a/ui/AwardsDialog.ui b/ui/AwardsDialog.ui index 0ac83aa0..840b9d80 100644 --- a/ui/AwardsDialog.ui +++ b/ui/AwardsDialog.ui @@ -6,7 +6,7 @@ 0 0 - 1044 + 1016 702 @@ -14,12 +14,45 @@ Awards + + 3 + + + 6 + + + 2 + + + 6 + + + 6 + Options + + 3 + + + 3 + + + 6 + + + 6 + + + 6 + + + 6 + @@ -28,7 +61,14 @@ - + + + + 0 + 0 + + + @@ -38,7 +78,14 @@ - + + + + 0 + 0 + + + @@ -49,6 +96,9 @@ + + 6 + @@ -139,6 +189,12 @@ QAbstractItemView::SingleSelection + + QAbstractItemView::ScrollPerPixel + + + QAbstractItemView::ScrollPerPixel + true @@ -154,6 +210,12 @@ false + + 20 + + + 20 + false From 3f11d0f7c2fb1384e9f4b166d33ed819e475b584 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:53:33 -0500 Subject: [PATCH 08/26] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0d53acad..89d558ef 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ compile_commands.json # QtCreator local machine specific files for imported projects *creator.user* +/build From 01b035179584625a0f1215cc7d3f826954fe8146 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Sun, 18 Aug 2024 23:34:52 -0500 Subject: [PATCH 09/26] Steppir Added Steppir Control Widget --- .DS_Store | Bin 0 -> 10244 bytes QLog.pro | 3 + ui/MainWindow.cpp | 2 + ui/MainWindow.h | 1 + ui/MainWindow.ui | 125 ++++++---- ui/Steppir.cpp | 596 ++++++++++++++++++++++++++++++++++++++++++++++ ui/Steppir.h | 70 ++++++ ui/Steppir.ui | 234 ++++++++++++++++++ 8 files changed, 982 insertions(+), 49 deletions(-) create mode 100644 .DS_Store create mode 100644 ui/Steppir.cpp create mode 100644 ui/Steppir.h create mode 100644 ui/Steppir.ui diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..643dcbc4049a17fdb2381a74d902c5fd18c39170 GIT binary patch literal 10244 zcmeHMU2GIp6u#fI&>1_xv{L?L*_8!sprzXawNS*REkBi3kZtJ?#k$)W+L7r@-I?9; z6STx=G?Msl;u8_kN1{ff#6Z+16D9tnA(2F4^g(>_i5E1Y=gyr4+QJ(~f-}k7Gw0lU z&dmAdJ9qZpWsIRIr`IwTV~ojka;d4*+~DB-{G4(~fkhz+@@H&_W*ZrDWgL} zh(L%yh(L%yh(L(I?SKG%v-u&H3K_N`0wDq+0#^~>^FxeIE|Y;A6VjhLsPUHoB#X)H zA9PLY0N*DT$YdbLg!El0rdT~7a7D1hfN-b&7#~hD8OSjqg*$_AX9(_$V1)wz?&KHq zhchIF4BHTa5P_)(@U?phTge8Q$-L{=?@oq#PGv?c)AbUGbC8OPr%f*@QA$cn_N0cK z(Uh0=a&A*PyPInrj$>sC*XhhI(-`g7W;Z*wmo{x9>pPgbK|}hwOj~zGo1C1jyS{Hq zbSR3f^lS4E9jaYZS6>yYTebRdRqW8(x3R516GC}laHK~aXyu`Eyo_D9v*NS%g{cC$tFVz3Rr|Wl0mn|62aSGhmP;gVC3Q#E z$P;9*tS^KC@r-y8JbRJRndm@p=_sQ~ZZg0*S z)C#j2Sy4p}=?<3w3LZ02t0U!vQ!=iwMVeb=S^M%)e&e>Z>unz~?5mH|yj7Na-Jx{W*gi^=O~Ip0mi-q?cJ8uC zH$5loqw(PDwAAH@`fRige1__vE9QcHX4vjoyWr<>Yws__zKmi6@u) zlEsB!%*R-nT~Gtbf6heMGS)ypUpm-c=CC8|C_BbJWT)8~c9xxE7uZGiJG;#OV1KeJ zD1wS|EW{F2qXr4oVjUW>9viR?9q7a^WUvnwhT*`&VLXYaa0JidMZAQU@haZLalDNa zco!$}F+Ra5e1WglPCO4=-Kk#4h?*ZC+kx(#ac_S#-F%`9_OR) zRpU`@8kLJsm#LLeZ90{TP*+5&qnbn&D%3=@PSuL2{uJMLO|)9oAPZ%!+Nf&9REa{} zpe|B1rU<1e+7i`xUCFna;oq_I>?dOQC3YFpQ3?%FRAMC>h|!y|6|HDPJF&VOJ=l#t z7#PG59w&}_$YT@-a1c-98DjWzcpk6dHN1{Da13t|&rjeTV)=V`A0OaToW>b^hR=Pz zkK;%Dj9(@(xP2mnajC%INngT=!$K`YAVeTUAVeTU;0{HgNaPjc`~RD6{{R0Snthm7 zh(L${M*zhwsg@>waT7cwvd8Frj81;=abrUIF4XWL-0pA3lft*-D+61wo#FQ<1KXI8 ezB~E(?j*%-{=fcbK)C)7*Z>oTYS literal 0 HcmV?d00001 diff --git a/QLog.pro b/QLog.pro index fe93dee5..65e60895 100644 --- a/QLog.pro +++ b/QLog.pro @@ -164,6 +164,7 @@ SOURCES += \ ui/SettingsDialog.cpp \ ui/ShowUploadDialog.cpp \ ui/StatisticsWidget.cpp \ + ui/Steppir.cpp \ ui/SwitchButton.cpp \ ui/WebEnginePage.cpp \ ui/WsjtxFilterDialog.cpp \ @@ -297,6 +298,7 @@ HEADERS += \ ui/QrzDialog.h \ ui/ShowUploadDialog.h \ ui/SplashScreen.h \ + ui/Steppir.h \ ui/StyleItemDelegate.h \ ui/RigWidget.h \ ui/RotatorWidget.h \ @@ -349,6 +351,7 @@ FORMS += \ ui/SettingsDialog.ui \ ui/ShowUploadDialog.ui \ ui/StatisticsWidget.ui \ + ui/Steppir.ui \ ui/WsjtxFilterDialog.ui \ ui/WsjtxWidget.ui diff --git a/ui/MainWindow.cpp b/ui/MainWindow.cpp index e78e5694..dd00b223 100644 --- a/ui/MainWindow.cpp +++ b/ui/MainWindow.cpp @@ -1234,3 +1234,5 @@ MainWindow::~MainWindow() delete ui; } + + diff --git a/ui/MainWindow.h b/ui/MainWindow.h index d458d71a..095da9db 100644 --- a/ui/MainWindow.h +++ b/ui/MainWindow.h @@ -79,6 +79,7 @@ private slots: void saveProfileLayoutGeometry(); void setEquipmentKeepOptions(bool); + private: Ui::MainWindow* ui; QLabel* conditionsLabel; diff --git a/ui/MainWindow.ui b/ui/MainWindow.ui index c946f9b0..2701ec5c 100644 --- a/ui/MainWindow.ui +++ b/ui/MainWindow.ui @@ -7,14 +7,14 @@ 0 0 913 - 558 + 562 - QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::GroupedDragging + QMainWindow::DockOption::AllowNestedDocks|QMainWindow::DockOption::AllowTabbedDocks|QMainWindow::DockOption::AnimatedDocks|QMainWindow::DockOption::GroupedDragging @@ -40,7 +40,7 @@ - Qt::ClickFocus + Qt::FocusPolicy::ClickFocus @@ -52,7 +52,7 @@ 0 0 913 - 22 + 24 @@ -110,6 +110,7 @@ + @@ -156,7 +157,7 @@ false - Qt::ToolButtonIconOnly + Qt::ToolButtonStyle::ToolButtonIconOnly false @@ -194,7 +195,7 @@ - Qt::ClickFocus + Qt::FocusPolicy::ClickFocus @@ -279,10 +280,18 @@ + + + Steppir + + + 2 + + + - - .. + Quit @@ -294,7 +303,7 @@ Ctrl+Q - QAction::QuitRole + QAction::MenuRole::QuitRole true @@ -302,20 +311,18 @@ - - .. + &Settings - QAction::PreferencesRole + QAction::MenuRole::PreferencesRole - - .. + New QSO - Clear @@ -332,8 +339,7 @@ - - .. + &Import @@ -341,8 +347,7 @@ - - .. + &Export @@ -361,20 +366,18 @@ - - .. + &About - QAction::AboutRole + QAction::MenuRole::AboutRole - - .. + New QSO - Save @@ -409,8 +412,7 @@ - - .. + S&tatistics @@ -475,8 +477,7 @@ - - .. + &Awards @@ -530,8 +531,7 @@ - - .. + &Wiki @@ -608,10 +608,10 @@ Ctrl+F - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -628,10 +628,10 @@ Ctrl+M - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -645,10 +645,10 @@ Ctrl+PgDown - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -662,10 +662,10 @@ Ctrl+PgUp - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -679,10 +679,10 @@ Alt+Return - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -696,10 +696,10 @@ Alt+Up - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -713,10 +713,10 @@ Alt+Down - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -730,10 +730,10 @@ Alt+Right - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -747,10 +747,10 @@ Alt+Left - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut - QAction::NoRole + QAction::MenuRole::NoRole true @@ -764,18 +764,23 @@ Alt+\ - Qt::ApplicationShortcut + Qt::ShortcutContext::ApplicationShortcut false - QAction::NoRole + QAction::MenuRole::NoRole true + + + Steppir + + @@ -871,6 +876,12 @@ ui/ProfileImageWidget.h 1 + + Steppir + QWidget + ui/steppir.h + 1 + @@ -1532,6 +1543,22 @@ + + actionSteppir + triggered() + SteppirdockWidget + show() + + + -1 + -1 + + + 881 + 511 + + + settingsChanged() diff --git a/ui/Steppir.cpp b/ui/Steppir.cpp new file mode 100644 index 00000000..2f8adb76 --- /dev/null +++ b/ui/Steppir.cpp @@ -0,0 +1,596 @@ +#include "Steppir.h" +#include "ui_Steppir.h" +#include +#include +#include +#include +#include +#include + +Steppir::Steppir(QWidget *parent) + : QWidget(parent) + , ui(new Ui::Steppir) +{ + ui->setupUi(this); + serial = new QSerialPort(this); + // connect(serial, &QSerialPort::readyRead, this, &Steppir::readData); + // serial->setPortName("/dev/ttyS0"); // Replace with your serial port + // serial->setBaudRate(QSerialPort::Baud19200); + // serial->setDataBits(QSerialPort::Data8); + // serial->setParity(QSerialPort::NoParity); + // serial->setStopBits(QSerialPort::OneStop); + // serial->setFlowControl(QSerialPort::NoFlowControl); + + + socket = new QTcpSocket(this); + socket->connectToHost("192.168.2.136", 4002); + if (socket->state() != QAbstractSocket::ConnectingState && socket->state() != QAbstractSocket::ConnectedState) { + qDebug() << "Connection failed: " << socket->errorString(); + } + + if (socket->waitForConnected(3000)) { + qDebug() << "Connected to Steppir antenna."; + } else { + qDebug() << "Failed to connect to Steppir antenna: " << socket->errorString(); + } + connect(socket, &QTcpSocket::readyRead, this, &Steppir::readData); + connect(socket, &QTcpSocket::connected, this, &Steppir::onConnected); + connect(socket, &QTcpSocket::errorOccurred, this, &Steppir::onError); + + qWarning() << "In Steppir"; + timer = new QTimer; + connect(timer, &QTimer::timeout, this, &Steppir::pollSteppir); + timer->start(500); + +} + +Steppir::~Steppir() +{ + closeSerialPort(); + delete ui; +} + +void Steppir::openSerialPort() { + serial->setPortName("COM1"); // Set the correct COM port + serial->setBaudRate(QSerialPort::Baud19200); + serial->setDataBits(QSerialPort::Data8); + serial->setParity(QSerialPort::NoParity); + serial->setStopBits(QSerialPort::OneStop); + serial->setFlowControl(QSerialPort::NoFlowControl); + + if (serial->open(QIODevice::ReadWrite)) { + qDebug() << "Serial port opened"; + } else { + qDebug() << "Failed to open serial port"; + } +} + +void Steppir::closeSerialPort() { + // if (serial->isOpen()) { + // serial->close(); + // } +} + +void Steppir::onConnected(){ + qDebug() << "Successfully connected to the Steppir Antenna"; +} + +void Steppir::onError(){ + qDebug() << "Connection error " << socket->errorString(); +} + +void Steppir::sendStatusRequest() { + QByteArray command = "?A\r"; + serial->write(command); +} + +void Steppir::sendSetCommand(QString frequency, char direction, char steppircommand) { + QByteArray command; + command.append('@'); // ASCII @ (40 hex) + command.append('A'); // ASCII A (41 hex) + command.append(char(0x00)); // The zero byte + + // Frequency + int freq = frequency.toInt() * 100; // Multiply by 10 as per the specification + command.append((freq >> 16) & 0xFF); // Fh + command.append((freq >> 8) & 0xFF); // Fm + command.append(freq & 0xFF); // Fl + + command.append(char(0x00)); // ac field placeholder (ignored) + command.append(direction);// direction byte, ensure 'direction' is a char or similar type + command.append(steppircommand); // cmd placeholder + command.append(char(0x00)); // cmd placeholder + command.append(0x0D); // End of message with CR + + if (serial->isOpen() || serial->open(QIODevice::ReadWrite)) { + serial->write(command); + serial->flush(); + } else if (socket->state() == QAbstractSocket::ConnectedState) { + // Write the command to the TCP socket + socket->write(command); + socket->flush(); + } + else { + qDebug() << "Failed to open serial or network port."; + } +} + +void Steppir::readData() { + buffer.append(socket->readAll()); + + int index; + while ((index = buffer.indexOf('\r')) != -1) { + QByteArray response = buffer.left(index + 1); + parseResponse(response); // Process the message + buffer.remove(0, index + 1); // Remove the processed bytes from the buffer + } + + // QByteArray responseData = serial->readAll(); + // qDebug() << "Response: " << responseData; + // Parse and process the response data +} + +void Steppir::parseResponse(const QByteArray &response) { + if (response.size() != 11) { + qDebug() << "Invalid response size"; + return; + } + QString resp = response.toHex(); + //qWarning() << "Input Str " << resp; + bool ok; + + // Frequency + int tfrequency = resp.mid(6,6).toUInt(&ok,16); + Frequency = tfrequency / 100.0; + + // Active Motor Flags + bool dvrActive = response[6] & 0x04; + bool dir1Active = response[6] & 0x08; + bool reflActive = response[6] & 0x10; + bool dir2Active = response[6] & 0x20; + + qDebug() << "DVR Active:" << dvrActive; + qDebug() << "DIR1 Active:" << dir1Active; + qDebug() << "Reflector Active:" << reflActive; + qDebug() << "DIR2 Active:" << dir2Active; + + // Direction + switch ((response[7] & 0xe0) >> 5) { + case 0x00: + Direction = "Normal"; + break; + case 0x02: + Direction = "180"; + break; + case 0x04: + Direction = "Bi-directional"; + break; + case 0x03: + Direction = "3/4 wave"; + break; + default: + Direction = "Unknown"; + } + qDebug() << "Direction:" << Direction; + + // Version Number + QString version = QString("%1%2").arg(response[8]).arg(response[9]); + + Tuning = false; + + if (response[6] != 0x00){ + Tuning = true; + } + + quint8 TrackFlag = 0; + TrackFlag = response[7]; + TrackFlag = (TrackFlag & 0b00000100) >> 2; + AutoTracking = TrackFlag; + UpdateForm(); + qDebug() << "Version:" << version; +} + + +void Steppir::UpdateForm() +{ + + QColor colGreen = QColor(Qt::blue); + QString cssGreen = QString("background-color: %1").arg(colGreen.name()); + QColor colYellow = QColor(Qt::yellow); + QString cssYellow = QString("background-color: %1").arg(colYellow.name()); + + ui->frequencyLabel->setText(QString::number(Frequency,'f',2)); + if(Tuning){ + ui->frequencyLabel->setStyleSheet(cssYellow); + }else + { + ui->frequencyLabel->setStyleSheet(""); + } + + if(AutoTracking){ + ui->pushAutoTrack->setStyleSheet(cssGreen); + } + else + { + ui->pushAutoTrack->setStyleSheet(""); + } + + QStringList Bands; + Bands << "6m" << "10m" << "12m" << "15m" << "17m" << "20m" << "30m" << "40m" << "80m"; + + QString curband = BandPlan::freq2Band(Frequency/1000).name; + + if (band != curband){ + band = curband; + ui->pb10_2->setStyleSheet(""); + ui->pb12_2->setStyleSheet(""); + ui->pb15_2->setStyleSheet(""); + ui->pb17_2->setStyleSheet(""); + ui->pb20_2->setStyleSheet(""); + ui->pb30_2->setStyleSheet(""); + ui->pb40_2->setStyleSheet(""); + ui->pb80_2->setStyleSheet(""); + + if (curband == "6m") { + ui->pb6_2->setStyleSheet(cssGreen); + } else if (curband == "10m") { + ui->pb10_2->setStyleSheet(cssGreen); + } else if (curband == "12m") { + ui->pb12_2->setStyleSheet(cssGreen); + } else if (curband == "15m") { + ui->pb15_2->setStyleSheet(cssGreen); + } else if (curband == "17m") { + ui->pb17_2->setStyleSheet(cssGreen); + } else if (curband == "20m") { + ui->pb20_2->setStyleSheet(cssGreen); + } else if (curband == "30m") { + ui->pb30_2->setStyleSheet(cssGreen); + } else if (curband == "40m") { + ui->pb40_2->setStyleSheet(cssGreen); + } else if (curband == "80m") { + ui->pb80_2->setStyleSheet(cssGreen); + } + } + if(Direction != OldDirection){ + ui->buttonNormal->setStyleSheet(""); + ui->butonReverse->setStyleSheet(""); + ui->buttonBi->setStyleSheet(""); + OldDirection = Direction; + if ( Direction == "Normal") { + ui->buttonNormal->setStyleSheet(cssGreen); + } else if (Direction == "180") { + ui->butonReverse->setStyleSheet(cssGreen); + } else if (Direction =="Bi-directional") { + ui->buttonBi->setStyleSheet(cssGreen); + } + } +} + +void Steppir::pollSteppir() +{ + QByteArray command; + command.append('?'); // Send the status request command + command.append('A'); + command.append(char(0x0D)); // Append CR (0x0D) + + // Write the command to the serial port + if (serial->isOpen() || serial->open(QIODevice::ReadWrite)) { + serial->write(command); + serial->flush(); + } else if (socket->state() == QAbstractSocket::ConnectedState) { + // Write the command to the TCP socket + socket->write(command); + socket->flush(); + } + else { + qDebug() << "Failed to open serial port."; + } +} + + + +void Steppir::on_buttonNormal_clicked() +{ + sendSetCommand(QString::number(Frequency),char(0x00),char(0x00)); +} + + +void Steppir::on_butonReverse_clicked() +{ + sendSetCommand(QString::number(Frequency),char(0x40),char(0x00)); +} + + +void Steppir::on_buttonBi_clicked() +{ + sendSetCommand(QString::number(Frequency),char(0x80),char(0x00)); +} + + +void Steppir::on_buttonRetract_clicked() +{ + sendSetCommand(QString::number(Frequency),char(0x00),char(0x53)); +} + + +void Steppir::on_buttonLeftFast_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + //if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(Frequency-100),dir,char(0x00)); +} + + +void Steppir::on_butonLeftSlow_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + //if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(Frequency-25),dir,char(0x00)); +} + + +void Steppir::on_pushAutoTrack_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + if(AutoTracking){ + sendSetCommand(QString::number(Frequency),dir,char(0x55)); + + } else { + sendSetCommand(QString::number(Frequency),dir,char(0x52)); + } +} + + +void Steppir::on_buttonRightSlow_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + //if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(Frequency+25),dir,char(0x00)); +} + + +void Steppir::on_buttonRightFast_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + //if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(Frequency+100),dir,char(0x00)); +} + + +void Steppir::on_pb80_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(3500),dir,char(0x00)); +} + + +void Steppir::on_pb40_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(7000),dir,char(0x00)); + +} + + +void Steppir::on_pb30_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(10100),dir,char(0x00)); + +} + + +void Steppir::on_pb20_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(14000),dir,char(0x00)); + +} + + +void Steppir::on_pb17_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + //if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(18068),dir,char(0x00)); + +} + + +void Steppir::on_pb15_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(21000),dir,char(0x00)); + +} + + +void Steppir::on_pb12_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(24890),dir,char(0x00)); + +} + + +void Steppir::on_pb10_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(28000),dir,char(0x00)); + +} + + +void Steppir::on_pb6_2_clicked() +{ + char dir = char(0x00); + + if ( Direction == "Normal") { + dir = char(0x00); + } else if (Direction == "180") { + dir = char(0x40); + } else if (Direction =="Bi-directional") { + dir = char(0x80); + } + + // if(AutoTracking){ + // sendSetCommand(QString::number(Frequency),dir,char(0x55)); + // } + sendSetCommand(QString::number(50000),dir,char(0x00)); + +} + + +void Steppir::on_buttonCalibrate_clicked() +{ + sendSetCommand(QString::number(Frequency),char(0x00),char(0x56)); +} + diff --git a/ui/Steppir.h b/ui/Steppir.h new file mode 100644 index 00000000..294bcd41 --- /dev/null +++ b/ui/Steppir.h @@ -0,0 +1,70 @@ +#ifndef STEPPIR_H +#define STEPPIR_H + +#include +#include +#include +#include +#include +#include +#include > + +namespace Ui { +class Steppir; +} + +class Steppir : public QWidget +{ + Q_OBJECT + +public: + explicit Steppir(QWidget *parent = nullptr); + ~Steppir(); + void openSerialPort(); + void closeSerialPort(); + void sendStatusRequest(); + void sendSetCommand(QString frequency, char direction, char steppircommand); + +private slots: + void readData(); + void parseResponse(const QByteArray &response); + void pollSteppir(); + void onConnected(); + void onError(); + void UpdateForm(); + void on_buttonNormal_clicked(); + void on_butonReverse_clicked(); + void on_buttonBi_clicked(); + void on_buttonRetract_clicked(); + void on_buttonLeftFast_clicked(); + void on_butonLeftSlow_clicked(); + void on_pushAutoTrack_clicked(); + void on_buttonRightSlow_clicked(); + void on_buttonRightFast_clicked(); + void on_pb80_2_clicked(); + void on_pb40_2_clicked(); + void on_pb30_2_clicked(); + void on_pb20_2_clicked(); + void on_pb17_2_clicked(); + void on_pb15_2_clicked(); + void on_pb12_2_clicked(); + void on_pb10_2_clicked(); + void on_pb6_2_clicked(); + + void on_buttonCalibrate_clicked(); + +private: + Ui::Steppir *ui; + QSerialPort *serial; + QTcpSocket *socket; + QTimer *timer; + QByteArray buffer; + double Frequency; + QString Direction; + QString OldDirection; + bool AutoTracking; + bool Tuning; + QString band; +}; + +#endif // STEPPIR_H diff --git a/ui/Steppir.ui b/ui/Steppir.ui new file mode 100644 index 00000000..3470419a --- /dev/null +++ b/ui/Steppir.ui @@ -0,0 +1,234 @@ + + + Steppir + + + + 0 + 0 + 325 + 130 + + + + + 325 + 130 + + + + Form + + + + + 10 + 0 + 231 + 31 + + + + + 18 + true + + + + 0.000 + + + Qt::AlignmentFlag::AlignCenter + + + + + + 0 + 30 + 321 + 32 + + + + + 0 + + + + + 80 + + + false + + + + + + + 40 + + + + + + + 30 + + + + + + + 20 + + + + + + + 17 + + + + + + + 15 + + + + + + + 12 + + + + + + + 10 + + + + + + + 6 + + + + + + + + + 0 + 60 + 321 + 32 + + + + + 0 + + + + + Normal + + + + + + + Reverse + + + + + + + Bi-Dir + + + + + + + Home + + + + + + + + + 0 + 90 + 321 + 32 + + + + + 0 + + + + + << + + + + + + + < + + + + + + + Autotrack + + + + + + + > + + + + + + + >> + + + + + + + + + 240 + 0 + 80 + 32 + + + + Calibrate + + + + + + From 98dff70936a00cd984a709a4f609eba0e3ded100 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Mon, 19 Aug 2024 09:10:06 -0500 Subject: [PATCH 10/26] trybuild --- .DS_Store | Bin 10244 -> 10244 bytes .github/workflows/macOSBuild.yml | 12 +----------- entitlements.xml | 8 ++++++++ 3 files changed, 9 insertions(+), 11 deletions(-) create mode 100644 entitlements.xml diff --git a/.DS_Store b/.DS_Store index 643dcbc4049a17fdb2381a74d902c5fd18c39170..6674d2c2ac66dbd828c8cabe4be514a60e7611b2 100644 GIT binary patch delta 14 VcmZn(XbITxSAdam^FIMLaR4n61x5e> delta 14 VcmZn(XbITxSAdaW^FIMLaR4n01w{Y= diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 7340a250..79d5c02e 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -51,18 +51,8 @@ jobs: - name: Build dmg run: | cd build + macdeployqt qlog.app -executable=./qlog.app/Contents/MacOS/qlog macdeployqt qlog.app - cp `brew --prefix`/lib/libhamlib.dylib qlog.app/Contents/Frameworks/libhamlib.dylib - cp `brew --prefix`/lib/libqt6keychain.dylib qlog.app/Contents/Frameworks/libqt6keychain.dylib - cp `brew --prefix`/lib/libdbus-1.dylib qlog.app/Contents/Frameworks/libdbus-1.dylib - cp `brew --prefix brotli`/lib/libbrotlicommon.1.dylib qlog.app/Contents/Frameworks/libbrotlicommon.1.dylib - cp `brew --prefix`/opt/icu4c/lib/libicui18n.74.dylib qlog.app/Contents/Frameworks/libicui18n.74.dylib - install_name_tool -change `brew --prefix`/lib/libhamlib.dylib @executable_path/../Frameworks/libhamlib.dylib qlog.app/Contents/MacOS/qlog - install_name_tool -change `brew --prefix`/lib/libqt6keychain.dylib @executable_path/../Frameworks/libqt6keychain.dylib qlog.app/Contents/MacOS/qlog - install_name_tool -change @loader_path/libbrotlicommon.1.dylib @executable_path/../Frameworks/libbrotlicommon.1.dylib qlog.app/Contents/MacOS/qlog - install_name_tool -change /usr/local/opt/icu4c/lib/libicui18n.74.dylib @executable_path/../Frameworks/libicui18n.74.dylib qlog.app/Contents/MacOS/qlog - otool -L qlog.app/Contents/MacOS/qlog - macdeployqt qlog.app -dmg - name: Copy artifact uses: actions/upload-artifact@v4 with: diff --git a/entitlements.xml b/entitlements.xml new file mode 100644 index 00000000..5e873f01 --- /dev/null +++ b/entitlements.xml @@ -0,0 +1,8 @@ + + + + +com.apple.security.cs.disable-executable-page-protection + + + From 26b022780605f36ea29ef0352f65b755d703c639 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Mon, 19 Aug 2024 09:23:44 -0500 Subject: [PATCH 11/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 79d5c02e..dad58ea3 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -13,7 +13,7 @@ jobs: name: MacOS Build strategy: matrix: - os: [macos-12, macos-13] + os: [macos-13] runs-on: ${{ matrix.os }} @@ -52,7 +52,7 @@ jobs: run: | cd build macdeployqt qlog.app -executable=./qlog.app/Contents/MacOS/qlog - macdeployqt qlog.app + macdeployqt qlog.app -dmg - name: Copy artifact uses: actions/upload-artifact@v4 with: From c174ca06d6050a370c466f4e7ce0b35d24d019ce Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Thu, 22 Aug 2024 08:35:47 -0500 Subject: [PATCH 12/26] alert widget spacing --- .DS_Store | Bin 10244 -> 10244 bytes devtools/.DS_Store | Bin 0 -> 6148 bytes ui/AlertWidget.ui | 25 +++++++++++++++++-------- 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 devtools/.DS_Store diff --git a/.DS_Store b/.DS_Store index 6674d2c2ac66dbd828c8cabe4be514a60e7611b2..d9f6b7946d9cd1b23b58e3d17d226d9c7a69992c 100644 GIT binary patch delta 250 zcmZn(XbG6$&&a`k#ghev8c@|4W2h+$F3QWv&r4@uU|a)9O)VVYu!MHPlQ qIY2k0Go%5@B8FU`X(gEE2y+5$KvT8(ub?>hW_E>NESvd+n3(}61UfMQ delta 46 zcmV+}0MY-1P=rvBPXP(BP`eKS39}3ko&l4D6-blv5gN1q6bK8kfb#;g2O#S5T0$TNhm@O3VK`cS}?XyC|*LXFJMFuDm9@+gE1>jY7eE5yS|Vw;`2DO zyA?|nJc-yDnEhtwC(C{bJ6Qk_y~*$ppaB3bDq+RL;R~TS>55dWhfwHe;=RyHvh#-Sc?=MbOjIr1FF-`Kq_uoXNTHDxk9M7pc*WsO-hDB6N@?JE) zq}iELX}qwb_&ga+2aWAxl@(EvjmEkl8ICaJ>LSU8YT8qiY?$lX&;&fs^#+Z-*{t2_ zbepo}`}3xpbz6Q@b~^3(+;eyK4~|X;_vu5Xo(-D#>&Q?!f}?W>=t8- zx4;SS$_dqXP%}eWZAekOXbIOAtzn zfyL4wMo@$)MKqlf#^>0Tg}tE&y*m1(P6rVfI ZLBAveF|b$~L=Ou82xuC3U - Qt::ClickFocus + Qt::FocusPolicy::ClickFocus - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers false @@ -35,23 +35,32 @@ true - QAbstractItemView::SingleSelection + QAbstractItemView::SelectionMode::SingleSelection - QAbstractItemView::SelectRows + QAbstractItemView::SelectionBehavior::SelectRows - QAbstractItemView::ScrollPerPixel + QAbstractItemView::ScrollMode::ScrollPerPixel - QAbstractItemView::ScrollPerPixel + QAbstractItemView::ScrollMode::ScrollPerPixel + + 24 + false true + + 20 + + + 20 + @@ -79,7 +88,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -92,7 +101,7 @@ - Qt::ClickFocus + Qt::FocusPolicy::ClickFocus Clear All From 897056bb2c878c0d06cb3ce41e9751baaaba8241 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Fri, 23 Aug 2024 22:31:54 -0500 Subject: [PATCH 13/26] Added more Steppir integrations --- .DS_Store | Bin 10244 -> 10244 bytes ui/MainWindow.cpp | 23 ++++ ui/MainWindow.h | 1 + ui/MainWindow.ui | 80 ++++++++---- ui/SettingsDialog.cpp | 83 ++++++++++++ ui/SettingsDialog.h | 13 ++ ui/SettingsDialog.ui | 285 +++++++++++++++++++++++++++++++++++++++--- ui/Steppir.cpp | 127 +++++++++++++------ ui/Steppir.h | 7 ++ 9 files changed, 533 insertions(+), 86 deletions(-) diff --git a/.DS_Store b/.DS_Store index d9f6b7946d9cd1b23b58e3d17d226d9c7a69992c..95e6014f674933bfb8e317e13e5b68bb44543b32 100644 GIT binary patch delta 356 zcmZn(XbG6$&&azmU^hP_?`9qWVaCloLd?u!JCX`=GK)(L46ZRUF|)9;v2(CAvvYFu^1CLV7nEo0 z-h5JY2D50qfKXXxYPo+wNoIataad|mF_4~|C0QvIk(r#I7o1s@D#CyY7&kLYu`@DF zJusO|TDD%e?jV;|!L#)*ux80Rp~Wt_*joN=WJ<0{5AjB6RUG45d8$+(O0Fym3iV~i&l lPcoijyv%rq@hRgg#@CxKNt?1vYK2*^;7UB`@15Zodw z=Ix>}7k89rE$UvRW~k7(r>7_VC}$#F>PS~UB> z!6q4Y*kz9#1@<}MkRwj0aLO6yTvDY*ohv-9x#5;O?rHEqlNOIW@yrWt-gxJeFA@Dc UmGJ36^v`Du5Cg#R(5o}@4=52qiU0rr diff --git a/ui/MainWindow.cpp b/ui/MainWindow.cpp index dd00b223..ae7e6f38 100644 --- a/ui/MainWindow.cpp +++ b/ui/MainWindow.cpp @@ -423,6 +423,19 @@ void MainWindow::rigErrorHandler(const QString &error, const QString &errorDetai ui->actionConnectRig->setChecked(false); } +void MainWindow::steppirConnect() +{ + FCT_IDENTIFICATION; + if ( ui->actionConnect_Steppir->isChecked() ) + { + ui->SteppirDock->open(); + } + else + { + ui->SteppirDock->close(); + } +} + void MainWindow::rotErrorHandler(const QString &error, const QString &errorDetail) { FCT_IDENTIFICATION; @@ -734,6 +747,7 @@ void MainWindow::saveEquipmentConnOptions() settings.setValue("equipment/rigconnected", ui->actionConnectRig->isChecked()); settings.setValue("equipment/rotconnected", ui->actionConnectRotator->isChecked()); settings.setValue("equipment/cwkeyconnected", ui->actionConnectCWKeyer->isChecked()); + settings.setValue("equipment/steppirconnected",ui->actionConnect_Steppir->isChecked()); } } @@ -771,6 +785,15 @@ void MainWindow::restoreConnectionStates() ui->actionConnectCWKeyer->setChecked(true); }); } + + if ( settings.value("equipment/steppirconnected", false).toBool() ) + { + QTimer::singleShot(3000, this, [this]() + { + if ( !ui->actionConnect_Steppir->isChecked() ) + ui->actionConnect_Steppir->setChecked(true); + }); + } } } diff --git a/ui/MainWindow.h b/ui/MainWindow.h index 095da9db..43618628 100644 --- a/ui/MainWindow.h +++ b/ui/MainWindow.h @@ -46,6 +46,7 @@ public slots: private slots: void rigConnect(); void rotConnect(); + void steppirConnect(); void cwKeyerConnect(); void cwKeyerConnectProfile(QString); void cwKeyerDisconnectProfile(QString); diff --git a/ui/MainWindow.ui b/ui/MainWindow.ui index 2701ec5c..4576b711 100644 --- a/ui/MainWindow.ui +++ b/ui/MainWindow.ui @@ -14,7 +14,7 @@ - QMainWindow::DockOption::AllowNestedDocks|QMainWindow::DockOption::AllowTabbedDocks|QMainWindow::DockOption::AnimatedDocks|QMainWindow::DockOption::GroupedDragging + QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::GroupedDragging @@ -40,7 +40,7 @@ - Qt::FocusPolicy::ClickFocus + Qt::ClickFocus @@ -83,6 +83,7 @@ + @@ -157,7 +158,7 @@ false - Qt::ToolButtonStyle::ToolButtonIconOnly + Qt::ToolButtonIconOnly false @@ -195,7 +196,7 @@ - Qt::FocusPolicy::ClickFocus + Qt::ClickFocus @@ -303,7 +304,7 @@ Ctrl+Q - QAction::MenuRole::QuitRole + QAction::QuitRole true @@ -317,7 +318,7 @@ &Settings - QAction::MenuRole::PreferencesRole + QAction::PreferencesRole @@ -372,7 +373,7 @@ &About - QAction::MenuRole::AboutRole + QAction::AboutRole @@ -608,10 +609,10 @@ Ctrl+F - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -628,10 +629,10 @@ Ctrl+M - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -645,10 +646,10 @@ Ctrl+PgDown - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -662,10 +663,10 @@ Ctrl+PgUp - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -679,10 +680,10 @@ Alt+Return - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -696,10 +697,10 @@ Alt+Up - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -713,10 +714,10 @@ Alt+Down - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -730,10 +731,10 @@ Alt+Right - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -747,10 +748,10 @@ Alt+Left - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut - QAction::MenuRole::NoRole + QAction::NoRole true @@ -764,13 +765,13 @@ Alt+\ - Qt::ShortcutContext::ApplicationShortcut + Qt::ApplicationShortcut false - QAction::MenuRole::NoRole + QAction::NoRole true @@ -781,6 +782,14 @@ Steppir + + + true + + + Connect Steppir + + @@ -1559,6 +1568,22 @@ + + actionConnect_Steppir + toggled(bool) + MainWindow + steppirConnect() + + + -1 + -1 + + + 456 + 280 + + + settingsChanged() @@ -1569,6 +1594,7 @@ exportLog() showAbout() rigConnect() + steppirConnect() showStatistics() showLotw() rotConnect() diff --git a/ui/SettingsDialog.cpp b/ui/SettingsDialog.cpp index 21cc84c9..5ccd5183 100644 --- a/ui/SettingsDialog.cpp +++ b/ui/SettingsDialog.cpp @@ -87,6 +87,9 @@ SettingsDialog::SettingsDialog(MainWindow *parent) : ui->rigPortTypeCombo->addItem(tr("Network")); ui->rigPortTypeCombo->addItem(tr("Special - Omnirig")); + ui->steppirPortTypeCombo->addItem(tr("Serial")); + ui->steppirPortTypeCombo->addItem(tr("Network")); + #ifdef QLOG_FLATPAK ui->lotwTextMessage->setVisible(true); ui->tqslPathEdit->setVisible(false); @@ -2279,6 +2282,17 @@ void SettingsDialog::readSettings() { ui->notifWSJTXCQSpotsEdit->setText(NetworkNotification::getNotifWSJTXCQSpotAddrs()); ui->notifSpotAlertEdit->setText(NetworkNotification::getNotifSpotAlertAddrs()); + /***********/ + /* STEPPIR */ + /***********/ + ui->steppirBaudSelect->setCurrentIndex(settings.value("steppir/baud").toInt()); + ui->steppirHostNameEdit->setText(settings.value("steppir/hostname").toString()); + ui->steppirPortTypeCombo->setCurrentIndex(settings.value("steppir/portype").toInt()); + ui->steppirPollIntervalSpinBox->setValue(settings.value("steppir/poll").toInt()); + ui->steppirPortEdit->setText(settings.value("steppir/portedit").toString()); + ui->steppirNetPortSpin->setValue(settings.value("steppir/netport").toInt()); + + /******************/ /* END OF Reading */ /******************/ @@ -2388,6 +2402,17 @@ void SettingsDialog::writeSettings() { Wsjtx::saveConfigMulticastAddress(ui->wsjtMulticastAddressEdit->text()); Wsjtx::saveConfigMulticastTTL(ui->wsjtMulticastTTLSpin->value()); + /***********/ + /* STEPPIR */ + /***********/ + settings.setValue("steppir/baud",ui->steppirBaudSelect->currentIndex()); + settings.setValue("steppir/hostname",ui->steppirHostNameEdit->text()); + settings.setValue("steppir/portype",ui->steppirPortTypeCombo->currentIndex()); + settings.setValue("steppir/poll",ui->steppirPollIntervalSpinBox->value()); + settings.setValue("steppir/portedit",ui->steppirPortEdit->text()); + settings.setValue("steppir/netport",ui->steppirNetPortSpin->value()); + settings.setValue("steppir/baudrate",ui->steppirBaudSelect->currentText()); + NetworkNotification::saveNotifQSOAdiAddrs(ui->notifQSOEdit->text()); NetworkNotification::saveNotifDXSpotAddrs(ui->notifDXSpotsEdit->text()); NetworkNotification::saveNotifWSJTXCQSpotAddrs(ui->notifWSJTXCQSpotsEdit->text()); @@ -2627,3 +2652,61 @@ SettingsDialog::~SettingsDialog() { iotaCompleter->deleteLater(); delete ui; } + +void SettingsDialog::on_steppirPollIntervalSpinBox_valueChanged(int arg1) +{ + +} + + +void SettingsDialog::on_steppirPortTypeCombo_currentIndexChanged(int index) +{ + FCT_IDENTIFICATION; + qWarning() << "steppirPortTypeCombo " << index; + + switch (index) + { + // Serial + case RIGPORT_SERIAL_INDEX: + { + ui->steppirStackedWidget->setCurrentIndex(STACKED_WIDGET_SERIAL_SETTING); + ui->steppirHostNameEdit->clear(); + } + break; + + // Network + case RIGPORT_NETWORK_INDEX: + ui->steppirStackedWidget->setCurrentIndex(STACKED_WIDGET_NETWORK_SETTING); + ui->steppirPortEdit->clear(); + ui->steppirNetPortSpin->setValue(RIG_NET_DEFAULT_PORT); + break; + + default: + qWarning() << "Unsupported Network Port" << index; + } +} + + +void SettingsDialog::on_steppirPortEdit_textChanged(const QString &arg1) +{ + +} + + +void SettingsDialog::on_steppirBaudSelect_currentIndexChanged(int index) +{ + +} + + +void SettingsDialog::on_steppirHostNameEdit_textChanged(const QString &arg1) +{ + +} + + +void SettingsDialog::on_steppirNetPortSpin_valueChanged(int arg1) +{ + +} + diff --git a/ui/SettingsDialog.h b/ui/SettingsDialog.h index cd90835a..66523de4 100644 --- a/ui/SettingsDialog.h +++ b/ui/SettingsDialog.h @@ -115,6 +115,19 @@ public slots: void hrdlogSettingChanged(); void clublogSettingChanged(); +private slots: + void on_steppirPollIntervalSpinBox_valueChanged(int arg1); + + void on_steppirPortTypeCombo_currentIndexChanged(int index); + + void on_steppirPortEdit_textChanged(const QString &arg1); + + void on_steppirBaudSelect_currentIndexChanged(int index); + + void on_steppirHostNameEdit_textChanged(const QString &arg1); + + void on_steppirNetPortSpin_valueChanged(int arg1); + private: void readSettings(); void writeSettings(); diff --git a/ui/SettingsDialog.ui b/ui/SettingsDialog.ui index 5ec4f124..b5acf9b9 100644 --- a/ui/SettingsDialog.ui +++ b/ui/SettingsDialog.ui @@ -27,7 +27,7 @@ - 0 + 1 false @@ -523,17 +523,17 @@ - - + + - Add + Delete - - + + - Delete + Add @@ -557,17 +557,267 @@ - - - Qt::Vertical - - + + - 20 - 40 + 0 + 120 - + + Steppir Controller + + + + + 130 + 50 + 389 + 61 + + + + + 0 + 0 + + + + QFrame::NoFrame + + + 0 + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + 6 + + + 4 + + + 0 + + + 2 + + + 0 + + + 0 + + + + + Port + + + + + + + + 0 + 0 + + + + Use COMxx for Window or path to COM port under Unix-like OS + + + + + + + + + + + 0 + 0 + + + + Baudrate + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + 115200 + + + + + 57600 + + + + + 38400 + + + + + 19200 + + + + + 9600 + + + + + 4800 + + + + + 2400 + + + + + 1200 + + + + + + + + + + 6 + + + 2 + + + 0 + + + 2 + + + 0 + + + 0 + + + + + Host Name + + + + + + + 10 + + + + + + + + Port + + + + + + + + + + 1 + + + 65535 + + + 4532 + + + + + + + + + + + + + 130 + 20 + 391 + 32 + + + + + + + Poll Interval + + + + + + + + 0 + 0 + + + + ms + + + 100 + + + 60000 + + + 500 + + + + + + + Connection Type + + + + + + + + + @@ -2909,7 +3159,7 @@ - + Qt::Vertical @@ -3443,8 +3693,7 @@ Browse - - .. + diff --git a/ui/Steppir.cpp b/ui/Steppir.cpp index 2f8adb76..fa2deb10 100644 --- a/ui/Steppir.cpp +++ b/ui/Steppir.cpp @@ -6,69 +6,111 @@ #include #include #include +#include Steppir::Steppir(QWidget *parent) : QWidget(parent) , ui(new Ui::Steppir) { + ui->setupUi(this); + + socket = new QTcpSocket(this); serial = new QSerialPort(this); - // connect(serial, &QSerialPort::readyRead, this, &Steppir::readData); - // serial->setPortName("/dev/ttyS0"); // Replace with your serial port - // serial->setBaudRate(QSerialPort::Baud19200); - // serial->setDataBits(QSerialPort::Data8); - // serial->setParity(QSerialPort::NoParity); - // serial->setStopBits(QSerialPort::OneStop); - // serial->setFlowControl(QSerialPort::NoFlowControl); - socket = new QTcpSocket(this); - socket->connectToHost("192.168.2.136", 4002); - if (socket->state() != QAbstractSocket::ConnectingState && socket->state() != QAbstractSocket::ConnectedState) { - qDebug() << "Connection failed: " << socket->errorString(); +} + +Steppir::~Steppir() +{ + closeSerialPort(); + delete ui; +} + +void Steppir::open() +{ + QSettings settings; + baud = settings.value("steppir/baudrate").toString() ; + serialport = settings.value("steppir/portedit").toString(); + networkport = settings.value("steppir/netport").toInt(); + networkhost = settings.value("steppir/hostname").toString(); + pollint = settings.value("steppir/poll").toInt(); + + + + if (serialport.length() > 5 ) + { + connect(serial, &QSerialPort::readyRead, this, &Steppir::readData); + openSerialPort(); } - if (socket->waitForConnected(3000)) { - qDebug() << "Connected to Steppir antenna."; - } else { - qDebug() << "Failed to connect to Steppir antenna: " << socket->errorString(); + if (networkhost.length() > 5){ + socket->connectToHost(networkhost, networkport); + if (socket->state() != QAbstractSocket::ConnectingState && socket->state() != QAbstractSocket::ConnectedState) { + qDebug() << "Connection failed: " << socket->errorString(); + } + + if (socket->waitForConnected(3000)) { + qDebug() << "Connected to Steppir antenna."; + } else { + qDebug() << "Failed to connect to Steppir antenna: " << socket->errorString(); + } + connect(socket, &QTcpSocket::readyRead, this, &Steppir::readData); + connect(socket, &QTcpSocket::connected, this, &Steppir::onConnected); + connect(socket, &QTcpSocket::errorOccurred, this, &Steppir::onError); } - connect(socket, &QTcpSocket::readyRead, this, &Steppir::readData); - connect(socket, &QTcpSocket::connected, this, &Steppir::onConnected); - connect(socket, &QTcpSocket::errorOccurred, this, &Steppir::onError); - qWarning() << "In Steppir"; timer = new QTimer; connect(timer, &QTimer::timeout, this, &Steppir::pollSteppir); - timer->start(500); + if (serial->isOpen() || serial->open(QIODevice::ReadWrite)) { + timer->start(pollint); + } else if (socket->state() == QAbstractSocket::ConnectedState) { + timer->start(pollint); + } } -Steppir::~Steppir() +void Steppir::close() { - closeSerialPort(); - delete ui; + if (serial->isOpen() || serial->open(QIODevice::ReadWrite)) { + serial->close(); + } else if (socket->state() == QAbstractSocket::ConnectedState) { + socket->close(); + } + else { + qDebug() << "Failed to open serial or network port."; + } } void Steppir::openSerialPort() { - serial->setPortName("COM1"); // Set the correct COM port - serial->setBaudRate(QSerialPort::Baud19200); - serial->setDataBits(QSerialPort::Data8); - serial->setParity(QSerialPort::NoParity); - serial->setStopBits(QSerialPort::OneStop); - serial->setFlowControl(QSerialPort::NoFlowControl); - - if (serial->open(QIODevice::ReadWrite)) { - qDebug() << "Serial port opened"; - } else { - qDebug() << "Failed to open serial port"; + qDebug() << "In openSerialPort"; + foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { + if(serialport ==info.systemLocation()) { + serial->setPortName(serialport); // Set the correct COM port + serial->setBaudRate(baud.toInt()); + serial->setDataBits(QSerialPort::Data8); + serial->setParity(QSerialPort::NoParity); + serial->setStopBits(QSerialPort::OneStop); + serial->setFlowControl(QSerialPort::NoFlowControl); + + if (serial->open(QIODevice::ReadWrite)) { + qDebug() << "Serial port opened"; + } else { + serial->close(); + qDebug() << serial->errorString(); + qDebug() << "Failed to open serial port"; + } + } + } + + } void Steppir::closeSerialPort() { - // if (serial->isOpen()) { - // serial->close(); - // } + if (serial->isOpen()) { + serial->close(); + } } void Steppir::onConnected(){ @@ -116,7 +158,12 @@ void Steppir::sendSetCommand(QString frequency, char direction, char steppircomm } void Steppir::readData() { - buffer.append(socket->readAll()); + if (serial->isOpen() || serial->open(QIODevice::ReadWrite)) { + buffer.append(serial->readAll()); + } else if (socket->state() == QAbstractSocket::ConnectedState) { + buffer.append(socket->readAll()); + } + int index; while ((index = buffer.indexOf('\r')) != -1) { @@ -136,7 +183,6 @@ void Steppir::parseResponse(const QByteArray &response) { return; } QString resp = response.toHex(); - //qWarning() << "Input Str " << resp; bool ok; // Frequency @@ -278,12 +324,11 @@ void Steppir::pollSteppir() serial->write(command); serial->flush(); } else if (socket->state() == QAbstractSocket::ConnectedState) { - // Write the command to the TCP socket socket->write(command); socket->flush(); } else { - qDebug() << "Failed to open serial port."; + qDebug() << "Steppir - Nothing is open"; } } diff --git a/ui/Steppir.h b/ui/Steppir.h index 294bcd41..7ba3814a 100644 --- a/ui/Steppir.h +++ b/ui/Steppir.h @@ -24,6 +24,8 @@ class Steppir : public QWidget void closeSerialPort(); void sendStatusRequest(); void sendSetCommand(QString frequency, char direction, char steppircommand); + void open(); + void close(); private slots: void readData(); @@ -65,6 +67,11 @@ private slots: bool AutoTracking; bool Tuning; QString band; + QString baud; + QString serialport; + int networkport; + QString networkhost; + int pollint; }; #endif // STEPPIR_H From 091ebd29b1931a985493529f7535e1e2ddb9c936 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:04:28 -0500 Subject: [PATCH 14/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index dad58ea3..0ef9bb74 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -37,6 +37,20 @@ jobs: with: fetch-depth: 0 submodules: recursive + - name: Checkout Code + uses: actions/checkout@v4 + with: + repository: hamlib/hamlib + path: ./hamlib + + - name: Configure and compile + run: | + cd ./hamlib + ./bootstrap + ./configure --prefix=/Users/runner/work/QLog/QLog/hamlib + make -j 4 + make check + make install - name: Get version from tag run : | TAGVERSION=$(git describe --tags) @@ -46,7 +60,7 @@ jobs: run: | mkdir build cd build - qmake -config release .. + qmake "HAMLIBINCLUDEPATH = /Users/runner/work/QLog/QLog/hamlib/include" "HAMLIBLIBPATH = /Users/runner/work/QLog/QLog/hamlib/lib" -config release .. make -j4 - name: Build dmg run: | From ead65b82c4b6ca928bbfc6516993326a3674da37 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:10:34 -0500 Subject: [PATCH 15/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 0ef9bb74..18ad14ce 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -32,6 +32,11 @@ jobs: brew install brotli brew install icu4c brew install pkg-config + brew install automake + brew install autoconf + brew install libtool + brew install libusb-compat + - name: Checkout Code uses: actions/checkout@v4 with: From dc0efdf058d395b5db796e09c58973649129310d Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:28:26 -0500 Subject: [PATCH 16/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 18ad14ce..e1a89ed4 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -65,7 +65,7 @@ jobs: run: | mkdir build cd build - qmake "HAMLIBINCLUDEPATH = /Users/runner/work/QLog/QLog/hamlib/include" "HAMLIBLIBPATH = /Users/runner/work/QLog/QLog/hamlib/lib" -config release .. + qmake "HAMLIBINCLUDEPATH = /Users/runner/work/QLog/QLog/hamlib/include" "HAMLIBLIBPATH = /Users/runner/work/QLog/QLog/hamlib/lib" "HAMLIBVERSION_MAJOR = 4" "HAMLIBVERSION_MINOR = 6" "HAMLIBVERSION_PATCH = 0" -config release .. make -j4 - name: Build dmg run: | From 5b8f85b07f9dc179f0940df1c60aa61b0137a6b1 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:44:32 -0500 Subject: [PATCH 17/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 103 ++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index e1a89ed4..9abdd85d 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -71,7 +71,108 @@ jobs: run: | cd build macdeployqt qlog.app -executable=./qlog.app/Contents/MacOS/qlog - macdeployqt qlog.app -dmg + #macdeployqt qlog.app -dmg + - name: Codesign app bundle + # Extract the secrets we defined earlier as environment variables + env: + MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} + run: | + # Turn our base64-encoded certificate back to a regular .p12 file + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + # We need to create a new keychain, otherwise using the certificate will prompt + # with a UI dialog asking for the certificate password, which we can't + # use in a headless CI environment + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + # We finally codesign our app bundle, specifying the Hardened runtime option + /usr/bin/codesign --timestamp -s "$MACOS_CERTIFICATE_NAME" --options runtime --deep -f /Users/runner/work/QLog/QLog/build/qlog.app + - name: "Notarize app bundle" + # Extract the secrets we defined earlier as environment variables + env: + PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} + PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} + run: | + # Store the notarization credentials so that we can prevent a UI password dialog + # from blocking the CI + + echo "Create keychain profile" + xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD" + + echo "Creating temp notarization archive" + ditto -c -k --keepParent "/Users/runner/work/QLog/QLog/build/qlog.app" "notarization.zip" + + # Here we send the notarization request to the Apple's Notarization service, waiting for the result. + # This typically takes a few seconds inside a CI environment, but it might take more depending on the App + # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if + # you're curious + + echo "Notarize app" + xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait + + echo "Attach staple" + xcrun stapler staple "/Users/runner/work/QLog/QLog/build/qlog.app" + - name: make dmg + run: | + mkdir out + cp -R "/Users/runner/work/QLog/QLog/build/qlog.app" out + cd out + ln -s /Applications/ Applications + cd .. + hdiutil create -volname "QLog Installer" -srcfolder out -ov -format UDZO "/Users/runner/work/QLog/QLog/build/qlog.dmg" + - name: Codesign dmg bundle + # Extract the secrets we defined earlier as environment variables + env: + MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} + run: | + # Turn our base64-encoded certificate back to a regular .p12 file + ##echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + # We need to create a new keychain, otherwise using the certificate will prompt + # with a UI dialog asking for the certificate password, which we can't + # use in a headless CI environment + ##security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + ##security default-keychain -s build.keychain + ##security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + ##security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + ##security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + # We finally codesign our app bundle, specifying the Hardened runtime option + /usr/bin/codesign --timestamp -s "$MACOS_CERTIFICATE_NAME" --options runtime --deep -f /Users/runner/work/QLog/QLog/build/qlog.dmg + - name: "Notarize app bundle" + # Extract the secrets we defined earlier as environment variables + env: + PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} + PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} + run: | + # Store the notarization credentials so that we can prevent a UI password dialog + # from blocking the CI + + echo "Create keychain profile" + xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD" + + echo "Creating temp notarization archive" + ditto -c -k --keepParent "/Users/runner/work/QLog/QLog/build/qlog.dmg" "notarization.zip" + + # Here we send the notarization request to the Apple's Notarization service, waiting for the result. + # This typically takes a few seconds inside a CI environment, but it might take more depending on the App + # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if + # you're curious + + echo "Notarize app" + xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait + + echo "Attach staple" + xcrun stapler staple "/Users/runner/work/QLog/QLog/build/qlog.dmg" + - name: Copy artifact uses: actions/upload-artifact@v4 with: From d59de4581912bc9a95a42ac7fa0e4cbf7133b248 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Mon, 26 Aug 2024 09:55:44 -0500 Subject: [PATCH 18/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 9abdd85d..c0e6c0c4 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -71,7 +71,7 @@ jobs: run: | cd build macdeployqt qlog.app -executable=./qlog.app/Contents/MacOS/qlog - #macdeployqt qlog.app -dmg + macdeployqt qlog.app - name: Codesign app bundle # Extract the secrets we defined earlier as environment variables env: From a2bc04f71efdb7ff517e8ece54cfed2e7e8aafb4 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:39:32 -0500 Subject: [PATCH 19/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index c0e6c0c4..b6408a8f 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -91,6 +91,7 @@ jobs: security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain # We finally codesign our app bundle, specifying the Hardened runtime option + /usr/bin/codesign --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --entitlements entitlements.xml --options runtime /Users/runner/work/QLog/QLog/build/qlog.app/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess /usr/bin/codesign --timestamp -s "$MACOS_CERTIFICATE_NAME" --options runtime --deep -f /Users/runner/work/QLog/QLog/build/qlog.app - name: "Notarize app bundle" # Extract the secrets we defined earlier as environment variables From 4acd49089a9e519e8c885fcd5b99f9425a96b783 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:07:13 -0500 Subject: [PATCH 20/26] Update entitlements.xml --- entitlements.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/entitlements.xml b/entitlements.xml index 5e873f01..36d136cf 100644 --- a/entitlements.xml +++ b/entitlements.xml @@ -2,6 +2,9 @@ +com.apple.security.cs.allow-unsigned-executable-memory +com.apple.security.cs.disable-library-validation +com.apple.security.cs.allow-jit com.apple.security.cs.disable-executable-page-protection From b8597278591b9b0b46d8f0345029f1a6e89f6644 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Mon, 26 Aug 2024 22:34:58 -0500 Subject: [PATCH 21/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index b6408a8f..97295760 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -71,7 +71,7 @@ jobs: run: | cd build macdeployqt qlog.app -executable=./qlog.app/Contents/MacOS/qlog - macdeployqt qlog.app + #macdeployqt qlog.app - name: Codesign app bundle # Extract the secrets we defined earlier as environment variables env: @@ -91,8 +91,9 @@ jobs: security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain # We finally codesign our app bundle, specifying the Hardened runtime option - /usr/bin/codesign --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --entitlements entitlements.xml --options runtime /Users/runner/work/QLog/QLog/build/qlog.app/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess - /usr/bin/codesign --timestamp -s "$MACOS_CERTIFICATE_NAME" --options runtime --deep -f /Users/runner/work/QLog/QLog/build/qlog.app + sudo codesign --deep --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --options runtime /Users/runner/work/QLog/QLog/build/qlog.app + sudo codesign --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --entitlements QtWebEngineProcess.entitlements --options runtime /Users/runner/work/QLog/QLog/build/qlog.app/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess + sudo codesign --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --options runtime /Users/runner/work/QLog/QLog/build/qlog.app/Contents/MacOS/qlog - name: "Notarize app bundle" # Extract the secrets we defined earlier as environment variables env: From f614688157b2365cccff144ed36e297830856877 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Mon, 26 Aug 2024 22:36:44 -0500 Subject: [PATCH 22/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 97295760..2d330bb3 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -92,7 +92,7 @@ jobs: security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain # We finally codesign our app bundle, specifying the Hardened runtime option sudo codesign --deep --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --options runtime /Users/runner/work/QLog/QLog/build/qlog.app - sudo codesign --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --entitlements QtWebEngineProcess.entitlements --options runtime /Users/runner/work/QLog/QLog/build/qlog.app/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess + sudo codesign --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --entitlements /Users/runner/work/QLog/QLog/entitlements.xml --options runtime /Users/runner/work/QLog/QLog/build/qlog.app/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess sudo codesign --force --verify --verbose --sign "$MACOS_CERTIFICATE_NAME" --options runtime /Users/runner/work/QLog/QLog/build/qlog.app/Contents/MacOS/qlog - name: "Notarize app bundle" # Extract the secrets we defined earlier as environment variables From 846dcad923556aea5345c717e15acad00e891ed8 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Tue, 27 Aug 2024 06:36:12 -0500 Subject: [PATCH 23/26] Update macOSBuild.yml --- .github/workflows/macOSBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macOSBuild.yml b/.github/workflows/macOSBuild.yml index 2d330bb3..0b073e3d 100644 --- a/.github/workflows/macOSBuild.yml +++ b/.github/workflows/macOSBuild.yml @@ -71,7 +71,7 @@ jobs: run: | cd build macdeployqt qlog.app -executable=./qlog.app/Contents/MacOS/qlog - #macdeployqt qlog.app + macdeployqt qlog.app - name: Codesign app bundle # Extract the secrets we defined earlier as environment variables env: From e9f49e5fa9c84685b9acef8a4f85f2c8351ea527 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Tue, 27 Aug 2024 09:11:10 -0500 Subject: [PATCH 24/26] rig caps fix --- .DS_Store | Bin 10244 -> 14340 bytes rig/drivers/HamlibRigDrv.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.DS_Store b/.DS_Store index 95e6014f674933bfb8e317e13e5b68bb44543b32..517955764ae161b4909f7803475b821a38ab7329 100644 GIT binary patch delta 2025 zcmeH{YfM{Z7{{OgDWz`@Ro>EaDThKC1=$#^8*GCO#!c7_?B>SJO&r*xt1E4x1$0ci z#7WecC>~kVF9vndeOY9U%QB;)iN?fznc}>~#kgtIFB+p+jMMm@9v~P^jEP@NJSXqv zdCq&y|9Ae!b{&g)hzKpCfwe?F(Pg6OEw_nklE`D5^4#Dyi2$P5MG<{YG)8fXh&M#B zso@gM=S?%~1Jbmg>>ka>owLKOmZXKHF);1>tej*;)>UYm?W3j|U#&L7+me@@({ntr68k&X;-6rmhdsKpkvV;i=k1D)tbFZ!?#`=R1a9K>BX zggC}9j(czz_u~Of;z2xw$MFQFaU9QJ2G8PooWLo(gjt-%D|i*JVGeKLO}vYFe1HezAG>s7(S(+PDL`W*VeX3W_TR2FGL3!BAvS-0-YcZy(Oco0wR?p>DNjU0sbf z>rk|FPOop-_)u)D)fjKG4@N`5Sls9P2$CtyoNi%OIYa5{mV3qRH(Gn+>fP}@!NaN+ z&EAr0%XY6QtMIMgw54_HPXGLM*JpBBb~v@Sva1-+$<1@+D~k3@c3C3zMe!6{8Gm_y zU?8q`MgqY*f@&Z&M^QYbjP29&ts|278b8sW3}?w-b2Cg!c@7s zhFN)_D>N{uhK$wZ+B%Wi*)yhDbBqNG3A5B0CzGwfFYO(2yFA#}@W&ZefhS)35K` zF%XOUqiT5ROwH|#-4Z)EFrxa$!|KT5j2(>K#xqlSeM(y(7>|t1>$mOjC`zBcRC6Gp z1{j;q%gN=+Zeg3ouV@| zM{m;wdXL_xi}Wd7p>G9t*ICdpEUR45fm z{$+Hc40|* z<+=@<8?`kqKTGi?7r3=aS6M<2isWK9HwzfpydHYxGB-~bAQ<6FcZHivfv^e)i%`|TRa>u`CTFEQGT6vyAEQRcVoZtc32Yaoox!4Qo}$4zfbR;LICnE44&T}3r@xc7E0f0I oomMp9OX2GmH}(yE%xyxn8?$xJH6v%jOz?k454)cKtI9C`0F?e>5dZ)H diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index 631d6971..b9680fee 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -577,7 +577,7 @@ bool HamlibRigDrv::checkFreqChange() } if ( rigProfile.getFreqInfo - && rig->caps->get_freq ) + && (rig->caps->get_freq || rig->caps->get_vfo) ) { freq_t vfo_freq; int status = rig_get_freq(rig, RIG_VFO_CURR, &vfo_freq); From c12f486e45b8aeea17a0ad7b27fb78bb98af6349 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:14:04 -0500 Subject: [PATCH 25/26] Update HamlibRigDrv.cpp --- rig/drivers/HamlibRigDrv.cpp | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index b9680fee..af159191 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -577,7 +577,7 @@ bool HamlibRigDrv::checkFreqChange() } if ( rigProfile.getFreqInfo - && (rig->caps->get_freq || rig->caps->get_vfo) ) + && rig->caps->get_freq ) { freq_t vfo_freq; int status = rig_get_freq(rig, RIG_VFO_CURR, &vfo_freq); @@ -605,6 +605,37 @@ bool HamlibRigDrv::checkFreqChange() return false; } } + else if ( rigProfile.getFreqInfo + && rig->caps->get_vfo ) + { + freq_t vfo_freq; + vfo_t vfo; + rig_get_freq(rig, &vfo); + int status = rig_get_freq(rig, vfo, &vfo_freq); + + if ( status == RIG_OK ) + { + qCDebug(runtime) << "Rig Freq: "<< QSTRING_FREQ(Hz2MHz(vfo_freq)); + qCDebug(runtime) << "Object Freq: "<< QSTRING_FREQ(Hz2MHz(currFreq)); + + if ( vfo_freq != currFreq || forceSendState ) + { + currFreq = vfo_freq; + qCDebug(runtime) << "emitting FREQ changed"; + emit frequencyChanged(Hz2MHz(currFreq), + Hz2MHz(getRITFreq()), + Hz2MHz(getXITFreq())); + } + } + else + { + lastErrorText = hamlibErrorString(status); + emit errorOccured(tr("Get Frequency Error"), + lastErrorText); + qCWarning(runtime) << "Get Freq error" << lastErrorText; + return false; + } + } else { qCDebug(runtime) << "Get Freq is disabled"; From ab3eb66cf37f9ae41b06c2488e6f654f76b7e0d3 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:34:05 -0500 Subject: [PATCH 26/26] Update HamlibRigDrv.cpp --- rig/drivers/HamlibRigDrv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index af159191..11dabae4 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -610,7 +610,7 @@ bool HamlibRigDrv::checkFreqChange() { freq_t vfo_freq; vfo_t vfo; - rig_get_freq(rig, &vfo); + rig_get_vfo(rig, &vfo); int status = rig_get_freq(rig, vfo, &vfo_freq); if ( status == RIG_OK )
HezAG>s7(S(+PDL`W*VeX3W_TR2FGL3!BAvS-0-YcZy(Oco0wR?p>DNjU0sbf z>rk|FPOop-_)u)D)fjKG4@N`5Sls9P2$CtyoNi%OIYa5{mV3qRH(Gn+>fP}@!NaN+ z&EAr0%XY6QtMIMgw54_HPXGLM*JpBBb~v@Sva1-+$<1@+D~k3@c3C3zMe!6{8Gm_y zU?8q`MgqY*f@&Z&M^QYbjP29&ts|278b8sW3}?w-b2Cg!c@7s zhFN)_D>N{uhK$wZ+B%Wi*)yhDbBqNG3A5B0CzGwfFYO(2yFA#}@W&ZefhS)35K` zF%XOUqiT5ROwH|#-4Z)EFrxa$!|KT5j2(>K#xqlSeM(y(7>|t1>$mOjC`zBcRC6Gp z1{j;q%gN=+Zeg3ouV@| zM{m;wdXL_xi}Wd7p>G9t*ICdpEUR45fm z{$+Hc40|* z<+=@<8?`kqKTGi?7r3=aS6M<2isWK9HwzfpydHYxGB-~bAQ<6FcZHivfv^e)i%`|TRa>u`CTFEQGT6vyAEQRcVoZtc32Yaoox!4Qo}$4zfbR;LICnE44&T}3r@xc7E0f0I oomMp9OX2GmH}(yE%xyxn8?$xJH6v%jOz?k454)cKtI9C`0F?e>5dZ)H diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index 631d6971..b9680fee 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -577,7 +577,7 @@ bool HamlibRigDrv::checkFreqChange() } if ( rigProfile.getFreqInfo - && rig->caps->get_freq ) + && (rig->caps->get_freq || rig->caps->get_vfo) ) { freq_t vfo_freq; int status = rig_get_freq(rig, RIG_VFO_CURR, &vfo_freq); From c12f486e45b8aeea17a0ad7b27fb78bb98af6349 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:14:04 -0500 Subject: [PATCH 25/26] Update HamlibRigDrv.cpp --- rig/drivers/HamlibRigDrv.cpp | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index b9680fee..af159191 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -577,7 +577,7 @@ bool HamlibRigDrv::checkFreqChange() } if ( rigProfile.getFreqInfo - && (rig->caps->get_freq || rig->caps->get_vfo) ) + && rig->caps->get_freq ) { freq_t vfo_freq; int status = rig_get_freq(rig, RIG_VFO_CURR, &vfo_freq); @@ -605,6 +605,37 @@ bool HamlibRigDrv::checkFreqChange() return false; } } + else if ( rigProfile.getFreqInfo + && rig->caps->get_vfo ) + { + freq_t vfo_freq; + vfo_t vfo; + rig_get_freq(rig, &vfo); + int status = rig_get_freq(rig, vfo, &vfo_freq); + + if ( status == RIG_OK ) + { + qCDebug(runtime) << "Rig Freq: "<< QSTRING_FREQ(Hz2MHz(vfo_freq)); + qCDebug(runtime) << "Object Freq: "<< QSTRING_FREQ(Hz2MHz(currFreq)); + + if ( vfo_freq != currFreq || forceSendState ) + { + currFreq = vfo_freq; + qCDebug(runtime) << "emitting FREQ changed"; + emit frequencyChanged(Hz2MHz(currFreq), + Hz2MHz(getRITFreq()), + Hz2MHz(getXITFreq())); + } + } + else + { + lastErrorText = hamlibErrorString(status); + emit errorOccured(tr("Get Frequency Error"), + lastErrorText); + qCWarning(runtime) << "Get Freq error" << lastErrorText; + return false; + } + } else { qCDebug(runtime) << "Get Freq is disabled"; From ab3eb66cf37f9ae41b06c2488e6f654f76b7e0d3 Mon Sep 17 00:00:00 2001 From: aa5sh <84428382+aa5sh@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:34:05 -0500 Subject: [PATCH 26/26] Update HamlibRigDrv.cpp --- rig/drivers/HamlibRigDrv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rig/drivers/HamlibRigDrv.cpp b/rig/drivers/HamlibRigDrv.cpp index af159191..11dabae4 100644 --- a/rig/drivers/HamlibRigDrv.cpp +++ b/rig/drivers/HamlibRigDrv.cpp @@ -610,7 +610,7 @@ bool HamlibRigDrv::checkFreqChange() { freq_t vfo_freq; vfo_t vfo; - rig_get_freq(rig, &vfo); + rig_get_vfo(rig, &vfo); int status = rig_get_freq(rig, vfo, &vfo_freq); if ( status == RIG_OK )