From 5a684f394728059c362e6da47c626ea73af850f1 Mon Sep 17 00:00:00 2001 From: PianetaRadio <78976006+PianetaRadio@users.noreply.github.com> Date: Sat, 12 Mar 2022 20:09:26 +0100 Subject: [PATCH] Add files via upload --- CatRadio.pro | 51 ++ CatRadio.pro.user | 426 ++++++++++++++ CatRadio.qss | 1249 +++++++++++++++++++++++++++++++++++++++++ catradio.ico | Bin 0 -> 10462 bytes catradio.png | Bin 0 -> 2793 bytes dialogconfig.cpp | 115 ++++ dialogconfig.h | 46 ++ dialogconfig.ui | 164 ++++++ dialogsetup.cpp | 43 ++ dialogsetup.h | 31 ++ dialogsetup.ui | 103 ++++ guidata.cpp | 22 + guidata.h | 10 + main.cpp | 43 ++ mainwindow.cpp | 839 ++++++++++++++++++++++++++++ mainwindow.h | 153 +++++ mainwindow.ui | 1353 +++++++++++++++++++++++++++++++++++++++++++++ rigcommand.cpp | 153 +++++ rigcommand.h | 36 ++ rigdaemon.cpp | 424 ++++++++++++++ rigdaemon.h | 42 ++ rigdata.cpp | 26 + rigdata.h | 100 ++++ smeter.cpp | 318 +++++++++++ smeter.h | 73 +++ submeter.cpp | 195 +++++++ submeter.h | 67 +++ vfodisplay.cpp | 152 +++++ vfodisplay.h | 37 ++ 29 files changed, 6271 insertions(+) create mode 100644 CatRadio.pro create mode 100644 CatRadio.pro.user create mode 100644 CatRadio.qss create mode 100644 catradio.ico create mode 100644 catradio.png create mode 100644 dialogconfig.cpp create mode 100644 dialogconfig.h create mode 100644 dialogconfig.ui create mode 100644 dialogsetup.cpp create mode 100644 dialogsetup.h create mode 100644 dialogsetup.ui create mode 100644 guidata.cpp create mode 100644 guidata.h create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui create mode 100644 rigcommand.cpp create mode 100644 rigcommand.h create mode 100644 rigdaemon.cpp create mode 100644 rigdaemon.h create mode 100644 rigdata.cpp create mode 100644 rigdata.h create mode 100644 smeter.cpp create mode 100644 smeter.h create mode 100644 submeter.cpp create mode 100644 submeter.h create mode 100644 vfodisplay.cpp create mode 100644 vfodisplay.h diff --git a/CatRadio.pro b/CatRadio.pro new file mode 100644 index 0000000..4fdc6ae --- /dev/null +++ b/CatRadio.pro @@ -0,0 +1,51 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + dialogconfig.cpp \ + dialogsetup.cpp \ + guidata.cpp \ + main.cpp \ + mainwindow.cpp \ + rigcommand.cpp \ + rigdaemon.cpp \ + rigdata.cpp \ + smeter.cpp \ + submeter.cpp \ + vfodisplay.cpp + +HEADERS += \ + dialogconfig.h \ + dialogsetup.h \ + guidata.h \ + mainwindow.h \ + rigcommand.h \ + rigdaemon.h \ + rigdata.h \ + smeter.h \ + submeter.h \ + vfodisplay.h + +FORMS += \ + dialogconfig.ui \ + dialogsetup.ui \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +LIBS += -L$$PWD/hamlib/ -llibhamlib +INCLUDEPATH += $$PWD/hamlib + +VERSION = 1.0.0 + +RC_ICONS = catradio.ico diff --git a/CatRadio.pro.user b/CatRadio.pro.user new file mode 100644 index 0000000..7239cd7 --- /dev/null +++ b/CatRadio.pro.user @@ -0,0 +1,426 @@ + + + + + + EnvironmentId + {3eda28a5-2ae6-4f98-9ee1-3326cb54ce82} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + -fno-delayed-template-parsing + + true + Builtin.BuildSystem + + true + true + Builtin.DefaultTidyAndClazy + 4 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop Qt 5.15.2 MinGW 32-bit + Desktop Qt 5.15.2 MinGW 32-bit + qt.qt5.5152.win32_mingw81_kit + 0 + 0 + 0 + + 0 + C:\Users\Johnny\Documents\QT\build-CatRadio-Desktop_Qt_5_15_2_MinGW_32_bit-Debug + C:/Users/Johnny/Documents/QT/build-CatRadio-Desktop_Qt_5_15_2_MinGW_32_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + C:\Users\Johnny\Documents\QT\build-CatRadio-Desktop_Qt_5_15_2_MinGW_32_bit-Release + C:/Users/Johnny/Documents/QT/build-CatRadio-Desktop_Qt_5_15_2_MinGW_32_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + + + 0 + C:\Users\Johnny\Documents\QT\build-CatRadio-Desktop_Qt_5_15_2_MinGW_32_bit-Profile + C:/Users/Johnny/Documents/QT/build-CatRadio-Desktop_Qt_5_15_2_MinGW_32_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + CatRadio2 + Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Johnny/Documents/QT/CatRadio_1.0.0/CatRadio.pro + C:/Users/Johnny/Documents/QT/CatRadio_1.0.0/CatRadio.pro + false + true + true + false + true + C:/Users/Johnny/Documents/QT/build-CatRadio-Desktop_Qt_5_15_2_MinGW_32_bit-Debug + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop + Desktop Qt 6.1.3 MinGW 64-bit + Desktop Qt 6.1.3 MinGW 64-bit + qt.qt6.613.win64_mingw81_kit + 1 + 0 + 0 + + 0 + C:\Users\Johnny\Documents\QT\build-CatRadio-Desktop_Qt_6_1_3_MinGW_64_bit-Debug + C:/Users/Johnny/Documents/QT/build-CatRadio-Desktop_Qt_6_1_3_MinGW_64_bit-Debug + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + C:\Users\Johnny\Documents\QT\build-CatRadio-Desktop_Qt_6_1_3_MinGW_64_bit-Release + C:/Users/Johnny/Documents/QT/build-CatRadio-Desktop_Qt_6_1_3_MinGW_64_bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + + + 0 + C:\Users\Johnny\Documents\QT\build-CatRadio-Desktop_Qt_6_1_3_MinGW_64_bit-Profile + C:/Users/Johnny/Documents/QT/build-CatRadio-Desktop_Qt_6_1_3_MinGW_64_bit-Profile + + + true + QtProjectManager.QMakeBuildStep + false + + + + true + Qt4ProjectManager.MakeStep + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + clean + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + 0 + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + Qt4ProjectManager.Qt4RunConfiguration:C:/Users/Johnny/Documents/QT/CatRadio/CatRadio.pro + C:/Users/Johnny/Documents/QT/CatRadio/CatRadio.pro + false + true + true + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/CatRadio.qss b/CatRadio.qss new file mode 100644 index 0000000..b1463fe --- /dev/null +++ b/CatRadio.qss @@ -0,0 +1,1249 @@ +/*Copyright (c) DevSec Studio. All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/*-----QWidget-----*/ +QWidget +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(102, 115, 140, 255),stop:1 rgba(56, 63, 77, 255)); + color: #ffffff; + border-color: #051a39; + +} + + +/*-----QLabel-----*/ +QLabel +{ + background-color: transparent; + color: #ffffff; + font-weight: bold; + +} + + +QLabel::disabled +{ + background-color: transparent; + color: #898988; + +} + + +/*-----QMenuBar-----*/ +QMenuBar +{ + background-color: #484c58; + color: #ffffff; + border-color: #051a39; + font-weight: bold; + +} + + +QMenuBar::disabled +{ + background-color: #404040; + color: #898988; + border-color: #051a39; + +} + + +QMenuBar::item +{ + background-color: transparent; + +} + + +QMenuBar::item:selected +{ + background-color: #c4c5c3; + color: #000000; + border: 1px solid #000000; + +} + + +QMenuBar::item:pressed +{ + background-color: #979796; + border: 1px solid #000; + margin-bottom: -1px; + padding-bottom: 1px; + +} + + +/*-----QMenu-----*/ +QMenu +{ + background-color: #c4c5c3; + border: 1px solid; + color: #000000; + font-weight: bold; + +} + + +QMenu::separator +{ + height: 1px; + background-color: #363942; + color: #ffffff; + padding-left: 4px; + margin-left: 10px; + margin-right: 5px; + +} + + +QMenu::item +{ + min-width : 150px; + padding: 3px 20px 3px 20px; + +} + + +QMenu::item:selected +{ + background-color: #363942; + color: #ffffff; + +} + + +QMenu::item:disabled +{ + color: #898988; +} + + +/*-----QToolTip-----*/ +QToolTip +{ + background-color: #bbbcba; + color: #000000; + border-color: #051a39; + border : 1px solid #000000; + border-radius: 2px; + +} + + +/*-----QPushButton-----*/ +QPushButton +{ + background-color: qlineargradient(spread:repeat, x1:0.486, y1:0, x2:0.505, y2:1, stop:0.00480769 rgba(170, 0, 0, 255),stop:1 rgba(122, 0, 0, 255)); + color: #ffffff; + font-weight: bold; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QPushButton::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QPushButton::hover +{ + background-color: #9c0000; + color: #ffffff; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QPushButton::pressed +{ + background-color: #880000; + color: #ffffff; + border-style: solid; + border-width: 2px; + border-radius: 3px; + border-color: #000000; + padding: 5px; + +} + + +/*-----QToolButton-----*/ +QToolButton +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(177, 181, 193, 255),stop:1 rgba(159, 163, 174, 255)); + color: #ffffff; + font-weight: bold; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QToolButton::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QToolButton::hover +{ + background-color: #9fa3ae; + color: #ffffff; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QToolButton::pressed +{ + background-color: #7b7e86; + color: #ffffff; + border-style: solid; + border-width: 2px; + border-radius: 3px; + border-color: #000000; + padding: 5px; + +} + + +/*-----QComboBox-----*/ +QComboBox +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(118, 118, 118, 255),stop:1 rgba(70, 70, 70, 255)); + border: 1px solid #333333; + border-radius: 3px; + padding-left: 6px; + color: lightgray; + font-weight: bold; + height: 20px; + +} + + +QComboBox::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QComboBox:hover +{ + background-color: #646464; + +} + + +QComboBox:on +{ + background-color: #979796; + color: #000000; + +} + + +QComboBox QAbstractItemView +{ + background-color: #c4c5c3; + color: #000000; + border: 1px solid black; + selection-background-color: #363942; + selection-color: #ffffff; + outline: 0; + +} + + +QComboBox::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + border-left-width: 1px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + +} + + +QComboBox::down-arrow +{ + image: url(://arrow-down.png); + width: 8px; + height: 8px; +} + + +/*-----QSpinBox & QDoubleSpinBox & QDateTimeEdit-----*/ +QSpinBox, +QDoubleSpinBox, +QDateTimeEdit +{ + background-color: #000000; + color: #00ff00; + font-weight: bold; + border: 1px solid #333333; + padding : 4px; + +} + + +QSpinBox::disabled, +QDoubleSpinBox::disabled, +QDateTimeEdit::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QSpinBox:hover, +QDoubleSpinBox::hover, +QDateTimeEdit::hover +{ + border: 1px solid #00ff00; + +} + + +QSpinBox::up-button, QSpinBox::down-button, +QDoubleSpinBox::up-button, QDoubleSpinBox::down-button, +QDateTimeEdit::up-button, QDateTimeEdit::down-button +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(118, 118, 118, 255),stop:1 rgba(70, 70, 70, 255)); + border: 0px solid #333333; + +} + + +QSpinBox::disabled, +QDoubleSpinBox::disabled, +QDateTimeEdit::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QSpinBox::up-button:hover, QSpinBox::down-button:hover, +QDoubleSpinBox::up-button:hover, QDoubleSpinBox::down-button:hover, +QDateTimeEdit::up-button:hover, QDateTimeEdit::down-button:hover +{ + background-color: #646464; + border: 1px solid #333333; + + +} + + +QSpinBox::up-button:disabled, QSpinBox::down-button:disabled, +QDoubleSpinBox::up-button:disabled, QDoubleSpinBox::down-button:disabled, +QDateTimeEdit::up-button:disabled, QDateTimeEdit::down-button:disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QSpinBox::up-button:pressed, QSpinBox::down-button:pressed, +QDoubleSpinBox::up-button:pressed, QDoubleSpinBox::down-button::pressed, +QDateTimeEdit::up-button:pressed, QDateTimeEdit::down-button::pressed +{ + background-color: #979796; + border: 1px solid #444444; + +} + + +QSpinBox::down-arrow, +QDoubleSpinBox::down-arrow, +QDateTimeEdit::down-arrow +{ + image: url(://arrow-down.png); + width: 7px; + +} + + +QSpinBox::up-arrow, +QDoubleSpinBox::up-arrow, +QDateTimeEdit::up-arrow +{ + image: url(://arrow-up.png); + width: 7px; + +} + + +/*-----QLineEdit-----*/ +QLineEdit +{ + background-color: #000000; + color: #00ff00; + font-weight: bold; + border: 1px solid #333333; + padding: 4px; + +} + + +QLineEdit:hover +{ + border: 1px solid #00ff00; + +} + + +QLineEdit::disabled +{ + background-color: #404040; + color: #656565; + border-width: 1px; + border-color: #051a39; + padding: 2px; + +} + + +/*-----QTextEdit-----*/ +QTextEdit +{ + background-color: #808080; + color: #fff; + border: 1px groove #333333; + +} + + +QTextEdit::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +/*-----QGroupBox-----*/ +QGroupBox +{ + border: 1px groove #333333; + border-radius: 2px; + margin-top: 20px; + +} + + +QGroupBox +{ + background-color: qlineargradient(spread:repeat, x1:0.486, y1:0, x2:0.505, y2:1, stop:0.00480769 rgba(170, 169, 169, 255),stop:1 rgba(122, 122, 122, 255)); + font-weight: bold; + +} + + +QGroupBox::title +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(71, 75, 87, 255),stop:1 rgba(35, 37, 43, 255)); + color: #ffffff; + border: 2px groove #333333; + subcontrol-origin: margin; + subcontrol-position: top left; + padding: 2px; + +} + + +QGroupBox::title::disabled +{ + background-color: #404040; + color: #656565; + subcontrol-origin: margin; + subcontrol-position: top left; + padding: 5px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + +} + + +/*-----QCheckBox-----*/ +QCheckBox{ + background-color: transparent; + font-weight: bold; + color: #fff; + +} + + +QCheckBox::indicator +{ + color: #b1b1b1; + background-color: #323232; + border: 2px solid #222222; + width: 12px; + height: 12px; + +} + + +QCheckBox::indicator:checked +{ + image:url(://checkbox.png); + border: 2px solid #00ff00; + +} + + +QCheckBox::indicator:unchecked:hover +{ + border: 2px solid #00ff00; + +} + + +QCheckBox::disabled +{ + color: #656565; + +} + + +QCheckBox::indicator:disabled +{ + background-color: #656565; + color: #656565; + border: 1px solid #656565; + +} + + +/*-----QRadioButton-----*/ +QRadioButton{ + background-color: transparent; + font-weight: bold; + color: #fff; + +} + + +QRadioButton::indicator::unchecked +{ + border: 2px inset #222222; + border-radius: 6px; + background-color: #323232; + width: 9px; + height: 9px; + +} + + +QRadioButton::indicator::unchecked:hover +{ + border: 2px solid #00ff00; + border-radius: 5px; + background-color: #323232; + width: 9px; + height: 9px; + +} + + +QRadioButton::indicator::checked +{ + border: 2px inset #222222; + border-radius: 5px; + background-color: #00ff00; + width: 9px; + height: 9px; + +} + + +QRadioButton::disabled +{ + color: #656565; + +} + + +QRadioButton::indicator:disabled +{ + background-color: #656565; + color: #656565; + border: 2px solid #656565; + +} + + +/*-----QTableView & QTableWidget-----*/ +QTableView +{ + background-color: #808080; + border: 1px groove #333333; + color: #f0f0f0; + font-weight: bold; + gridline-color: #333333; + outline : 0; + +} + + +QTableView::disabled +{ + background-color: #242526; + border: 1px solid #32414B; + color: #656565; + gridline-color: #656565; + outline : 0; + +} + + +QTableView::item:hover +{ + background-color: #484c58; + color: #f0f0f0; + +} + + +QTableView::item:selected +{ + background-color: #484c58; + border: 2px groove #00ff00; + color: #F0F0F0; + +} + + +QTableView::item:selected:disabled +{ + background-color: #1a1b1c; + border: 2px solid #525251; + color: #656565; + +} + + +QTableCornerButton::section +{ + background-color: #282830; + +} + + +QHeaderView::section +{ + background-color: #282830; + color: #fff; + font-weight: bold; + text-align: left; + padding: 4px; + +} + + +QHeaderView::section:disabled +{ + background-color: #525251; + color: #656565; + +} + + +QHeaderView::section:checked +{ + background-color: #00ff00; + +} + + +QHeaderView::section:checked:disabled +{ + color: #656565; + background-color: #525251; + +} + + +QHeaderView::section::vertical::first, +QHeaderView::section::vertical::only-one +{ + border-top: 0px; + +} + + +QHeaderView::section::vertical +{ + border-top: 0px; + +} + + +QHeaderView::section::horizontal::first, +QHeaderView::section::horizontal::only-one +{ + border-left: 0px; + +} + + +QHeaderView::section::horizontal +{ + border-left: 0px; + +} + + +/*-----QTabWidget-----*/ +QTabBar::tab +{ + background-color: transparent; + color: #ffffff; + font-weight: bold; + width: 80px; + height: 9px; + +} + + +QTabBar::tab:disabled +{ + background-color: #656565; + color: #656565; + +} + + +QTabWidget::pane +{ + background-color: transparent; + color: #ffffff; + border: 1px groove #333333; + +} + + +QTabBar::tab:selected +{ + background-color: #484c58; + color: #ffffff; + border: 1px groove #333333; + border-bottom: 0px; + +} + + +QTabBar::tab:selected:disabled +{ + background-color: #404040; + color: #656565; + +} + + +QTabBar::tab:!selected +{ + background-color: #a3a7b2; + +} + + +QTabBar::tab:!selected:hover +{ + background-color: #484c58; + +} + + +QTabBar::tab:top:!selected +{ + margin-top: 1px; + +} + + +QTabBar::tab:bottom:!selected +{ + margin-bottom: 3px; + +} + + +QTabBar::tab:top, QTabBar::tab:bottom +{ + min-width: 8ex; + margin-right: -1px; + padding: 5px 10px 5px 10px; + +} + + +QTabBar::tab:top:selected +{ + border-bottom-color: none; + +} + + +QTabBar::tab:bottom:selected +{ + border-top-color: none; + +} + + +QTabBar::tab:top:last, QTabBar::tab:bottom:last, +QTabBar::tab:top:only-one, QTabBar::tab:bottom:only-one +{ + margin-right: 0; + +} + + +QTabBar::tab:left:!selected +{ + margin-right: 2px; + +} + + +QTabBar::tab:right:!selected +{ + margin-left: 2px; + +} + + +QTabBar::tab:left, QTabBar::tab:right +{ + min-height: 15ex; + margin-bottom: -1px; + padding: 10px 5px 10px 5px; + +} + + +QTabBar::tab:left:selected +{ + border-left-color: none; + +} + + +QTabBar::tab:right:selected +{ + border-right-color: none; + +} + + +QTabBar::tab:left:last, QTabBar::tab:right:last, +QTabBar::tab:left:only-one, QTabBar::tab:right:only-one +{ + margin-bottom: 0; + +} + + +/*-----QSlider-----*/ +QSlider{ + background-color: transparent; + +} + + +QSlider::groove:horizontal +{ + background-color: transparent; + height: 6px; + +} + + +QSlider::sub-page:horizontal +{ + background-color: qlineargradient(spread:reflect, x1:1, y1:0, x2:1, y2:1, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + +} + + +QSlider::add-page:horizontal +{ + background-color: #404040; + border: 1px solid #000; + +} + + +QSlider::handle:horizontal +{ + background-color: qlineargradient(spread:reflect, x1:1, y1:0, x2:1, y2:1, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + width: 12px; + margin-top: -6px; + margin-bottom: -6px; + +} + + +QSlider::handle:horizontal:hover +{ + background-color: #808080; + +} + + +QSlider::sub-page:horizontal:disabled +{ + background-color: #bbb; + border-color: #999; + +} + + +QSlider::add-page:horizontal:disabled +{ + background-color: #eee; + border-color: #999; + +} + + +QSlider::handle:horizontal:disabled +{ + background-color: #eee; + border: 1px solid #aaa; + +} + + +QSlider::groove:vertical +{ + background-color: transparent; + width: 6px; + +} + + +QSlider::sub-page:vertical +{ + background-color: qlineargradient(spread:reflect, x1:0, y1:0.483, x2:1, y2:0.517, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + +} + + +QSlider::add-page:vertical +{ + background-color: #404040; + border: 1px solid #000; + +} + + +QSlider::handle:vertical +{ + background-color: qlineargradient(spread:reflect, x1:0, y1:0.483, x2:1, y2:0.517, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + height: 12px; + margin-left: -6px; + margin-right: -6px; + +} + + +QSlider::handle:vertical:hover +{ + background-color: #808080; + +} + + +QSlider::sub-page:vertical:disabled +{ + background-color: #bbb; + border-color: #999; + +} + + +QSlider::add-page:vertical:disabled +{ + background-color: #eee; + border-color: #999; + +} + + +QSlider::handle:vertical:disabled +{ + background-color: #eee; + border: 1px solid #aaa; + border-radius: 3px; + +} + + +/*-----QDial-----*/ +QDial +{ + background-color: #600000; + +} + + +QDial::disabled +{ + background-color: #404040; + +} + + +/*-----QScrollBar-----*/ +QScrollBar:horizontal +{ + border: 1px solid #222222; + background-color: #63676d; + height: 18px; + margin: 0px 18px 0 18px; + +} + + +QScrollBar::handle:horizontal +{ + background-color: #a6acb3; + border: 1px solid #656565; + border-radius: 2px; + min-height: 20px; + +} + + +QScrollBar::add-line:horizontal +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + width: 18px; + subcontrol-position: right; + subcontrol-origin: margin; + +} + + +QScrollBar::sub-line:horizontal +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + width: 18px; + subcontrol-position: left; + subcontrol-origin: margin; + +} + + +QScrollBar::right-arrow:horizontal +{ + image: url(://arrow-right.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::left-arrow:horizontal +{ + image: url(://arrow-left.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal +{ + background: none; + +} + + +QScrollBar:vertical +{ + background-color: #63676d; + width: 18px; + margin: 18px 0 18px 0; + border: 1px solid #222222; + +} + + +QScrollBar::handle:vertical +{ + background-color: #a6acb3; + border: 1px solid #656565; + border-radius: 2px; + min-height: 20px; + +} + + +QScrollBar::add-line:vertical +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + height: 18px; + subcontrol-position: bottom; + subcontrol-origin: margin; + +} + + +QScrollBar::sub-line:vertical +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + height: 18px; + subcontrol-position: top; + subcontrol-origin: margin; + +} + + +QScrollBar::up-arrow:vertical +{ + image: url(://arrow-up.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::down-arrow:vertical +{ + image: url(://arrow-down.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical +{ + background: none; + +} + + +/*-----QProgressBar-----*/ +QProgressBar +{ + background-color: #000; + color: #00ff00; + font-weight: bold; + border: 0px groove #000; + border-radius: 10px; + text-align: center; + +} + + +QProgressBar:disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + border: 1px solid #000; + border-radius: 10px; + text-align: center; + +} + + +QProgressBar::chunk { + background-color: #ffaf02; + border: 0px; + border-radius: 10px; + color: #000; + +} + + +QProgressBar::chunk:disabled { + background-color: #333; + border: 0px; + border-radius: 10px; + color: #656565; +} + + +/*-----QStatusBar-----*/ +QStatusBar +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(102, 115, 140, 255),stop:1 rgba(56, 63, 77, 255)); + color: #ffffff; + border-color: #051a39; + font-weight: bold; + +} + + diff --git a/catradio.ico b/catradio.ico new file mode 100644 index 0000000000000000000000000000000000000000..37954a6eb8721fa00830559fad1220e477a108a0 GIT binary patch literal 10462 zcmdU!3shCd6^5@-OR%-ZRgF~>h}NJ8g7~UZ6>FmL{Qyzp3s6Atfq;UsqN3FbkxJ5K zd{q-uW317HXf#Hv4O+8S+ESw=sgJ6$HSH=Ifm++(bNc;hRa8lY{?HIX-UZa6ImCI4B&L9MK^A9i$%Z$?zFm15?Y8PoF{}$X9n# zALCxAZN69J&mMer7t5R)jG=(B*S2WUVq^2>&39GfJj$K&@@EVc#eT2$tBkpQ`0(MQ zqobqe#KgqJPo6wE7F!scsD}BJ|K;U62Dkn;Y}nAPy`ugu_WYqkhxUq(k57c>pbt!h zzCJ!a$VZ)}<*|H5DJUFsfuU;c< zy=Tv!!v+l+6lLr9JtZtGED61!apT76_}m|U3^PFz3)v$^jPR$=W_T?)I5?(Tw{B4$ z9v+*}<-bTCJ9cc#@#DvPtM0V@pO4tfi@QFCIY&ZII$Q13{UNYPlP0!48oiB6`_t&d z(EkBbsmFohm<3Z{0xX;~X;K$YPtOG{Tecj9J_Md-eY9Sm2>Fk#9Sl%BPP;oFX(}V` z`g{|c9fy2O28rTQEQ_L|qDCtYJQ#sK7<#J?Rvhvj+Y=C49dR(u51~Kf+v~46XSnDg z=m9QzYjow^P1sA_3sPYTEQXaZpY=|m{WMs4)w_4^c-6tqtE6$`#ZpZjMqlc-CW6Qdm&z4u-C;w;N&2jj2c`22RS5X_Dy7jM21f`1Gej4|1 zT4%FocA(ih&Ck3Z>uV0o?PTd&;@X?7@qT9eOnmq&3-Z_EhH!lR4&DeG(cA(zLVn>3%*}+&EV>fJ@?q}8ILv_TF z`;*S*9p+dv(%WQ>ZEd#1w>NL#!_rW1vua`+^L9c9^U}B%GI`Je0nEk0i zRz6fm90yoC`Lu1CKk;<1#@8HLcdhp>>TeQT4sCnqbhOq`_CxbK<3~qpU2|rY`lRy1 zd7aInv@X_tJvcYW>Zg0GYc+;^*L^uao2ah);hM9`ap`&{?0mP&J3S|^<5aa?h5Mm1 zS7muv8{6b_d8vtWdrimg?%b|(LQT(G-Q&+Le>2eax%PvHD3hCu<(^IPA|m z`i|~lmPR9VAW___ zp|uo5_7%_+egW$5ipH);!f7Z3_0e|;-f*w7g9|l|zW-B>t%DNy5{|$}@Gp1+8p144 z4yybP$o?1bf{pMuxCPpGe-C$(HgvGhrx&UJ=uQ{7Y43eZ_eD^{#ni(TVPgS!zu@4G?k zsWps%yOrYEd7im$-MWyjUAroma(sP# z6HcBy`6T^Dz-(A{<;s-^FE1~R^&#A?)TQG}kUwHGJO-6XHyY1^`u_>+XH4t8iggXg zpULnH1Vd}+dj0x!-`lrucc&gh8H}!Y`$8y0z&x0J>(;GA#(4$4fT~Ia7hD1PRs_lg zU-%a2zO{u&*aJEn+A%1fZ23b#K)_!7TZlhvVGt-D`8ok2AO$jDE+oJrm<~%I4PGW6 zlNs=R_?9TF0vXHM?~&->tWMN>r6P`G~m`bqeuJclkJtZ0J!WPg%*&cm7;H*VXibl|{&2l)Ny#e#x@p4eX1enTJa9cQ39JV?>|O?&zmXU?1% zihuL@Jun{qlGw6ki{4AI+1c4EdAD80c4pP8Rf;Y4@ZrNlqmZa0CPixQUcjU;C_ULKw9QUKM;^4W6L03-oh1wvEapI4#3mV{KLwE!{ z;4$!WmeT9PQh*E(o;2nr2Yc6&Pb8LJrY!L= zmR?e)v@CY0OwXuWyoi#ZOF|fj@}_r5ACEX>4Tx04R}tkv&MmKpe$iQ>7v;3U&~2$WS|35EXHh zDi*;)X)CnqU~=gfG-*guTpR`0f`cE6RRK&nZBh=>897?NNf zvYTX=ecgLc|KJy936K&bCi%^rxqHsJd+zUhe~dEMUFN9{?teRUqF7dVzlfG2ks=IpCM;n?S6lre>GiS34F#WC5=M zO}lpOy5`wupM6rSlN1Xifg`oGwGVyp!3PWH&71chVDk_z_@#+sP=7iwA9$*=vNB`t z+_}wuzkkE)ufJYySyqYH>+SUW{Rb;5D$0~n6a9Yw+q-w~z6+QP>>n%E(1AyQu9seV z=_aMra;4O5N~v3FWfkD=FCoD4WNw`AYPzRTq{c{m8+D} zl~Qh{RK8NGOs;OFlv61+xx2f2-hu@S-T-z0p3%0#fXoM`tzNylK`B-G_~VafYMOSx zrfK&cJa}*lP_bjj4xgrJt2Ir#uB)qSLP0^n*IX{w7N7#Sax4IG0k;CZ_uO;OVW4K` z&YjDEhk=J18ylAbQyLo^S5;P4{uubf=FOWu0PEJR+XM8={~e

_xygfvx4`-w8O6+lHr#XG>2KA&%UNl8hi$K%;mQ&W=!=2ul!9hD8V8u%4(Y&0#i3OHU@SNC0| z)cs1S?JdW z74TQ!Q+a+ba1eL}_#seuF4ua$va<5?rlzKyPN&l+`^Y3w)F;*LL~*B(xQ$obtVkYK zm`o-=b-Ud+h^71&0AMQc4DgNrb6*q)0&B%}wJGfgw*bUM92z9{VjlD2JIhG9&X>@{VWAnpX7lJ&yC)4<<=L*fO+zyhEK zxLNex1$;~NM;F(*ytTFU6QB>c0VrL&c5RoYX;-^kuE%s;Us_jJcc7}OYN^ZRdSv$O z*_XAnv^0v@lfWg>Xf#w-R(6G0@_fYrehWM&AfA_(uvTifr0CQl_bif)`!Mj;fhuHR zu^&i)|7OpgJr#*W;^uHTJRevmmT3o0$nO}?CfCOr8XB@p)4V+riQKt<{rYEQoqNv{ zL>}-4pu|P)9L5WnAaSFB-wh0A1Amgm+JNm+JN3#N$_4HRB67`<@q<7aumNaIOVjV2 zhaz7AJ`zQ`B-;&F=E^f;K#3vQ=xtyx;1op>7x|;4;4T?|4(Jqfo4_{lUAKT~lkvX* zkDfz;8gYqBfjz+W^6cTtXF#R2wvkBbO4`d3m_DEsxD9AXo3Bsz?+cXMWv#6vwLeAE z6dv4qfV(cz`DKc%d1$17_<)CiCUJot;2q#c666<4vIR(laV{PK64u8#km+(gI^KaS zlI!;I3?c*Q5ZAhXJOlZKfM^1=0oQT@t7W%M4v{)Xt0jSbz=LVWb5rKl$Q7s1plY17 ze~8Yy)QP8L^*91C&>lRSuYEKQfqZzj6Jk{J}haG>c1W;}x7%*1eI zVB03jGI8Zxf|W{;iiR*8E(~`zRw9ZsD<93!u~R7&8oI-QGE>-A3M(1Mk&#U*)`v4I z|KvvDExsV`_smJ%fn_G?Kh{FD>o8`#4>Q(Fe@6?k@pNo6Nk(1~mYE=XqK2mFC}rc!%*AkLV(2*-&P<$n1t<-anIvoCWUN#S z!<~gA+Y5#R3|1K}{!n(zKH?24v*>PP@-NsDGi9sT#rTV#zU?G=A)2(!J;DT4|D-n@fLx z|8S1G;ljegrta?Umt}0CoY$vv=9l7;vq&HixDhad!QfWuUj{gW!QdY0X8~F;7>r84 z6etb`gN;C_yuAGP)z#Glghmo5>ged$zh%po`+#o);i96V*3QmOo0H!l^X1XuG;SIIc(1y;dZQ59vxOs`?(_Mst*xznU#O&4r%jvo z^umP;>ws4UKp6Pt9e3QZ2)IVLweV=g$T8s2Kp@Z#%n;tmmTI*$9*^&@udlC&#bSE{ zfj|oA4+evmNLkK`6)SG>dc7KObtn{iufD$i4dJjZ%p!q6;I=>@;7{vc9tZ^H78Dc= z^p^($f$3@UGXjCYlC&jCf!$I{n4J7huPn^LHXf8b{S(WA&mV4=K}FRb^nZ)s>^rc00000NkvXXu0mjf^gcx` literal 0 HcmV?d00001 diff --git a/dialogconfig.cpp b/dialogconfig.cpp new file mode 100644 index 0000000..2a0fe0f --- /dev/null +++ b/dialogconfig.cpp @@ -0,0 +1,115 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "dialogconfig.h" +#include "ui_dialogconfig.h" + +#include +#include +#include + +#include "rigdata.h" + +#include + + +extern rigConnect rigCom; + + +QString rigListFile = "rig.lst"; //Text file containing the list of rig supported by hamlib +QFile file(rigListFile); + + +DialogConfig::DialogConfig(QWidget *parent) : + QDialog(parent), + ui(new Ui::DialogConfig) +{ + ui->setupUi(this); + + //* rigModel comboBox + if (!file.exists()) //Create file rig.lst if not exists + { + file.open(QIODevice::ReadWrite); + rig_load_all_backends(); //Load all backends information + rig_list_foreach(printRigList, NULL); //Create the rig list + } + else file.open(QIODevice::ReadOnly); //Open file rig.lst and populate the combobox + file.seek(0); + ui->comboBox_rigModel->clear(); + while(!file.atEnd()) + { + QString line = file.readLine(); + ui->comboBox_rigModel->addItem(line.trimmed()); + } + file.close(); + + //* serialSpeed comboBox + ui->comboBox_serialSpeed->clear(); + ui->comboBox_serialSpeed->addItem("4800"); + ui->comboBox_serialSpeed->addItem("9600"); + ui->comboBox_serialSpeed->addItem("19200"); + ui->comboBox_serialSpeed->addItem("38400"); + ui->comboBox_serialSpeed->addItem("57600"); + ui->comboBox_serialSpeed->addItem("115200"); + + //* Update values in the GUI + ui->comboBox_rigModel->setCurrentIndex(ui->comboBox_rigModel->findText(QString::number(rigCom.rigModel),Qt::MatchStartsWith)); + ui->lineEdit_RigPath->setText(rigCom.rigPort); + ui->comboBox_serialSpeed->setCurrentText(QString::number(rigCom.serialSpeed)); + if (rigCom.civAddr) ui->lineEdit_civAddr->setText(QString::number(rigCom.civAddr)); + ui->spinBox_RefreshRate->setValue(rigCom.rigRefresh); + ui->checkBox_fullPoll->setChecked(rigCom.fullPoll); +} + +DialogConfig::~DialogConfig() +{ + delete ui; +} + +void DialogConfig::on_buttonBox_accepted() +{ + //* Read settings from GUI + QString rigModel = ui->comboBox_rigModel->currentText(); + QRegularExpression regexp("[0-9]+"); + QRegularExpressionMatch rigNumber = regexp.match(rigModel); + rigCom.rigModel = rigNumber.captured(0).toInt(); + + rigCom.rigPort = ui->lineEdit_RigPath->text(); + rigCom.serialSpeed = ui->comboBox_serialSpeed->currentText().toInt(); + rigCom.civAddr = ui->lineEdit_civAddr->text().toInt(); + rigCom.rigRefresh = ui->spinBox_RefreshRate->value(); + rigCom.fullPoll = ui->checkBox_fullPoll->isChecked(); + + //* Save settings in config.ini + QSettings configFile(QString("config.ini"), QSettings::IniFormat); + configFile.setValue("rigModel", rigCom.rigModel); + configFile.setValue("rigPort", ui->lineEdit_RigPath->text()); + configFile.setValue("serialSpeed", ui->comboBox_serialSpeed->currentText()); + configFile.setValue("civAddress", ui->lineEdit_civAddr->text()); + configFile.setValue("rigRefresh", ui->spinBox_RefreshRate->value()); + configFile.setValue("fullPolling", ui->checkBox_fullPoll->isChecked()); +} + +int printRigList(const struct rig_caps *rigCaps, void *data) //Load rig list from hamlib and save into file rig.lst +{ + if (data) return 0; + QTextStream stream(&file); + stream << rigCaps->rig_model << " " << rigCaps->mfg_name << " " << rigCaps->model_name << "\n"; + return 1; +} diff --git a/dialogconfig.h b/dialogconfig.h new file mode 100644 index 0000000..3afdf77 --- /dev/null +++ b/dialogconfig.h @@ -0,0 +1,46 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#ifndef DIALOGCONFIG_H +#define DIALOGCONFIG_H + +#include + +namespace Ui { +class DialogConfig; +} + +class DialogConfig : public QDialog +{ + Q_OBJECT + +public: + explicit DialogConfig(QWidget *parent = nullptr); + ~DialogConfig(); + +private slots: + void on_buttonBox_accepted(); + +private: + Ui::DialogConfig *ui; +}; + +int printRigList(const struct rig_caps *rigCaps, void *data); + +#endif // DIALOGCONFIG_H diff --git a/dialogconfig.ui b/dialogconfig.ui new file mode 100644 index 0000000..0447762 --- /dev/null +++ b/dialogconfig.ui @@ -0,0 +1,164 @@ + + + DialogConfig + + + + 0 + 0 + 400 + 300 + + + + Config + + + + + + Model + + + + + + + + + + Path + + + lineEdit_RigPath + + + + + + + + + + Speed + + + comboBox_serialSpeed + + + + + + + + + + Refresh Rate + + + spinBox_RefreshRate + + + + + + + 50 + + + 1000 + + + 50 + + + 200 + + + + + + + Options + + + + + + CI-V Address + + + + + + + Full polling + + + + + + + CI-V address (decimal, Icom only) + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + lineEdit_RigPath + comboBox_serialSpeed + spinBox_RefreshRate + + + + + buttonBox + accepted() + DialogConfig + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogConfig + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/dialogsetup.cpp b/dialogsetup.cpp new file mode 100644 index 0000000..ce6d7fb --- /dev/null +++ b/dialogsetup.cpp @@ -0,0 +1,43 @@ +#include "dialogsetup.h" +#include "ui_dialogsetup.h" + +#include "guidata.h" + +#include +#include + + +extern guiConfig guiConf; + + +DialogSetup::DialogSetup(QWidget *parent) : + QDialog(parent), + ui(new Ui::DialogSetup) +{ + ui->setupUi(this); + + if (guiConf.vfoDisplayMode) ui->radioButton_vfoDispMode_UD->setChecked(true); +} + +DialogSetup::~DialogSetup() +{ + delete ui; +} + +void DialogSetup::on_radioButton_vfoDispMode_LR_toggled(bool checked) +{ + if (checked) guiConf.vfoDisplayMode=0; +} + +void DialogSetup::on_radioButton_vfoDispMode_UD_toggled(bool checked) +{ + if (checked) guiConf.vfoDisplayMode=1; +} + +void DialogSetup::on_buttonBox_accepted() +{ + //* Save settings in config.ini + QSettings configFile(QString("config.ini"), QSettings::IniFormat); + configFile.setValue("vfoDisplayMode", guiConf.vfoDisplayMode); +} + diff --git a/dialogsetup.h b/dialogsetup.h new file mode 100644 index 0000000..c39b453 --- /dev/null +++ b/dialogsetup.h @@ -0,0 +1,31 @@ +#ifndef DIALOGSETUP_H +#define DIALOGSETUP_H + +#include + +namespace Ui { +class DialogSetup; +} + +class DialogSetup : public QDialog +{ + Q_OBJECT + +public: + explicit DialogSetup(QWidget *parent = nullptr); + ~DialogSetup(); + +private slots: + + + void on_radioButton_vfoDispMode_LR_toggled(bool checked); + + void on_radioButton_vfoDispMode_UD_toggled(bool checked); + + void on_buttonBox_accepted(); + +private: + Ui::DialogSetup *ui; +}; + +#endif // DIALOGSETUP_H diff --git a/dialogsetup.ui b/dialogsetup.ui new file mode 100644 index 0000000..9a40c03 --- /dev/null +++ b/dialogsetup.ui @@ -0,0 +1,103 @@ + + + DialogSetup + + + + 0 + 0 + 400 + 300 + + + + Setup + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + VFO Display Mode + + + + + + Left/Right buttons + + + true + + + + + + + Up/Down click + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + buttonBox + accepted() + DialogSetup + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DialogSetup + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/guidata.cpp b/guidata.cpp new file mode 100644 index 0000000..d700faa --- /dev/null +++ b/guidata.cpp @@ -0,0 +1,22 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "guidata.h" + +guiConfig guiConf; diff --git a/guidata.h b/guidata.h new file mode 100644 index 0000000..2fdd987 --- /dev/null +++ b/guidata.h @@ -0,0 +1,10 @@ +#ifndef GUIDATA_H +#define GUIDATA_H + +#endif // GUIDATA_H + + +typedef struct { + int vfoDisplayMode; //0: use Left/Right mouse button, 1: click digit up or down + +} guiConfig; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..f8a5cf6 --- /dev/null +++ b/main.cpp @@ -0,0 +1,43 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + +#include "mainwindow.h" + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + +/* + QFile file("./CatRadio.qss"); //open qss file + //if(!file.open(QFile::ReadOnly)) + file.open(QFile::ReadOnly); + + QString styleSheet (file.readAll()); + file.close(); + + a.setStyleSheet(styleSheet); //setup stylesheet +*/ + + w.show(); + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..36d1921 --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,839 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "dialogconfig.h" +#include "dialogsetup.h" +#include "rigdaemon.h" +#include "rigdata.h" +#include "guidata.h" +#include "rigcommand.h" + +#include +#include +#include +#include +#include + +#include //Hamlib + +extern RIG *my_rig; //Defined in rigdaemon.cpp + +extern rigConnect rigCom; +extern rigSettings rigGet; +extern rigSettings rigSet; +extern rigCommand rigCmd; +extern rigCommand rigCap; +extern guiConfig guiConf; + +int retcode; //Return code from function +int i; //Index +int prevDial; //Previous dial value +int fastDial; //Fast pushbutton state + +FILE* debugFile; + + +QThread workerThread; // +RigDaemon *rigDaemon = new RigDaemon; + + +//***** MainWindow ***** + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + timer = new QTimer(this); //timer for rigDaemon thread call + + //* Debug + rig_set_debug_level(RIG_DEBUG_WARN); + rig_set_debug_time_stamp(true); + if ((debugFile=fopen("debug.log","w+")) == NULL) rig_set_debug_level(RIG_DEBUG_NONE); + else rig_set_debug_file(debugFile); + + //* Signal and Slot connection for Slider and associated Label + connect(ui->horizontalSlider_RFpower, &QAbstractSlider::valueChanged, ui->label_RFpowerValue, qOverload(&QLabel::setNum)); + connect(ui->horizontalSlider_RFgain, &QAbstractSlider::valueChanged, ui->label_RFgainValue, qOverload(&QLabel::setNum)); + connect(ui->horizontalSlider_IFshift, &QAbstractSlider::valueChanged, ui->label_IFshiftValue, qOverload(&QLabel::setNum)); + + //* Signal and Slot connection for vfoDisplay + connect(ui->lineEdit_vfoMain, &vfoDisplay::on_valueChanged, this, &MainWindow::on_vfoDisplayValueChanged); + + //* Thread for RigDaemon + rigDaemon->moveToThread(&workerThread); // + connect(&workerThread, &QThread::finished, rigDaemon, &QObject::deleteLater); + connect(timer, &QTimer::timeout, rigDaemon, &RigDaemon::rigUpdate); + connect(rigDaemon, &RigDaemon::resultReady, this, &MainWindow::on_rigDaemonResultReady); + workerThread.start(); + + //* Load settings from config.ini + QSettings configFile(QString("config.ini"), QSettings::IniFormat); + rigCom.rigModel = configFile.value("rigModel", 0).toInt(); + rigCom.rigPort = configFile.value("rigPort").toString(); + rigCom.serialSpeed = configFile.value("serialSpeed", 9600).toInt(); + rigCom.civAddr = configFile.value("civAddress", 0).toInt(); + rigCom.rigRefresh = configFile.value("rigRefresh", 100).toInt(); + rigCom.fullPoll = configFile.value("fullPolling", false).toBool(); + guiConf.vfoDisplayMode = configFile.value("vfoDisplayMode", 0).toInt(); +} + +MainWindow::~MainWindow() +{ + workerThread.quit(); // + workerThread.wait(); + + if (rigCom.connected) + { + timer->stop(); + + rigCom.connected = 0; + rig_close(my_rig); //Close the communication to the rig + } + + rig_cleanup(my_rig); //Release rig handle and free associated memory + + fclose(debugFile); //Close debug.log + + delete ui; +} + + +//***** GUI function ***** + +void MainWindow::guiInit() +{ + ui->statusbar->showMessage(my_rig->caps->model_name); + + if (rig_has_set_func(my_rig, RIG_FUNCTION_SET_POWERSTAT)==0) //Power pushbutton + { + ui->pushButton_Power->setDisabled(true); + rigCap.onoff = 0; + } + else + { + ui->pushButton_Power->setDisabled(false); + rigCap.onoff = 1; + } + + if (rig_has_set_func(my_rig, RIG_FUNCTION_SET_PTT)==0) //PTT pushbutton + { + ui->pushButton_PTT->setDisabled(true); + rigCap.ptt = 0; + } + else + { + ui->pushButton_PTT->setDisabled(false); + rigCap.ptt = 1; + } + + //* Mode combobox + if (my_rig->state.mode_list==RIG_MODE_NONE) + { + ui->comboBox_Mode->setDisabled(true); + ui->comboBox_ModeSub->setDisabled(true); + } + else + { + ui->comboBox_Mode->clear(); //Clear old contents + ui->comboBox_ModeSub->clear(); + for (i=0; istate.mode_list & (1ULL << i)) + { + ui->comboBox_Mode->addItem(rig_strrmode(my_rig->state.mode_list & (1ULL << i))); + ui->comboBox_ModeSub->addItem(rig_strrmode(my_rig->state.mode_list & (1ULL << i))); + } + } + rigCmd.bwidthList = 1; //Command to populate BW combobox in guiUpdate() + } + + //* AGC level comboBox + ui->comboBox_AGC->clear(); + /* It seems that has_set_level or has_get_level is not well implemented in Hamlib, at the moment it is skipped in favour of fix values entry + agc_level_e agcLevel; + for (i = 0; i < 7; i++) + { + agcLevel = levelagcvalue(i); + if (rig_has_set_level(my_rig, agcLevel)) + { + ui->comboBox_AGC->addItem(rig_stragclevel(agcLevel)); + } + }*/ + ui->comboBox_AGC->addItem(rig_stragclevel(RIG_AGC_OFF)); + ui->comboBox_AGC->addItem(rig_stragclevel(RIG_AGC_AUTO)); + ui->comboBox_AGC->addItem(rig_stragclevel(RIG_AGC_FAST)); + ui->comboBox_AGC->addItem(rig_stragclevel(RIG_AGC_MEDIUM)); + ui->comboBox_AGC->addItem(rig_stragclevel(RIG_AGC_SLOW)); + + //* Meter comboBox + ui->comboBox_Meter->clear(); + if (rig_has_get_level(my_rig, RIG_METER_SWR)) ui->comboBox_Meter->addItem("SWR"); + if (rig_has_get_level(my_rig, RIG_METER_ALC)) ui->comboBox_Meter->addItem("ALC"); + rigSet.meter = levelmeterstr (ui->comboBox_Meter->currentText()); + setSubMeter(); + + //* Attenuator comboBox + ui->comboBox_Att->clear(); + ui->comboBox_Att->addItem("0"); + for (i = 0; i < HAMLIB_MAXDBLSTSIZ && my_rig->state.attenuator[i] != 0; i++) + { + ui->comboBox_Att->addItem(QString::number(my_rig->state.attenuator[i])); + } + + //* Preamp comboBox + ui->comboBox_Preamp->clear(); + ui->comboBox_Preamp->addItem("0"); + for (i = 0; i < HAMLIB_MAXDBLSTSIZ && my_rig->state.preamp[i] != 0; i++) + { + ui->comboBox_Preamp->addItem(QString::number(my_rig->state.preamp[i])); + } + + rigCmd.rangeList = 1; + rigCmd.antList = 1; +} + +void MainWindow::guiUpdate() +{ + //* Power button + if (rigGet.onoff == RIG_POWER_ON) ui->pushButton_Power->setChecked(true); + + //* VFOs + ui->lineEdit_vfoMain->setValue(rigGet.freqMain); + ui->lineEdit_vfoSub->setText(QString::number(rigGet.freqSub/1000,'f',2)); + + ui->label_vfoMain->setText(rig_strvfo(rigGet.vfoMain)); + switch (rigGet.vfoMain) + { + case RIG_VFO_A: rigGet.vfoSub = RIG_VFO_B; break; + case RIG_VFO_B: rigGet.vfoSub = RIG_VFO_A; break; + case RIG_VFO_MAIN: rigGet.vfoSub = RIG_VFO_SUB; break; + case RIG_VFO_SUB: rigGet.vfoSub = RIG_VFO_MAIN; break; + } + ui->label_vfoSub->setText(rig_strvfo(rigGet.vfoSub)); + + //* Mode + ui->comboBox_Mode->setCurrentText(rig_strrmode(rigGet.mode)); + ui->comboBox_ModeSub->setCurrentText(rig_strrmode(rigGet.modeSub)); + + //* BW combobox + if (rigCmd.bwidthList) + { + ui->comboBox_BW->clear(); + filter_list bwidth_list; //IF filter bandwidth per mode + for (i=0; istate.filters[i]); i++) + { + char modeslist[1000] = ""; + QString modes, mode; + bwidth_list = my_rig->state.filters[i]; + rig_strrmodes(bwidth_list.modes, modeslist, sizeof(modeslist)); + modes = modeslist; + modes.append(" "); + //qDebug() << modes << bwidth_list.width; + mode = rig_strrmode(rigGet.mode); + QRegularExpression rx("\\b"+mode+"?\\s"); + if (modes.contains (rx) && bwidth_list.width != RIG_FLT_ANY) ui->comboBox_BW->addItem(QString::number(bwidth_list.width)); + } + ui->comboBox_BW->model()->sort(0, Qt::DescendingOrder); + rigCmd.bwidthList = 0; + } + + ui->comboBox_BW->setCurrentText(QString::number(rigGet.bwidth)); + ui->checkBox_NAR->setChecked(rigGet.bwNarrow); + + //* Range list + if (rigCmd.rangeList) + { + for (i=0; i= my_rig->state.tx_range_list[i].startf && rigGet.freqMain <= my_rig->state.tx_range_list[i].endf) break; + } + rigGet.rangeListTxIndex = i; + + for (i=0; i= my_rig->state.rx_range_list[i].startf && rigGet.freqMain <= my_rig->state.rx_range_list[i].endf) break; + } + if (rigGet.rangeListRxIndex != i) rigCmd.antList = 1; + rigGet.rangeListRxIndex = i; + + rigCmd.rangeList = 0; + } + + //* Antenna comboBox + if (rigCmd.antList) + { + ui->comboBox_Ant->clear(); + if (my_rig->state.tx_range_list[rigGet.rangeListRxIndex].ant == RIG_ANT_NONE) ui->comboBox_Ant->addItem("NONE"); //RIG_ANT_NONE + else for (i=0; i < RIG_ANT_MAX; i++) + { + if (my_rig->state.tx_range_list[rigGet.rangeListRxIndex].ant & (1UL << i)) + { + switch (i) + { + case 0: ui->comboBox_Ant->addItem("ANT1"); break; //RIG_ANT_1 + case 1: ui->comboBox_Ant->addItem("ANT2"); break; //RIG_ANT_2 + case 2: ui->comboBox_Ant->addItem("ANT3"); break; //RIG_ANT_3 + case 3: ui->comboBox_Ant->addItem("ANT4"); break; //RIG_ANT_4 + case 4: ui->comboBox_Ant->addItem("ANT5"); break; //RIG_ANT_5 + case 30: ui->comboBox_Ant->addItem("UNK"); break; //RIG_ANT_UNKNOWN + case 31: ui->comboBox_Ant->addItem("CURR"); break; //RIG_ANT_CURR + default: ui->comboBox_Ant->addItem("UNK"); break; + } + } + } + rigCmd.antList = 0; + } + + //* Split + if (rigGet.split == RIG_SPLIT_ON) + { + ui->pushButton_Split->setChecked(true); + if (rigGet.vfoSub == rigGet.vfoTx) + { + ui->label_vfoMainRxTx->setText("RX"); + ui->label_vfoSubRxTx->setText("TX"); + } + else + { + ui->label_vfoMainRxTx->setText("TX"); + ui->label_vfoSubRxTx->setText("RX"); + } + } + else + { + ui->pushButton_Split->setChecked(false); + ui->label_vfoMainRxTx->setText("RX TX"); + ui->label_vfoSubRxTx->setText(""); + } + + //* PTT & Meter + if (rigGet.ptt == RIG_PTT_ON) + { + ui->pushButton_PTT->setChecked(true); + + ui->progressBar_Smeter->setTx(true); + ui->progressBar_Smeter->setValue(rigGet.powerMeter.f*100); + ui->progressBar_subMeter->setValue(rigGet.subMeter.f); + } + else + { + ui->pushButton_PTT->setChecked(false); + + ui->progressBar_Smeter->setTx(false); + ui->progressBar_Smeter->setValue(rigGet.sMeter.i); + if (rigSet.meter == RIG_LEVEL_SWR) ui->progressBar_subMeter->setValue(1.0); + else ui->progressBar_subMeter->setValue(0.0); + } + + //* + if (!ui->horizontalSlider_RFpower->isSliderDown()) ui->horizontalSlider_RFpower->setValue((int)(rigGet.rfPower*100)); + + //* + ui->radioButton_Tuner->setChecked(rigGet.tuner); + + ui->checkBox_BKIN->setChecked(rigGet.bkin); + + ui->comboBox_AGC->setCurrentText(rig_stragclevel(rigGet.agc)); + + ui->comboBox_Att->setCurrentText(QString::number(rigGet.att)); + + ui->comboBox_Preamp->setCurrentText(QString::number(rigGet.pre)); +} + + +//* RigDaemon handle results +void MainWindow::on_rigDaemonResultReady() +{ + guiUpdate(); +} + +//* SubMeter +void MainWindow::setSubMeter() +{ + if (rigSet.meter == RIG_LEVEL_SWR) + { + ui->progressBar_subMeter->setMaxValue(5.0); + ui->progressBar_subMeter->setMinValue(1.0); + ui->progressBar_subMeter->setGateValue(2.0); + ui->progressBar_subMeter->setPrecision(1); + ui->progressBar_subMeter->setLongStep(0.5); + ui->progressBar_subMeter->setShortStep(0.1); + ui->progressBar_subMeter->setValue(1); + } + else + { + ui->progressBar_subMeter->setMaxValue(1.0); + ui->progressBar_subMeter->setMinValue(0.0); + ui->progressBar_subMeter->setGateValue(0.5); + ui->progressBar_subMeter->setPrecision(1); + ui->progressBar_subMeter->setLongStep(0.5); + ui->progressBar_subMeter->setShortStep(0.1); + ui->progressBar_subMeter->setValue(0); + } +} + + +//***** PushButton ***** + +void MainWindow::on_pushButton_Connect_toggled(bool checked) +{ + if (checked && rigCom.connected == 0) + { + retcode = rigDaemon->rigConnect(); //Open Rig connection + + if (retcode != RIG_OK) //Connection error + { + rigCom.connected = 0; + ui->statusbar->showMessage(rigerror(retcode)); + ui->pushButton_Connect->setChecked(false); //Uncheck the button + } + else //Rig connected + { + rigCom.connected = 1; + guiInit(); + if (rigCap.onoff == 0 || rigGet.onoff == RIG_POWER_ON) timer->start(rigCom.rigRefresh); + } + } + else if (rigCom.connected) //Button unchecked + { + rigCom.connected = 0; + timer->stop(); + rig_close(my_rig); //Close the communication to the rig + //rig_cleanup(my_rig); //Release rig handle and free associated memory + } +} + +void MainWindow::on_pushButton_Power_toggled(bool checked) +{ + if (checked && !rigGet.onoff) + { + retcode = rig_set_powerstat(my_rig, RIG_POWER_ON); + if (retcode != RIG_OK) + { + ui->pushButton_Power->setChecked(false); //Uncheck the button + ui->statusbar->showMessage(rigerror(retcode)); + } + else timer->start(rigCom.rigRefresh); + } + else if (!checked && rigGet.onoff) + { + retcode = rig_set_powerstat(my_rig, RIG_POWER_OFF); + if (retcode != RIG_OK) + { + ui->pushButton_Power->setChecked(false); //Uncheck the button + timer->stop(); + } + } +} + +void MainWindow::on_pushButton_PTT_toggled(bool checked) +{ + if (checked && !rigGet.ptt) + { + rigSet.ptt = RIG_PTT_ON; + rigCmd.ptt = 1; + } + else if (!checked && rigGet.ptt) + { + rigSet.ptt = RIG_PTT_OFF; + rigCmd.ptt = 1; + } +} + +void MainWindow::on_pushButton_Split_toggled(bool checked) +{ + if (checked && !rigGet.split) + { + rigSet.split = RIG_SPLIT_ON; + rigCmd.split = 1; + } + else if (!checked && rigGet.split) + { + rigSet.split = RIG_SPLIT_OFF; + rigCmd.split = 1; + } +} + +void MainWindow::on_pushButton_QSplit_clicked() +{ + quick_split(); +} + +void MainWindow::on_pushButton_AB_clicked() +{ + rigCmd.vfoXchange = 1; +} + +void MainWindow::on_pushButton_AeqB_clicked() +{ + rigCmd.vfoCopy = 1; +} + +void MainWindow::on_pushButton_Fast_toggled(bool checked) +{ + if (checked) fastDial = 1; + else fastDial = 0; +} + +void MainWindow::on_pushButton_Tune_clicked() +{ + rigCmd.tune = 1; +} + +void MainWindow::on_pushButton_Band160_clicked() +{ + set_band(160); +} + +void MainWindow::on_pushButton_Band80_clicked() +{ + set_band(80); +} + +void MainWindow::on_pushButton_Band60_clicked() +{ + set_band(60); +} + +void MainWindow::on_pushButton_Band40_clicked() +{ + set_band(40); +} + +void MainWindow::on_pushButton_Band30_clicked() +{ + set_band(30); +} + +void MainWindow::on_pushButton_Band20_clicked() +{ + set_band(20); +} + +void MainWindow::on_pushButton_Band17_clicked() +{ + set_band(17); +} + +void MainWindow::on_pushButton_Band15_clicked() +{ + set_band(15); +} + +void MainWindow::on_pushButton_Band12_clicked() +{ + set_band(12); +} + +void MainWindow::on_pushButton_Band10_clicked() +{ + set_band(10); +} + +void MainWindow::on_pushButton_Band6_clicked() +{ + set_band(6); +} + +void MainWindow::on_pushButton_Band2_clicked() +{ + set_band(2); +} + +void MainWindow::on_pushButton_Band70_clicked() +{ + set_band(70); +} + +void MainWindow::on_pushButton_BandGen_clicked() +{ + set_band(1); +} + +void MainWindow::on_pushButton_BandDown_clicked() +{ + rigCmd.bandDown = 1; +} + +void MainWindow::on_pushButton_BandUp_clicked() +{ + rigCmd.bandUp = 1; +} + +//***** CheckBox ***** + +void MainWindow::on_checkBox_NAR_toggled(bool checked) +{ + if (checked && !rigGet.bwNarrow) + { + rigSet.bwidth = rig_passband_narrow(my_rig, rigGet.mode); + rigCmd.bwidth = 1; + } + else if (!checked && rigGet.bwNarrow) + { + rigSet.bwidth = RIG_PASSBAND_NORMAL; + rigCmd.bwidth = 1; + } +} + +void MainWindow::on_checkBox_BKIN_toggled(bool checked) +{ + if (checked && !rigGet.bkin) + { + rigSet.bkin = 1; + rigCmd.bkin = 1; + } + else if (!checked && rigGet.bkin) + { + rigSet.bkin = 0; + rigCmd.bkin = 1; + } +} + +void MainWindow::on_checkBox_NB_toggled(bool checked) +{ + if (checked && !rigGet.noiseBlanker) + { + rigSet.noiseBlanker = 1; + rigCmd.noiseBlanker = 1; + } + else if (!checked && rigGet.noiseBlanker) + { + rigSet.noiseBlanker = 0; + rigCmd.noiseBlanker = 1; + } +} + +void MainWindow::on_checkBox_NR_toggled(bool checked) +{ + if (checked && !rigGet.noiseReduction) + { + rigSet.noiseReduction = 1; + rigCmd.noiseReduction = 1; + } + else if (!checked && rigGet.noiseReduction) + { + rigSet.noiseReduction = 0; + rigCmd.noiseReduction = 1; + } +} + +void MainWindow::on_checkBox_NF_toggled(bool checked) +{ + if (checked && !rigGet.notchFilter) + { + rigSet.notchFilter = 1; + rigCmd.notchFilter = 1; + } + else if (!checked && rigGet.notchFilter) + { + rigSet.notchFilter = 0; + rigCmd.notchFilter = 1; + } +} + + +//***** RadioButton ***** + +void MainWindow::on_radioButton_Tuner_toggled(bool checked) +{ + if (checked && !rigGet.tuner) + { + rigSet.tuner = 1; + rigCmd.tuner = 1; + } + else if (!checked && rigGet.tuner) + { + rigSet.tuner = 0; + rigCmd.tuner = 1; + } +} + + +//***** Dial ***** + +void MainWindow::on_dial_valueChanged(int value) +{ + int step; + + step = value - prevDial; + if (step<=99 && step>50) step = value - 100 - prevDial; + if (step>=-99 && step<-50) step = value + 100 - prevDial; + prevDial = value; + + if (ui->radioButton_VFOSub->isChecked()) //dial VFO Sub + { + rigSet.freqSub = rigGet.freqSub + step*(!fastDial*10+fastDial*100); + rigCmd.freqSub = 1; + } + else //dial VFO Main + { + rigSet.freqMain = rigGet.freqMain + step*(!fastDial*10+fastDial*100); + rigCmd.freqMain = 1; + } +} + +void MainWindow::on_vfoDisplayValueChanged(int value) +{ + rigSet.freqMain = value; + rigCmd.freqMain = 1; +} + +//***** ComboBox ***** + +void MainWindow::on_comboBox_Mode_activated(int index) +{ + rigSet.mode = rig_parse_mode(ui->comboBox_Mode->itemText(index).toLatin1()); + rigCmd.mode = 1; +} + +void MainWindow::on_comboBox_BW_activated(int index) +{ + rigSet.bwidth = ui->comboBox_BW->itemText(index).toInt(); + rigCmd.bwidth = 1; +} + +void MainWindow::on_comboBox_AGC_activated(int index) +{ + rigSet.agc = levelagcstr(ui->comboBox_AGC->itemText(index)); + rigCmd.agc = 1; +} + +void MainWindow::on_comboBox_Att_activated(int index) +{ + rigSet.att = ui->comboBox_Att->itemText(index).toInt(); + rigCmd.att = 1; +} + +void MainWindow::on_comboBox_Preamp_activated(int index) +{ + rigSet.pre = ui->comboBox_Preamp->itemText(index).toInt(); + rigCmd.pre = 1; +} + +void MainWindow::on_comboBox_Ant_activated(int index) +{ + rigSet.ant = antstr(ui->comboBox_Ant->itemText(index)); + rigCmd.ant = 1; +} + +void MainWindow::on_comboBox_Meter_activated(int index) +{ + rigSet.meter = levelmeterstr (ui->comboBox_Meter->itemText(index)); + setSubMeter(); +} + + +//***** Spin Box ***** + +void MainWindow::on_spinBox_NR_valueChanged(int arg1) +{ + rigSet.noiseReductionLevel = arg1; + rigCmd.noiseReductionLevel = 1; +} + + +//***** Slider ***** + +void MainWindow::on_horizontalSlider_RFpower_valueChanged(int value) +{ + if (!rigCmd.rfPower) + { + if (value < 5) value = 5; + rigSet.rfPower = (float)(value)/100; + if (rigSet.rfPower != rigGet.rfPower) rigCmd.rfPower = 1; + } +} + +void MainWindow::on_horizontalSlider_RFgain_valueChanged(int value) +{ + if (!rigCmd.rfGain) + { + rigSet.rfGain = (float)(value)/100; + if (rigSet.rfGain != rigGet.rfGain) rigCmd.rfGain = 1; + } +} + +void MainWindow::on_horizontalSlider_IFshift_valueChanged(int value) +{ + if (!rigCmd.ifShift) + { + rigSet.ifShift = value; + if (rigSet.ifShift != rigGet.ifShift) rigCmd.ifShift = 1; + } +} + + +//***** Menu ***** + +void MainWindow::on_action_Connection_triggered() +{ + DialogConfig config; + config.setModal(true); + config.exec(); +} + +void MainWindow::on_action_Setup_triggered() +{ + DialogSetup setup; + setup.setModal(true); + setup.exec(); +} + +void MainWindow::on_action_AboutCatRadio_triggered() +{ + QMessageBox msgBox; + msgBox.setWindowTitle("About"); + msgBox.setTextFormat(Qt::RichText); + QString version = QString::number(VERSION_MAJ)+"."+QString::number(VERSION_MIN)+"."+QString::number(VERSION_MIC); + msgBox.setText("CatRadio Radio control software
version "+version+" "+RELEASE_DATE); + msgBox.setInformativeText("Copyright (C) 2022 Gianfranco Sordetti IZ8EWD
" + "www.pianetaradio.it

" + "

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
" + "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
" + "You should have received a copy of the GNU General Public License along with this program. If not, see www.gnu.org/licenses."); + msgBox.setIcon(QMessageBox::NoIcon); + msgBox.setStandardButtons(QMessageBox::Ok); + + QPixmap icon("catradio.png"); + msgBox.setIconPixmap(icon); + + msgBox.exec(); +} + +void MainWindow::on_action_AboutQT_triggered() +{ + QMessageBox::aboutQt(this); +} + +void MainWindow::on_action_AboutHamLib_triggered() +{ + QMessageBox msgBox; + msgBox.setWindowTitle("About Hamlib"); + msgBox.setText(rig_version()); + msgBox.setInformativeText(rig_copyright()); + //msgBox.setDetailedText(rig_license()); + msgBox.setIcon(QMessageBox::Information); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.exec(); +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..a095a46 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,153 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +#define RELEASE_DATE __DATE__ +#define VERSION_MAJ 1 +#define VERSION_MIN 0 +#define VERSION_MIC 0 + + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +public slots: + void guiUpdate(); + void on_rigDaemonResultReady(); //Slot for rigDaemon resultReady + void on_vfoDisplayValueChanged(int value); //Slot for vfoDisplay valueChanged + +signals: + +private slots: + void on_pushButton_Connect_toggled(bool checked); + void on_pushButton_Power_toggled(bool checked); + void on_pushButton_PTT_toggled(bool checked); + void on_pushButton_Split_toggled(bool checked); + void on_pushButton_AB_clicked(); + void on_pushButton_AeqB_clicked(); + + void on_dial_valueChanged(int value); + + void on_action_AboutQT_triggered(); + void on_action_AboutHamLib_triggered(); + + + + void on_comboBox_Mode_activated(int index); + + void on_pushButton_Fast_toggled(bool checked); + + void on_horizontalSlider_RFpower_valueChanged(int value); + + void on_pushButton_Band160_clicked(); + + void on_pushButton_Band80_clicked(); + + void on_pushButton_Band60_clicked(); + + void on_pushButton_Band40_clicked(); + + void on_pushButton_Band30_clicked(); + + void on_pushButton_Band20_clicked(); + + void on_pushButton_Band17_clicked(); + + void on_pushButton_Band15_clicked(); + + void on_pushButton_Band12_clicked(); + + void on_pushButton_Band10_clicked(); + + void on_pushButton_Band6_clicked(); + + void on_pushButton_Tune_clicked(); + + void on_radioButton_Tuner_toggled(bool checked); + + void on_pushButton_BandDown_clicked(); + + void on_pushButton_BandUp_clicked(); + + void on_pushButton_QSplit_clicked(); + + void on_action_Connection_triggered(); + + void on_comboBox_BW_activated(int index); + + void on_checkBox_NAR_toggled(bool checked); + + void on_checkBox_BKIN_toggled(bool checked); + + void on_comboBox_AGC_activated(int index); + + void on_comboBox_Att_activated(int index); + + void on_comboBox_Preamp_activated(int index); + + void on_comboBox_Ant_activated(int index); + + void on_action_AboutCatRadio_triggered(); + + void on_checkBox_NB_toggled(bool checked); + + void on_checkBox_NR_toggled(bool checked); + + void on_checkBox_NF_toggled(bool checked); + + void on_comboBox_Meter_activated(int index); + + void on_horizontalSlider_RFgain_valueChanged(int value); + + void on_spinBox_NR_valueChanged(int arg1); + + void on_horizontalSlider_IFshift_valueChanged(int value); + + void on_pushButton_Band2_clicked(); + + void on_pushButton_Band70_clicked(); + + void on_pushButton_BandGen_clicked(); + + void on_action_Setup_triggered(); + +private: + Ui::MainWindow *ui; + QTimer *timer; + + void guiInit(); + void setSubMeter(); +}; + +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..eb08f7b --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,1353 @@ + + + MainWindow + + + true + + + + 0 + 0 + 600 + 560 + + + + CatRadio + + + + catradio.icocatradio.ico + + + + + + 10 + 10 + 91 + 401 + + + + + + + Connect + + + true + + + + + + + Power + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Tuner + + + + + + + Tune + + + + + + + Antenna + + + comboBox_Ant + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + AGC + + + comboBox_AGC + + + + + + + + + + Attenuator + + + comboBox_Att + + + + + + + + + + Preamp + + + comboBox_Preamp + + + + + + + + + + + true + + + + 110 + 80 + 481 + 131 + + + + QFrame::Box + + + QFrame::Raised + + + 0 + + + + + 200 + 10 + 40 + 16 + + + + VFO + + + + + + 400 + 10 + 40 + 16 + + + + VFO + + + + + true + + + + 10 + 60 + 81 + 24 + + + + + + + 100 + 60 + 81 + 24 + + + + + + + 10 + 100 + 80 + 20 + + + + A / B + + + + + + 100 + 100 + 80 + 20 + + + + A = B + + + + + + 190 + 100 + 80 + 20 + + + + Split + + + true + + + + + + 280 + 100 + 80 + 20 + + + + Q Split + + + + + + 200 + 30 + 41 + 16 + + + + RX TX + + + + + + 400 + 30 + 41 + 16 + + + + RX TX + + + + + true + + + + 250 + 10 + 140 + 40 + + + + + 0 + 0 + + + + + 18 + + + + Qt::RightToLeft + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + true + + + + 250 + 60 + 81 + 24 + + + + false + + + + + + 10 + 9 + 181 + 41 + + + + + + + + 110 + 220 + 151 + 191 + + + + Band + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 1.8 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 3.5 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 5.3 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 7 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 10 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 14 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 18 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 21 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 24.5 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 28 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + Gen + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 50 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + << + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 144 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + 430 + + + + + + + + 0 + 0 + + + + + 20 + 20 + + + + + 16 + 16 + + + + >> + + + + + + + + + 470 + 230 + 121 + 181 + + + + Filter + + + + + 10 + 30 + 51 + 22 + + + + Noise Blanking + + + NB + + + + + + 10 + 60 + 51 + 22 + + + + Noise Reduction + + + NR + + + + + + 10 + 90 + 51 + 22 + + + + Notch Filter + + + NF + + + + + + 70 + 60 + 46 + 25 + + + + 1 + + + 15 + + + + + + 10 + 120 + 51 + 22 + + + + BW Narrow + + + NAR + + + + + + 10 + 160 + 101 + 18 + + + + -1200 + + + 1200 + + + 10 + + + 100 + + + false + + + Qt::Horizontal + + + + + + 10 + 150 + 55 + 16 + + + + IF-Shift + + + horizontalSlider_IFshift + + + + + true + + + + 40 + 140 + 41 + 16 + + + + 0 + + + Qt::AlignCenter + + + + + + + 470 + 420 + 120 + 91 + + + + CW + + + + + 10 + 30 + 71 + 22 + + + + Break-In + + + BK IN + + + + + + 10 + 60 + 71 + 22 + + + + APF + + + + + + + 270 + 220 + 191 + 191 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 150 + 171 + 31 + + + + PTT + + + \ + + + true + + + + + + 20 + 0 + 150 + 150 + + + + 100 + + + false + + + true + + + 10.000000000000000 + + + false + + + + + + 10 + 110 + 31 + 25 + + + + Fast + + + true + + + + + + 10 + 0 + 51 + 22 + + + + Main + + + true + + + + + + 130 + 0 + 51 + 22 + + + + Qt::RightToLeft + + + Sub + + + + + + + 110 + 9 + 481 + 61 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 0 + 0 + 191 + 61 + + + + + + + 250 + 0 + 151 + 61 + + + + + + + 400 + 20 + 75 + 24 + + + + + + + + 10 + 420 + 451 + 91 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 55 + 16 + + + + RF Gain + + + horizontalSlider_RFgain + + + + + + 10 + 50 + 55 + 16 + + + + RF Power + + + horizontalSlider_RFpower + + + + + + 60 + 10 + 200 + 20 + + + + 0 + + + 100 + + + 100 + + + true + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 10 + + + + + + 60 + 50 + 200 + 20 + + + + 0 + + + 100 + + + 100 + + + true + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 10 + + + + + true + + + + 270 + 10 + 31 + 16 + + + + 100 + + + + + true + + + + 270 + 50 + 31 + 16 + + + + 100 + + + + frame_2 + frame + verticalLayoutWidget + groupBox_Band + groupBox_filter + groupBox_CW + frame_3 + frame_4 + + + + + 0 + 0 + 600 + 25 + + + + + Config + + + + + + + Help + + + + + + + + + + + + Connection + + + + + About CatRadio + + + + + About HamLib + + + + + About QT + + + + + Setup + + + + + + SMeter + QWidget +

smeter.h
+ 1 + + + SubMeter + QWidget +
submeter.h
+ 1 +
+ + vfoDisplay + QWidget +
vfodisplay.h
+ 1 +
+ + + + diff --git a/rigcommand.cpp b/rigcommand.cpp new file mode 100644 index 0000000..a56a9c5 --- /dev/null +++ b/rigcommand.cpp @@ -0,0 +1,153 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "rigcommand.h" +#include "rigdata.h" + +#include //Hamlib + +#include + +extern rigSettings rigGet; +extern rigSettings rigSet; +extern rigCommand rigCmd; +extern rigCommand rigCap; + +void set_band (int band) +{ + freq_t freq; + + switch (band) + { + case 160: freq = 1840000; break; + case 80: freq = 3600000; break; + case 60: freq = 5355000; break; + case 40: freq = 7100000; break; + case 30: freq = 10130000; break; + case 20: freq = 14100000; break; + case 17: freq = 18120000; break; + case 15: freq = 21150000; break; + case 12: freq = 24940000; break; + case 10: freq = 28320000; break; + case 6: freq = 50150000; break; + case 2: freq = 144300000; break; + case 70: freq = 432200000; break; + default: freq = rigSet.freqMain; break; + } + + rigSet.freqMain = freq; + rigCmd.freqMain = 1; + rigCmd.bandChange = 1; +} + +void quick_split () +{ + if (rigGet.vfoMain == RIG_VFO_A) + { + rigSet.freqSub = rigGet.freqMain + 5000; + //rigSet.modeSub = rigGet.modeMain; + rigCmd.freqSub = 1; + //rigCmd.modeSub = 1; + } + else + { + rigSet.freqMain = rigGet.freqSub + 5000; + rigCmd.freqMain = 1; + } + rigCmd.split = 1; +} + +agc_level_e levelagcvalue (int agcValue) +{ + agc_level_e agcLevel; + + switch (agcValue) + { + case 0: agcLevel = RIG_AGC_OFF; break; + case 1: agcLevel = RIG_AGC_SUPERFAST; break; + case 2: agcLevel = RIG_AGC_FAST; break; + case 3: agcLevel = RIG_AGC_SLOW; break; + case 4: agcLevel = RIG_AGC_USER; break; + case 5: agcLevel = RIG_AGC_MEDIUM; break; + case 6: agcLevel = RIG_AGC_AUTO; break; + default: agcLevel = RIG_AGC_AUTO; break; + } + + return agcLevel; +} + +agc_level_e levelagcstr (QString agcString) +{ + agc_level_e agcLevel; + + if (agcString == "OFF") agcLevel = RIG_AGC_OFF; + else if (agcString == "SUPERFAST") agcLevel = RIG_AGC_SUPERFAST; + else if (agcString == "FAST") agcLevel = RIG_AGC_FAST; + else if (agcString == "SLOW") agcLevel = RIG_AGC_SLOW; + else if (agcString == "USER") agcLevel = RIG_AGC_USER; + else if (agcString == "MEDIUM") agcLevel = RIG_AGC_MEDIUM; + else agcLevel = RIG_AGC_AUTO; + + return agcLevel; +} + +value_t valueagclevel (agc_level_e agcLevel) +{ + value_t value; + + if (agcLevel == RIG_AGC_OFF) value.i = 0; + else if (agcLevel == RIG_AGC_SUPERFAST) value.i = 1; + else if (agcLevel == RIG_AGC_FAST) value.i = 2; + else if (agcLevel == RIG_AGC_SLOW) value.i = 3; + else if (agcLevel == RIG_AGC_USER) value.i = 4; + else if (agcLevel == RIG_AGC_MEDIUM) value.i = 5; + else value.i = 6; //RIG_AGC_AUTO + + return value; +} + +ant_t antstr (QString antString) +{ + ant_t ant; + + if (antString == "NONE") ant = RIG_ANT_NONE; + else if (antString == "ANT1") ant = RIG_ANT_1; + else if (antString == "ANT2") ant = RIG_ANT_2; + else if (antString == "ANT3") ant = RIG_ANT_3; + else if (antString == "ANT4") ant = RIG_ANT_4; + else if (antString == "ANT5") ant = RIG_ANT_5; + else if (antString == "UNK") ant = RIG_ANT_UNKNOWN; + else if (antString == "CURR") ant = RIG_ANT_CURR; + else ant = RIG_ANT_UNKNOWN; + + return ant; +} + +unsigned levelmeterstr (QString meterString) +{ + unsigned levelMeter; + + if (meterString == "SWR") levelMeter = RIG_LEVEL_SWR; + else if (meterString == "COMP") levelMeter = RIG_LEVEL_COMP; + else if (meterString == "ALC") levelMeter = RIG_LEVEL_ALC; + //... + else levelMeter = RIG_METER_NONE; + + return levelMeter; +} diff --git a/rigcommand.h b/rigcommand.h new file mode 100644 index 0000000..7c76aeb --- /dev/null +++ b/rigcommand.h @@ -0,0 +1,36 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#ifndef RIGCOMMAND_H +#define RIGCOMMAND_H + +#endif // RIGCOMMAND_H + +#include + +#include + + +void set_band (int band); +void quick_split (); +agc_level_e levelagcvalue (int agcValue); +agc_level_e levelagcstr (QString agcString); +value_t valueagclevel (agc_level_e agcLevel); +ant_t antstr (QString antString); +unsigned levelmeterstr (QString meterString); diff --git a/rigdaemon.cpp b/rigdaemon.cpp new file mode 100644 index 0000000..408a278 --- /dev/null +++ b/rigdaemon.cpp @@ -0,0 +1,424 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "rigdaemon.h" +#include "rigdata.h" +#include "rigcommand.h" + +#include +#include +#include + +#include + + +RIG *my_rig; + +extern rigConnect rigCom; +extern rigSettings rigGet; +extern rigSettings rigSet; +extern rigCommand rigCmd; +extern rigCommand rigCap; + +int commandPriority = 0; + + +RigDaemon::RigDaemon(QObject *parent) : QObject(parent) +{ + +} + +int RigDaemon::rigConnect() +{ + int retcode; + + my_rig = rig_init(rigCom.rigModel); //Allocate rig handle + + if (!my_rig) //Wrong Rig number + { + QMessageBox msgBox; //Show error MessageBox + msgBox.setWindowTitle("Warning"); + msgBox.setText("Rig model error"); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.exec(); + + return -1; //RIG_EINVAL, Invalid parameter + } + else + { + if (rigCom.rigModel == 2) //Rigctld + { + //myport.type.rig = RIG_PORT_NETWORK; + strncpy(my_rig->state.rigport.pathname, rigCom.rigPort.toLatin1(), HAMLIB_FILPATHLEN - 1); + //strncpy(my_rig->state.rigport.pathname, RIG_FILE, HAMLIB_FILPATHLEN - 1); + } + else + { + //myport.type.rig = RIG_PORT_SERIAL; + strncpy(my_rig->state.rigport.pathname, rigCom.rigPort.toLatin1(), HAMLIB_FILPATHLEN - 1); + my_rig->state.rigport.parm.serial.rate = rigCom.serialSpeed; + if (rigCom.civAddr) //CI-V address Icom + { + std::string civaddrS = std::to_string(rigCom.civAddr); //Convert int to string + char const *civaddr = civaddrS.c_str(); //Convert string to char* + rig_set_conf(my_rig, rig_token_lookup(my_rig, "civaddr"), civaddr); + } + } + + retcode = rig_open(my_rig); + + if (retcode != RIG_OK) return retcode; //Rig not connected + else //Rig connected + { + rig_get_powerstat(my_rig, &rigGet.onoff); + return 0; + } + + } +} + +void RigDaemon::rigUpdate() +{ + int retcode; + value_t retvalue; + + //***** Command execution ***** + //* PTT + if (rigCmd.ptt) + { + retcode = rig_set_ptt(my_rig, RIG_VFO_CURR, rigSet.ptt); + if (retcode == RIG_OK) rigGet.ptt = rigSet.ptt; + rigCmd.ptt = 0; + } + + //* VFO + if (rigCmd.freqMain) //VFO Main + { + retcode = rig_set_freq(my_rig, RIG_VFO_CURR, rigSet.freqMain); + if (retcode == RIG_OK) rigGet.freqMain = rigSet.freqMain; + rigCmd.freqMain = 0; + rigCmd.rangeList = 1; + } + + else if (rigCmd.freqSub) //VFO Sub + { + retcode = rig_set_freq(my_rig, rigGet.vfoSub, rigSet.freqSub); + if (retcode == RIG_OK) rigGet.freqSub = rigSet.freqSub; + rigCmd.freqSub = 0; + } + + else + { + freq_t retfreq; + retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &retfreq); + if (retcode == RIG_OK) rigGet.freqMain = retfreq; + retcode = rig_get_freq(my_rig, rigGet.vfoSub, &retfreq); + if (retcode == RIG_OK) rigGet.freqSub = retfreq; + + ptt_t retptt; + retcode = rig_get_ptt(my_rig, RIG_VFO_CURR, &retptt); + if (retcode == RIG_OK) rigGet.ptt = retptt; + + //* Meter + if (rigGet.ptt==1) + { + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER_METER, &rigGet.powerMeter); + rig_get_level(my_rig, RIG_VFO_CURR, rigSet.meter, &rigGet.subMeter); + } + else + { + retcode = rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_STRENGTH, &retvalue); + if (retcode == RIG_OK) rigGet.sMeter = retvalue; + } + + if (!rigGet.ptt) + { + //* Mode + if (rigCmd.mode) + { + retcode = rig_set_mode(my_rig, RIG_VFO_CURR, rigSet.mode, RIG_PASSBAND_NOCHANGE); + if (retcode == RIG_OK) + { + rigCmd.bwidthList = 1; //Update BWidth list + commandPriority = 0; + //rig_get_mode(my_rig, RIG_VFO_CURR, &rigGet.mode, &rigGet.bwidth); //Get BW + } + rigCmd.mode = 0; + } + + //* BandWidth + if (rigCmd.bwidth) + { + retcode = rig_set_mode(my_rig, RIG_VFO_CURR, rigGet.mode, rigSet.bwidth); + if (retcode == RIG_OK) rigGet.bwidth = rigSet.bwidth; + rigCmd.bwidth = 0; + } + + //* Split + if (rigCmd.split) + { + retcode = rig_set_split_vfo(my_rig, RIG_VFO_RX, rigSet.split, RIG_VFO_TX); + if (retcode == RIG_OK) rigGet.split = rigSet.split; + rigCmd.split = 0; + } + + //* VFO Exchange + if (rigCmd.vfoXchange) + { + retcode = rig_vfo_op(my_rig, RIG_VFO_CURR, RIG_OP_XCHG); + if (retcode == RIG_OK) commandPriority = 0; + rigCmd.vfoXchange = 0; + } + + //* VFO Copy + if (rigCmd.vfoCopy) + { + rig_vfo_op(my_rig, RIG_VFO_CURR, RIG_OP_CPY); + rigCmd.vfoCopy = 0; + } + + //* Band Up + if (rigCmd.bandUp) + { + retcode = rig_vfo_op(my_rig, RIG_VFO_CURR, RIG_OP_BAND_UP); + if (retcode == RIG_OK) commandPriority = 0; + rigCmd.bandUp = 0; + } + + //* Band Down + if (rigCmd.bandDown) + { + retcode = rig_vfo_op(my_rig, RIG_VFO_CURR, RIG_OP_BAND_DOWN); + if (retcode == RIG_OK) commandPriority = 0; + rigCmd.bandDown = 0; + } + + //* Band change + if (rigCmd.bandChange) commandPriority = 0; + + //* Tune + if (rigCmd.tune) + { + rig_vfo_op(my_rig, RIG_VFO_CURR, RIG_OP_TUNE); + rigCmd.tune = 0; + } + + //* Antenna + if (rigCmd.ant) + { + retcode = rig_set_ant(my_rig, RIG_VFO_CURR, rigSet.ant, retvalue); + if (retcode == RIG_OK) rigGet.ant = rigSet.ant; + rigCmd.ant = 0; + } + + //* AGC + if (rigCmd.agc) + { + retcode = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_AGC, valueagclevel(rigSet.agc)); + if (retcode == RIG_OK) rigGet.agc = rigSet.agc; + rigCmd.agc = 0; + } + + //* Attenuator + if (rigCmd.att) + { + retvalue.i = rigSet.att; + retcode = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_ATT, retvalue); + if (retcode == RIG_OK) rigGet.att = rigSet.att; + rigCmd.att = 0; + } + + //* Preamp + if (rigCmd.pre) + { + retvalue.i = rigSet.pre; + retcode = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, retvalue); + if (retcode == RIG_OK) rigGet.pre = rigSet.pre; + rigCmd.pre = 0; + } + + //* RF gain + if (rigCmd.rfGain) + { + retvalue.f = rigSet.rfGain; + retcode = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_RF, retvalue); + if (retcode == RIG_OK) rigGet.rfGain = rigSet.rfGain; + rigCmd.rfGain = 0; + } + + //* NB noise blanker + if (rigCmd.noiseBlanker) + { + retcode = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NB, rigSet.noiseBlanker); + if (retcode == RIG_OK) rigGet.noiseBlanker = rigSet.noiseBlanker; + rigCmd.noiseBlanker = 0; + } + + //* NR noise reduction + if (rigCmd.noiseReduction) + { + retcode = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NR, rigSet.noiseReduction); + if (retcode == RIG_OK) rigGet.noiseReduction = rigSet.noiseReduction; + rigCmd.noiseReduction = 0; + } + + if (rigCmd.noiseReductionLevel) + { + retvalue.i = rigSet.noiseReductionLevel; + retcode = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_NR, retvalue); + if (retcode == RIG_OK) rigGet.noiseReductionLevel = rigSet.noiseReductionLevel; + rigCmd.noiseReductionLevel = 0; + } + + //* NF notch filter + if (rigCmd.notchFilter) + { + retcode = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_ANF, rigSet.notchFilter); + if (retcode == RIG_OK) rigGet.notchFilter = rigSet.notchFilter; + rigCmd.notchFilter = 0; + } + + //* IF Shift + if (rigCmd.ifShift) + { + retvalue.i = rigSet.ifShift; + retcode = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_IF, retvalue); + if (retcode == RIG_OK) rigGet.ifShift = rigSet.ifShift; + rigCmd.ifShift = 0; + } + } //end if (!rigGet.ptt) + + //* Tuner + if (rigCmd.tuner) + { + retcode = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_TUNER, rigSet.tuner); + if (retcode == RIG_OK) rigGet.tuner = rigSet.tuner; + rigCmd.tune = 0; + } + + //* RF power + if (rigCmd.rfPower) + { + retvalue.f = rigSet.rfPower; + retcode = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER, retvalue); + if (retcode == RIG_OK) rigGet.rfPower = rigSet.rfPower; + rigCmd.rfPower = 0; + } + + //***** Poll execution ***** + if ((commandPriority == 1 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + //* Mode and BW + rig_get_mode(my_rig, RIG_VFO_CURR, &rigGet.mode, &rigGet.bwidth); + //rig_get_mode(my_rig, rigGet.vfoSub, &rigGet.modeSub, &rigGet.bwidthSub); + if (rigGet.bwidth == rig_passband_narrow(my_rig, rigGet.mode)) rigGet.bwNarrow = 1; + else rigGet.bwNarrow = 0; + } + + if ((commandPriority == 2 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + //* Split + rig_get_split_vfo(my_rig, RIG_VFO_CURR, &rigGet.split, &rigGet.vfoTx); + //else rig_get_split(my_rig, RIG_VFO_CURR, &rigGet.split); + + rig_get_vfo(my_rig, &rigGet.vfoMain); + } + + //* Tuner + if ((commandPriority == 3 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_TUNER, &rigGet.tuner); + + //* Antenna + if ((commandPriority == 4 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) rig_get_ant(my_rig, RIG_VFO_CURR, RIG_ANT_CURR, &retvalue, &rigGet.ant, &rigGet.antTx, &rigGet.antRx); + + //* AGC + if ((commandPriority == 5 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_AGC, &retvalue); + rigGet.agc = levelagcvalue(retvalue.i); + } + + //* Attenuator + if ((commandPriority == 6 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_ATT, &retvalue); + rigGet.att = retvalue.i; + } + + //* Preamp + if ((commandPriority == 7 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, &retvalue); + rigGet.pre = retvalue.i; + } + + //* RF power + if ((commandPriority == 8 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER, &retvalue); + rigGet.rfPower = retvalue.f; + } + + //* RF gain + if ((commandPriority == 9 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_RF, &retvalue); + rigGet.rfGain = retvalue.f; + } + + //* NB noise blanker + if ((commandPriority == 10 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NB, &rigGet.noiseBlanker); + + //* NR noise reduction + if ((commandPriority == 11 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_NR, &rigGet.noiseReduction); + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_NR, &retvalue); + rigGet.noiseReductionLevel = retvalue.i; + } + + //* NF notch filter + if ((commandPriority == 12 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_ANF, &rigGet.notchFilter); + + //* IF Shift + if ((commandPriority == 13 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) + { + rig_get_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_IF, &retvalue); + rigGet.ifShift = retvalue.i; + } + + if ((commandPriority == 14 && !rigGet.ptt && rigCom.fullPoll) || commandPriority == 0) //&& mode=CW + { + //* CW Full Break-in + if (rigCmd.bkin) + { + retcode = rig_set_func(my_rig, RIG_VFO_CURR, RIG_FUNC_FBKIN, rigSet.bkin); + if (retcode == RIG_OK) rigGet.bkin = rigSet.bkin; + rigCmd.bkin = 0; + } + else rig_get_func(my_rig, RIG_VFO_CURR, RIG_FUNC_FBKIN, &rigGet.bkin); + } + + commandPriority ++; + if (commandPriority == 15) commandPriority = 1; + + } + + emit resultReady(); +} diff --git a/rigdaemon.h b/rigdaemon.h new file mode 100644 index 0000000..4020535 --- /dev/null +++ b/rigdaemon.h @@ -0,0 +1,42 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#ifndef RIGDAEMON_H +#define RIGDAEMON_H + +#include +#include + +class RigDaemon : public QObject +{ + Q_OBJECT + +public: + explicit RigDaemon(QObject *parent = nullptr); + int rigConnect(); + +public slots: + void rigUpdate(); + +signals: + void resultReady(); + +}; + +#endif // RIGDAEMON_H diff --git a/rigdata.cpp b/rigdata.cpp new file mode 100644 index 0000000..84560e7 --- /dev/null +++ b/rigdata.cpp @@ -0,0 +1,26 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "rigdata.h" + +rigConnect rigCom; +rigSettings rigGet; +rigSettings rigSet; +rigCommand rigCmd; +rigCommand rigCap; diff --git a/rigdata.h b/rigdata.h new file mode 100644 index 0000000..87fe302 --- /dev/null +++ b/rigdata.h @@ -0,0 +1,100 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#ifndef RIGDATA_H +#define RIGDATA_H + +#endif // RIGDATA_H + +#include //Hamlib + +#include + +typedef struct { + unsigned rigModel; //Hamlib rig model + QString rigPort; //COM port or IP address + unsigned serialSpeed; //Serial port baud rate + int civAddr; //CI-V address (decimal, Icom radio) + unsigned rigRefresh; //GUI refresh interval (ms) + int connected; //connected flag + bool fullPoll; //full polling flag +} rigConnect; + +typedef struct { + powerstat_t onoff; //on/off status + freq_t freqMain, freqSub; //Frequency + rmode_t mode, modeSub; //Mode + pbwidth_t bwidth, bwidthSub; //IF filter bandwidth + int bwNarrow; //IF narrow filter + vfo_t vfoMain, vfoSub; //VFO + vfo_t vfoTx; + split_t split; //Split + ptt_t ptt; //PTT + value_t sMeter; //Smeter signal strenght + value_t powerMeter; //RF power meter + value_t subMeter; //secondary meter + unsigned meter; //secondary meter type + float rfPower; //RF power output level + float rfGain; //RF gain rx + agc_level_e agc; //AGC level + int att; //Attenuator + int pre; //Preamplifier + ant_t ant, antTx, antRx; //Antenna + int rangeListTxIndex, rangeListRxIndex; + int tuner; //Tuner + int bkin; //CW Break-in + int apf; + int noiseBlanker; + int noiseReduction, noiseReductionLevel; + int notchFilter; + int ifShift; +} rigSettings; + +typedef struct { + int onoff; + int freqMain; + int freqSub; + int mode; + int bwidth; + int bwidthList; + int vfo; + int split; + int vfoXchange; + int vfoCopy; + int ptt; + int rfPower; + int rfGain; + int agc; + int att; + int pre; + int ant; + int antList; + int rangeList; + int tuner; + int tune; + int bandUp; + int bandDown; + int bandChange; + int bkin; + int apf; + int noiseBlanker; + int noiseReduction, noiseReductionLevel; + int notchFilter; + int ifShift; +} rigCommand; diff --git a/smeter.cpp b/smeter.cpp new file mode 100644 index 0000000..442f1a8 --- /dev/null +++ b/smeter.cpp @@ -0,0 +1,318 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "smeter.h" +#include + +SMeter::SMeter(QWidget *parent) : QWidget(parent) +{ + lineColor = QColor(Qt::black); + bgColor = QColor(Qt::white); + progressColor = QColor(Qt::green); + + //Default value + minValue = 0; + maxValue = 100; + gateValue = 80; + longStep = 20; + shortStep = 10; + precision = 0; + + meterTx = 0; + + currentValue = -54; +} + +void SMeter::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + + QFont font; + font = painter.font(); + font.setPointSize(font.pointSize() - 2); + painter.setFont(font); + + drawMeter(&painter); + drawProgress(&painter); + drawScaleSMeter(&painter); + drawScalePWRMeter(&painter); +} + +void SMeter::drawMeter(QPainter *painter) +{ + painter->save(); + + QPen pen(lineColor, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + painter->setPen(pen); + painter->setBrush(bgColor); + painter->drawRect(0, height()/3+2, width()-12, height()/3-4); + painter->restore(); +} + +void SMeter::drawProgress(QPainter *painter) +{ + double max, min; + double gate; + + painter->save(); + painter->setPen(Qt::NoPen); + painter->setBrush(progressColor); + + if (meterTx) //RF power meter + { + max = maxValue; + min = minValue; + gate = gateValue; + } + else //SMeter + { + max = 60; + min = -54; + gate = 0; + } + + double length = width()-14; + double increment = length / (max - min); + double initX, initXX; + + if (currentValue>gate) + { + initX = (gate - min) * increment; + QRect rect(1, height()/3+2+1, initX, height()/3-4-2); + painter->drawRect(rect); + + //Red bar + initXX = (currentValue - gate) * increment; + QRect rect2(initX+1, height()/3+2+1, initXX, height()/3-4-2); + painter->setBrush(Qt::red); + painter->drawRect(rect2); + } + else + { + initX = (currentValue - min) * increment; + QRect rect(1, height()/3+2+1, initX, height()/3-4-2); + painter->drawRect(rect); + } + + painter->restore(); +} + +void SMeter::drawScalePWRMeter(QPainter *painter) +{ + painter->save(); + painter->setPen(lineColor); + + double initX = 0; + double initTopY = height()*2/3-2; + double length = width()-12; + double increment = length / (maxValue - minValue); + + int longLineLen = 6; + int shortLineLen = 3; + + QFontMetrics meterFont(painter->font()); + double textHeight = meterFont.height(); + + //Draw scale values and scale values based on range values Long lines + int stepNumber = (maxValue - minValue) / shortStep; + for (int i = 0; i <= stepNumber; i++) + { + double j = i * shortStep + minValue; + if (fmod(j,longStep) == 0) + { + if (j == minValue) //Do not draw the first value + { + QPointF textPot = QPointF(initX, initTopY + textHeight); + painter->drawText(textPot, "PO"); + + initX += increment * shortStep; + continue; + } + + QPointF topPot = QPointF(initX, initTopY); + QPointF bottomPot = QPointF(initX, initTopY + longLineLen); + painter->drawLine(topPot, bottomPot); + + QString strValue = QString("%1").arg(j, 0, 'f', precision); + double textWidth = fontMetrics().horizontalAdvance(strValue); + + QPointF textPot = QPointF(initX - textWidth / 2, initTopY + textHeight + longLineLen); + painter->drawText(textPot, strValue); + } + else + { + + QPointF topPot = QPointF(initX, initTopY); + QPointF bottomPot = QPointF(initX, initTopY + shortLineLen); + painter->drawLine(topPot, bottomPot); + } + + initX += increment * shortStep; + } + + painter->restore(); +} + +void SMeter::drawScaleSMeter(QPainter *painter) +{ + int minValue = -54; //Set min and max value according to Hamlib SMeter definition + int maxValue = 60; + + int longLineLen = 6; + int shortLineLen = 3; + + double initX = 0; + int sUnit = 0; + + double initBottomY = height()/3+2; + double length = width()-12; + double increment = length / (maxValue - minValue); + + QFontMetrics meterFont(painter->font()); + double textHeight = meterFont.height(); + + painter->save(); + painter->setPen(lineColor); + + //Draw scale values and scale values based on range values + int longStep = 12; + int shortStep = 6; + + for (int i = minValue; i <= 0; i = i + shortStep) //S0 to S9 + { + if (i == minValue) + { + QPointF textPot = QPointF(initX, initBottomY - 2); + painter->drawText(textPot, "S"); + + initX += increment * shortStep; + sUnit = sUnit + 1; + continue; + } + + if (i % longStep == 0) + { + QPointF topPot = QPointF(initX, initBottomY); + QPointF bottomPot = QPointF(initX, initBottomY - longLineLen); + painter->drawLine(topPot, bottomPot); + + QString strValue = QString::number(sUnit); + double textWidth = fontMetrics().horizontalAdvance(strValue); + QPointF textPot = QPointF(initX - textWidth / 2, initBottomY - textHeight / 2 - longLineLen + 2); + painter->drawText(textPot, strValue); + } + else + { + QPointF topPot = QPointF(initX, initBottomY); + QPointF bottomPot = QPointF(initX, initBottomY - shortLineLen); + painter->drawLine(topPot, bottomPot); + } + + sUnit = sUnit + 1; + initX += increment * shortStep; + } + initX -= increment * shortStep; + + shortStep = 10; + longStep = 20; + + for (int i = 0; i <= maxValue; i = i + shortStep) //S9+ to S9+60 + { + if (i % longStep == 0) + { + QPointF topPot = QPointF(initX, initBottomY); + QPointF bottomPot = QPointF(initX, initBottomY - longLineLen); + painter->drawLine(topPot, bottomPot); + + if (i == 0) //Do not draw the first value + { + initX += increment * shortStep; + continue; + } + + QString strValue = "+" + QString::number(i); + double textWidth = fontMetrics().horizontalAdvance(strValue); + + QPointF textPot = QPointF(initX - textWidth / 2, initBottomY - textHeight / 2 - longLineLen + 2); + painter->drawText(textPot, strValue); + } + else + { + QPointF topPot = QPointF(initX, initBottomY); + QPointF bottomPot = QPointF(initX, initBottomY - shortLineLen); + painter->drawLine(topPot, bottomPot); + } + + initX += increment * shortStep; + } + + painter->restore(); +} + +void SMeter::setMinValue(double value) +{ + minValue = value; + update(); +} + +void SMeter::setMaxValue(double value) +{ + maxValue = value; + update(); +} + +void SMeter::setGateValue(double value) +{ + gateValue = value; +} + +void SMeter::setLongStep(double value) +{ + longStep = value; + update(); +} + +void SMeter::setShortStep(double value) +{ + shortStep = value; + update(); +} + +void SMeter::setPrecision(int value) +{ + precision = value; + update(); +} + +void SMeter::setValue(double value) +{ + currentValue = value; + update(); +} + +void SMeter::setValue(int value) +{ + setValue(double(value)); +} + +void SMeter::setTx(bool Tx) +{ + meterTx = Tx; +} diff --git a/smeter.h b/smeter.h new file mode 100644 index 0000000..f35c0f3 --- /dev/null +++ b/smeter.h @@ -0,0 +1,73 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#ifndef SMETER_H +#define SMETER_H + +#include + +class SMeter : public QWidget +{ + Q_OBJECT + +public: + explicit SMeter(QWidget *parent = nullptr); + +public slots: + void setMinValue(double value); + void setMaxValue(double value); + void setGateValue(double value); + void setLongStep(double value); + void setShortStep(double value); + void setPrecision(int value); + + void setValue(double value); + void setValue(int value); + + void setTx(bool Tx); + +protected: + void paintEvent(QPaintEvent *); + void drawMeter(QPainter *painter); + void drawProgress(QPainter *painter); + void drawScaleSMeter(QPainter *painter); + void drawScalePWRMeter(QPainter *painter); + +private: + double minValue; //Minimum scale value + double maxValue; //Maximum scale value + double gateValue; //Gate value to bar color change + double longStep; //Long lines with equal steps + double shortStep; //Short lines with equal steps + int precision; //Precision, the last few decimal places + + double value; //target value + double currentValue; //current value + + bool meterTx; //Switch between SMeter or PowerMeter + + QColor bgColor; //background color + QColor lineColor; //line color + QColor progressColor; //progress color + +signals: + +}; + +#endif // SMETER_H diff --git a/submeter.cpp b/submeter.cpp new file mode 100644 index 0000000..5052a38 --- /dev/null +++ b/submeter.cpp @@ -0,0 +1,195 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "submeter.h" +#include +#include + +SubMeter::SubMeter(QWidget *parent) : QWidget(parent) +{ + lineColor = QColor(Qt::black); + bgColor = QColor(Qt::white); + progressColor = QColor(Qt::green); + + //Default value + minValue = 0; + maxValue = 10; + gateValue = 10; + longStep = 5; + shortStep = 1; + precision = 0; + + currentValue = 0; +} + +void SubMeter::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + + QFont font; + font = painter.font(); + font.setPointSize(font.pointSize() - 2); + painter.setFont(font); + + drawMeter(&painter); + drawProgress(&painter); + drawScale(&painter); +} + +void SubMeter::drawMeter(QPainter *painter) +{ + painter->save(); + QPen pen(lineColor, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + painter->setPen(pen); + painter->setBrush(bgColor); + painter->drawRect(0, height()/3+2, width()-12, height()/3-4); + painter->restore(); +} + +void SubMeter::drawProgress(QPainter *painter) +{ + painter->save(); + painter->setPen(Qt::NoPen); + painter->setBrush(progressColor); + + double length = width()-14; + double increment = length / (maxValue - minValue); + + double initX, initXX; + + if (currentValue>gateValue) + { + initX = (gateValue - minValue) * increment; + QRect rect(1, height()/3+2+1, initX, height()/3-4-2); + painter->drawRect(rect); + + //Red bar + initXX = (currentValue - gateValue) * increment; + QRect rect2(initX+1, height()/3+2+1, initXX, height()/3-4-2); + painter->setBrush(Qt::red); + painter->drawRect(rect2); + } + else + { + initX = (currentValue - minValue) * increment; + QRect rect(1, height()/3+2+1, initX, height()/3-4-2); + painter->drawRect(rect); + } + + painter->restore(); +} + +void SubMeter::drawScale(QPainter *painter) +{ + painter->save(); + painter->setPen(lineColor); + + double initX = 0; + double initTopY = height()*2/3-2; + double length = width()-12; + double increment = length / (maxValue - minValue); + + int longLineLen = 6; + int shortLineLen = 3; + + QFontMetrics meterFont(painter->font()); + double textHeight = meterFont.height(); + + //Draw scale values and scale values based on range values + int stepNumber = (maxValue - minValue) / shortStep; + for (int i = 0; i <= stepNumber; i++) + { + double j = i * shortStep + minValue; + if (fmod(j,longStep) == 0) + { + if (j == minValue) //Do not draw the first value + { + initX += increment * shortStep; + continue; + } + + QPointF topPot = QPointF(initX, initTopY); + QPointF bottomPot = QPointF(initX, initTopY + longLineLen); + painter->drawLine(topPot, bottomPot); + + QString strValue = QString("%1").arg(j, 0, 'f', precision); + double textWidth = fontMetrics().horizontalAdvance(strValue); + + QPointF textPot = QPointF(initX - textWidth / 2, initTopY + textHeight + longLineLen); + painter->drawText(textPot, strValue); + } + else + { + QPointF topPot = QPointF(initX, initTopY); + QPointF bottomPot = QPointF(initX, initTopY + shortLineLen); + painter->drawLine(topPot, bottomPot); + } + + initX += increment * shortStep; + } + + painter->restore(); +} + +void SubMeter::setMinValue(double value) +{ + minValue = value; + update(); +} + +void SubMeter::setMaxValue(double value) +{ + maxValue = value; + update(); +} + +void SubMeter::setGateValue(double value) +{ + gateValue = value; +} + +void SubMeter::setLongStep(double value) +{ + longStep = value; + update(); +} + +void SubMeter::setShortStep(double value) +{ + shortStep = value; + update(); +} + +void SubMeter::setPrecision(int value) +{ + precision = value; + update(); +} + +void SubMeter::setValue(double value) +{ + currentValue = value; + update(); +} + +void SubMeter::setValue(int value) +{ + setValue(double(value)); +} diff --git a/submeter.h b/submeter.h new file mode 100644 index 0000000..f65573d --- /dev/null +++ b/submeter.h @@ -0,0 +1,67 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#ifndef SUBMETER_H +#define SUBMETER_H + +#include + +class SubMeter : public QWidget +{ + Q_OBJECT +public: + explicit SubMeter(QWidget *parent = nullptr); + +public slots: + void setMinValue(double value); + void setMaxValue(double value); + void setGateValue(double value); + void setLongStep(double value); + void setShortStep(double value); + void setPrecision(int value); + + void setValue(double value); + void setValue(int value); + +protected: + void paintEvent(QPaintEvent *); + void drawMeter(QPainter *painter); + void drawProgress(QPainter *painter); + void drawScale(QPainter *painter); + +private: + double minValue; //Minimum scale value + double maxValue; //Maximum scale value + double gateValue; //Gate value to bar color change + double longStep; //Long lines with equal steps + double shortStep; //Short lines with equal steps + int precision; //Precision, the last few decimal places + + double value; //target value + double currentValue; //current value + + QColor bgColor; //background color + QColor lineColor; //line color + QColor progressColor; //progress color + +signals: + +}; + +#endif // SUBMETER_H diff --git a/vfodisplay.cpp b/vfodisplay.cpp new file mode 100644 index 0000000..67c6d7c --- /dev/null +++ b/vfodisplay.cpp @@ -0,0 +1,152 @@ +/** + ** This file is part of the CatRadio project. + ** Copyright 2022 Gianfranco Sordetti IZ8EWD . + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + **/ + + +#include "vfodisplay.h" +#include "guidata.h" + +#include +#include +#include + + +extern guiConfig guiConf; + + +vfoDisplay::vfoDisplay(QWidget *parent) : QWidget(parent) +{ + lineColor = QColor(Qt::black); + bgColor = QColor(Qt::white); + textColor = QColor(Qt::black); +} + +void vfoDisplay::paintEvent(QPaintEvent *) +{ + //setMouseTracking(true); + + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + + QFont font; + font = painter.font(); + font.setPointSize(height() - 18); + painter.setFont(font); + + drawDisplay(&painter); + drawText(&painter); +} + +void vfoDisplay::drawDisplay(QPainter *painter) +{ + painter->save(); + + QPen pen(lineColor, 1, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin); + painter->setPen(pen); + painter->setBrush(bgColor); + painter->drawRect(1, 1, width()-3, height()-2); + painter->restore(); +} + +void vfoDisplay::drawText(QPainter *painter) +{ + painter->save(); + painter->setPen(textColor); + + QFontMetrics meterFont(painter->font()); + double textHeight = meterFont.ascent(); + textWidth = meterFont.horizontalAdvance("0",-1); + + QPointF textPot; + + long val = currentValue; + + for (int i = 1; i < 10; i++) + { + val = qFloor(val/10); + int d = val % 10; + + if (i==2) + { + textPot = QPointF(width()-3-(textWidth+2)*i-4, textHeight); + painter->drawText(textPot, "."); + } + + textPot = QPointF(width()-3-(textWidth+2)*i, textHeight); + + if (val==0 && d==0) painter->drawText(textPot, " "); + else painter->drawText(textPot, QString::number(d)); + } + + painter->restore(); +} + +void vfoDisplay::setValue(unsigned long value) +{ + currentValue = value; + update(); +} + +//* Tuning using mouse buttons +void vfoDisplay::mousePressEvent(QMouseEvent *event) +{ + event->accept(); + + QPoint pointerPos = event->pos(); + + for (int i = 1; i < 10; i ++) + { + if (pointerPos.x() > (width()-3-(textWidth+2)*i+1) && pointerPos.x() < (width()-3-(textWidth+2)*(i-1)-1)) + { + if (guiConf.vfoDisplayMode && event->button() == Qt::LeftButton) //Up/Down mode + { + if (pointerPos.y() < height()/2) currentValue = currentValue + pow(10,i); //Up + else if (currentValue - pow(10,i) > 0) currentValue = currentValue - pow(10,i); //Down + } + else if (!guiConf.vfoDisplayMode) //Left/Right mode + { + if (event->button() == Qt::LeftButton) currentValue = currentValue + pow(10,i); //LeftButton + else if (currentValue - pow(10,i) > 0) currentValue = currentValue - pow(10,i); //RightButton + } + + break; + } + } + + update(); + emit on_valueChanged(currentValue); +} + +//* Tuning using mouse wheel +void vfoDisplay::wheelEvent(QWheelEvent *event) +{ + event->accept(); + + QPointF pointerPos = event->position(); + + for (int i = 1; i < 10; i ++) + { + if (pointerPos.x() > (width()-3-(textWidth+2)*i+1) && pointerPos.x() < (width()-3-(textWidth+2)*(i-1)-1)) + { + if (event->angleDelta().y() > 0) currentValue = currentValue + pow(10,i); //Wheel up + else if (currentValue - pow(10,i) > 0) currentValue = currentValue - pow(10,i); //Wheel down + } + } + + update(); + emit on_valueChanged(currentValue); +} diff --git a/vfodisplay.h b/vfodisplay.h new file mode 100644 index 0000000..9dee447 --- /dev/null +++ b/vfodisplay.h @@ -0,0 +1,37 @@ +#ifndef VFODISPLAY_H +#define VFODISPLAY_H + +#include + +class vfoDisplay : public QWidget +{ + Q_OBJECT + +public: + explicit vfoDisplay(QWidget *parent = nullptr); + +public slots: + void setValue(unsigned long value); + +signals: + void on_valueChanged(int value); + +protected: + void paintEvent(QPaintEvent *); + void drawDisplay(QPainter *painter); + void drawText(QPainter *painter); + void mousePressEvent(QMouseEvent *event); //Mouse buttons + void wheelEvent(QWheelEvent *event); //Mouse wheel + +private: + QColor bgColor; //background color + QColor lineColor; //line color + QColor textColor; //text color + + unsigned long currentValue; //current frequency value (Hz) + unsigned long value; //target value + + int textWidth; //number width +}; + +#endif // VFODISPLAY_H