diff --git a/plugins/channelrx/demodrtty/readme.md b/plugins/channelrx/demodrtty/readme.md index 1ca883c5e..27232fadc 100644 --- a/plugins/channelrx/demodrtty/readme.md +++ b/plugins/channelrx/demodrtty/readme.md @@ -106,3 +106,4 @@ Click to specify the name of the .txt file which received characters are logged The received text area shows characters as they are received. +Holding the cursor over an acronym may show a tooltip with the decoded acronym. diff --git a/plugins/channelrx/demodrtty/rttydemodgui.cpp b/plugins/channelrx/demodrtty/rttydemodgui.cpp index 57fda37c2..5945a1304 100644 --- a/plugins/channelrx/demodrtty/rttydemodgui.cpp +++ b/plugins/channelrx/demodrtty/rttydemodgui.cpp @@ -34,6 +34,7 @@ #include "plugin/pluginapi.h" #include "util/simpleserializer.h" #include "util/db.h" +#include "util/rtty.h" #include "gui/basicchannelsettingsdialog.h" #include "gui/devicestreamselectiondialog.h" #include "dsp/dspengine.h" @@ -482,6 +483,8 @@ RttyDemodGUI::RttyDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseb connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor())); connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); + ui->text->addAcronyms(Rtty::m_acronyms); + ui->scopeContainer->setVisible(false); // Hide developer only settings diff --git a/plugins/channelrx/demodrtty/rttydemodgui.ui b/plugins/channelrx/demodrtty/rttydemodgui.ui index a70e366f5..8ac4000d9 100644 --- a/plugins/channelrx/demodrtty/rttydemodgui.ui +++ b/plugins/channelrx/demodrtty/rttydemodgui.ui @@ -916,7 +916,7 @@ - + Received text @@ -1293,6 +1293,12 @@
gui/glscopegui.h
1 + + AcronymView + QTextEdit +
gui/acronymview.h
+ 1 +
deltaFrequency diff --git a/plugins/channeltx/modrtty/readme.md b/plugins/channeltx/modrtty/readme.md index 70deddbcf..cf267e4bd 100644 --- a/plugins/channeltx/modrtty/readme.md +++ b/plugins/channeltx/modrtty/readme.md @@ -115,6 +115,12 @@ Predefined text supports the following variable substitutions: The substitutions are applied when the Transmit Settings dialog is closed. +

21: Transmitted Text

+ +The trasnmitted text area shows characters as they are transmitted. + +Holding the cursor over an acronym may show a tooltip with the decoded acronym. +

API

Full details of the API can be found in the Swagger documentation. Below are a few examples. diff --git a/plugins/channeltx/modrtty/rttymodgui.cpp b/plugins/channeltx/modrtty/rttymodgui.cpp index dc5550b7a..f1fc898ea 100644 --- a/plugins/channeltx/modrtty/rttymodgui.cpp +++ b/plugins/channeltx/modrtty/rttymodgui.cpp @@ -31,6 +31,7 @@ #include "plugin/pluginapi.h" #include "util/simpleserializer.h" #include "util/db.h" +#include "util/rtty.h" #include "util/maidenhead.h" #include "gui/glspectrum.h" #include "gui/crightclickenabler.h" @@ -476,6 +477,8 @@ RttyModGUI::RttyModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS m_settings.setChannelMarker(&m_channelMarker); m_settings.setRollupState(&m_rollupState); + ui->transmittedText->addAcronyms(Rtty::m_acronyms); + ui->spectrumContainer->setVisible(false); displaySettings(); diff --git a/plugins/channeltx/modrtty/rttymodgui.ui b/plugins/channeltx/modrtty/rttymodgui.ui index d418d5b66..b7fee75f8 100644 --- a/plugins/channeltx/modrtty/rttymodgui.ui +++ b/plugins/channeltx/modrtty/rttymodgui.ui @@ -751,7 +751,7 @@
- + Qt::Horizontal @@ -854,11 +854,7 @@ 3 - - - true - - +
@@ -960,6 +956,12 @@
gui/levelmeter.h
1 + + AcronymView + QTextEdit +
gui/acronymview.h
+ 1 +
deltaFrequency diff --git a/plugins/channeltx/modrtty/rttymodsettings.cpp b/plugins/channeltx/modrtty/rttymodsettings.cpp index e728cfe44..d6682c26a 100644 --- a/plugins/channeltx/modrtty/rttymodsettings.cpp +++ b/plugins/channeltx/modrtty/rttymodsettings.cpp @@ -57,7 +57,7 @@ void RttyModSettings::resetToDefaults() "UR 599 QTH IS ${location}", "TU DE ${callsign} CQ" }); - m_rgbColor = QColor(0, 105, 2).rgb(); + m_rgbColor = QColor(180, 205, 130).rgb(); m_title = "RTTY Modulator"; m_streamIndex = 0; m_useReverseAPI = false; diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 1b7369a08..5b640f7bb 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -259,6 +259,7 @@ set(sdrbase_SOURCES util/simpleserializer.cpp util/serialutil.cpp #util/spinlock.cpp + util/rtty.cpp util/uid.cpp util/units.cpp util/timeutil.cpp @@ -491,6 +492,7 @@ set(sdrbase_HEADERS util/profiler.h util/radiosonde.h util/rtpsink.h + util/rtty.h util/syncmessenger.h util/samplesourceserializer.h util/simpleserializer.h diff --git a/sdrbase/util/rtty.cpp b/sdrbase/util/rtty.cpp new file mode 100644 index 000000000..1cacf96f0 --- /dev/null +++ b/sdrbase/util/rtty.cpp @@ -0,0 +1,290 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2023 Jon Beniston, M7RCE // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "util/rtty.h" + +// From http://www.ct2fzi.net/abreviations/abreviations.html +const QHash Rtty::m_acronyms = { + {"AA", "After All"}, + {"AB", "All Before"}, + {"ABT", "About"}, + {"ACK", "Acknowledgement"}, + {"ADEE", "Addressee"}, + {"ADR", "Address"}, + {"AF", "Audio Frequency"}, + {"AGN", "Again"}, + {"AM", "Amplitude Modulation"}, + {"AMU", "Antenna Matching Unit"}, + {"ANS", "Answer"}, + {"ANT", "Antenna"}, + {"ARQ", "Automatic Repeat Request"}, + {"ATU", "Antenna Tuning Unit"}, + {"B4", "Before"}, + {"BCN", "Beacon"}, + {"BCNU", "Be Seeing You"}, + {"BD", "Bad"}, + {"BK", "Break"}, + {"BN", "Been"}, + {"BTH", "Both"}, + {"BTR", "Better"}, + {"BTW", "By The Way"}, + {"BTU", "Back To You"}, + {"C", "Correct"}, + {"CBA", "Callbook Address"}, + {"CFM", "Confirm"}, + {"CK", "Check"}, + {"CKT", "Circuit"}, + {"CL", "Closing Down"}, + {"CLBK", "Callbook"}, + {"CLD", "Called"}, + {"CLG", "Calling"}, + {"CMG", "Coming"}, + {"CNT", "Can't"}, + {"COMP", "Computer"}, + {"CONDX", "Conditions"}, + {"COZ", "Because"}, + {"CPI", "Copy"}, + {"CQ", "General Call"}, + {"CRD", "Card"}, + {"CS", "Callsign"}, + {"CTCSS", "Continuous Tone Coded Squelch System"}, + {"CU", "See You"}, + {"CUAGN", "See You Again"}, + {"CUD", "Could"}, + {"CUL", "See You Later"}, + {"CUM", "Come"}, + {"CUZ", "Because"}, + {"CW", "Continuous Wave / Morse"}, + {"DA", "Day"}, + {"DE", "From"}, + {"DF", "Direction Finding"}, + {"DIFF", "Difference"}, + {"DLD", "Delivered"}, + {"DLVD", "Delivered"}, + {"DN", "Down"}, + {"DR", "Dear"}, + {"DSB", "Double Side Band"}, + {"DSP", "Digital Signal Processing"}, + {"DSW", "Goodbye (Russian)"}, + {"DWN", "Down"}, + {"DX", "Distance"}, + {"EL", "Element"}, + {"EME", "Earth-Moon-Earth"}, + {"ENUF", "Enough"}, + {"ES", "And"}, + {"EU", "Europe"}, + {"EVE", "Evening"}, + {"FB", "Fine Business"}, + {"FER", "For"}, + {"FIO", "For Information Only"}, + {"FM", "Frequency Modulation"}, + {"FQ", "Frequency"}, + {"FREQ", "Frequency"}, + {"FSD", "Full Scale Deflection"}, + {"FSK", "Frequency Shift Keying"}, + {"FWD", "Forward"}, + {"FWIW", "For What It's Worth"}, + {"FYI", "For Your Information"}, + {"GA", "Good Afternoon"}, + {"GB", "Good Bye"}, + {"GD", "Good Day"}, + {"GE", "Good Evening"}, + {"GESS", "Guess"}, + {"GG", "Going"}, + {"GLD", "Glad"}, + {"GM", "Good Morning"}, + {"GMT", "Greenwich Mean Time"}, + {"GN", "Good Night"}, + {"GND", "Ground"}, + {"GP", "Ground Plane"}, + {"GPS", "Global Positioning System"}, + {"GS", "Green Stamp"}, + {"GUD", "Good"}, + {"GV", "Give"}, + {"GVG", "Giving"}, + {"HAGD", "Have A Good Day"}, + {"HAGWE", "Have A Good Weekend"}, + {"HF", "High Frequency"}, + {"HI", "High"}, + {"HPE", "Hope"}, + {"HQ", "Headquarters"}, + {"HR", "Here / Hour"}, + {"HRD", "Heard"}, + {"HV", "Have"}, + {"HVG", "Having"}, + {"HVY", "Heavy"}, + {"HW", "How"}, + {"IMHO", "In My Humble Opinion"}, + {"IMI", "Say again"}, + {"K", "Over"}, + {"KN", "Over"}, + {"LF", "Low Frequency"}, + {"LNG", "Long"}, + {"LP", "Long Path"}, + {"LSB", "Lower Sideband"}, + {"LSN", "Listen"}, + {"LTR", "Later"}, + {"LV", "Leave"}, + {"LVG", "Leaving"}, + {"LW", "Long Wire"}, + {"MGR", "Manager"}, + {"MI", "My"}, + {"MNI", "Many"}, + {"MOM", "Moment"}, + {"MS", "Meteor Scatter"}, + {"MSG", "Message"}, + {"N", "No"}, + {"NCS", "Net Control Station"}, + {"ND", "Nothing Doing"}, + {"NM", "No More"}, + {"NR", "Near / Number"}, + {"NW", "Now"}, + {"OB", "Old Boy"}, + {"OC", "Old Chap"}, + {"OM", "Old Man"}, + {"OP", "Operator"}, + {"OPR", "Operator"}, + {"OT", "Old Timer"}, + {"OW", "Old Woman"}, + {"PA", "Power Amplifier"}, + {"PBL", "Preamble"}, + {"PKG", "Package"}, + {"POV", "Point Of View"}, + {"PSE", "Please"}, + {"PSK", "Phase Shift Keying"}, + {"PT", "Point"}, + {"PTT", "Push To Talk"}, + {"PWR", "Power"}, + {"PX", "Prefix"}, + {"QRA", "Address"}, + {"QRG", "Frequency"}, + {"QRK", "Readability"}, + {"QRL", "Busy"}, + {"QRM", "Interference"}, + {"QRN", "Noise"}, + {"QRO", "High Power"}, + {"QRP", "Low Power"}, + {"QRQ", "Send Faster"}, + {"QRS", "Send Slower"}, + {"QRSS", "Send Very Slowly"}, + {"QRT", "Stop Sending"}, + {"QRU", "Nothing Further To Say"}, + {"QRV", "Ready"}, + {"QRX", "Wait"}, + {"QRZ", "Who Is Calling Me"}, + {"QSA", "Signal Strength"}, + {"QSB", "Fading"}, + {"QSK", "Break-in"}, + {"QSL", "All Received OK"}, + {"QSLL", "I Will Send A QSL Card"}, + {"QSO", "Contact"}, + {"QSP", "Relay A Message"}, + {"QSX", "Listening On Frequency"}, + {"QSY", "Change Frequency"}, + {"QTH", "Location"}, + {"R", "Received OK"}, + {"RC", "Ragchew"}, + {"RCD", "Recieved"}, + {"RCVR", "Receiver"}, + {"RE", "Regarding"}, + {"REF", "Reference"}, + {"RF", "Radio Frequency"}, + {"RFI", "Radio Frequency Interference"}, + {"RPT", "Repeat / Report"}, + {"RST", "Signal Report"}, + {"RTTY", "Radio Teletype"}, + {"RX", "Receive"}, + {"SA", "Say"}, + {"SDR", "Software Defined Radio"}, + {"SEZ", "Says"}, + {"SGD", "Signed"}, + {"SHUD", "Should"}, + {"SIG", "Signal"}, + {"SK", "End Of Work"}, + {"SKED", "Schedule"}, + {"SN", "Soon"}, + {"SP", "Short Path"}, + {"SRI", "Sorry"}, + {"SSB", "Single Sideband"}, + {"STN", "Station"}, + {"SUM", "Some"}, + {"SVC", "Service"}, + {"SWR", "Standing Wave Ratio"}, + {"TFC", "Traffic"}, + {"TIA", "Thanks In Advance"}, + {"TKS", "Thanks"}, + {"TMW", "Tomorrow"}, + {"TNC", "Terminal Node Controller"}, + {"TNX", "Thanks"}, + {"TR", "Transmit"}, + {"T/R", "Transmit/Receive"}, + {"TRBL", "Trouble"}, + {"TRF", "Tuned Radio Frequency"}, + {"TRIX", "Tricks"}, + {"TRX", "Transceiver"}, + {"TT", "That"}, + {"TTS", "That Is"}, + {"TU", "Thank You"}, + {"TVI", "Television Interference"}, + {"TX", "Transmit"}, + {"TXT", "Text"}, + {"U", "You"}, + {"UHF", "Ultra High Frequency"}, + {"UNLIS", "Unlicensed"}, + {"UR", "Your"}, + {"URS", "Yours"}, + {"UTC", "Coordinated Universal Time"}, + {"V", "Volts"}, + {"VHF", "Very High Frequency"}, + {"VE", "Understood"}, + {"VERT", "Vertical"}, + {"VFB", "Very Fine Business"}, + {"VFO", "Variable Frequency Oscillator"}, + {"VLF", "Very Low Frequency"}, + {"VOX", "Voice Operated"}, + {"VSB", "Vestigial Sideband"}, + {"VSWR", "Voltage Standing Wave Ratio"}, + {"VY", "Very"}, + {"W", "Watts"}, + {"WA", "Word After"}, + {"WAT", "What"}, + {"WATSA", "What Say"}, + {"WB", "Word Before"}, + {"WD", "Word"}, + {"WDS", "Words"}, + {"WID", "With"}, + {"WKD", "Worked"}, + {"WKG", "Working"}, + {"WL", "Will"}, + {"WPM", "Words Per Minute"}, + {"WRD", "Word"}, + {"WRK", "Work"}, + {"WUD", "Would"}, + {"WX", "Weather"}, + {"XCVR", "Transceiver"}, + {"XMTR", "Transmitter"}, + {"XTAL", "Crystal"}, + {"YF", "Wife"}, + {"YL", "Young Lady"}, + {"YR", "Year"}, + {"Z", "Zulu Time"}, + {"30", "I Have Nothing More to Send"}, + {"33", "Fondest Regards"}, + {"55", "Best Success"}, + {"73", "Best Wishes"}, + {"88", "Love And Kisses"}, +}; diff --git a/sdrbase/util/rtty.h b/sdrbase/util/rtty.h new file mode 100644 index 000000000..d0a40f9cc --- /dev/null +++ b/sdrbase/util/rtty.h @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2023 Jon Beniston, M7RCE // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_UTIL_RTTY_H +#define INCLUDE_UTIL_RTTY_H + +#include + +#include "export.h" + +class SDRBASE_API Rtty +{ +public: + static const QHash m_acronyms; +}; + +#endif /* INCLUDE_UTIL_RTTY_H */ diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index d7ab6122f..fd3c5caa0 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -7,6 +7,7 @@ set(CMAKE_AUTOUIC OFF) set(sdrgui_SOURCES mainwindow.cpp gui/aboutdialog.cpp + gui/acronymview.cpp gui/addpresetdialog.cpp gui/audiodialog.cpp gui/audioselectdialog.cpp @@ -127,6 +128,7 @@ set(sdrgui_HEADERS gui/aboutdialog.h gui/accessiblevaluedial.h gui/accessiblevaluedialz.h + gui/acronymview.h gui/addpresetdialog.h gui/audiodialog.h gui/audioselectdialog.h diff --git a/sdrgui/gui/acronymview.cpp b/sdrgui/gui/acronymview.cpp new file mode 100644 index 000000000..295b6f706 --- /dev/null +++ b/sdrgui/gui/acronymview.cpp @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2023 Jon Beniston, M7RCE // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#include "acronymview.h" + +AcronymView::AcronymView(QWidget* parent) : + QPlainTextEdit(parent) +{ + setMouseTracking(true); + setReadOnly(true); +} + +bool AcronymView::event(QEvent* event) +{ + if (event->type() == QEvent::ToolTip) + { + QHelpEvent* helpEvent = static_cast(event); + QTextCursor cursor = cursorForPosition(helpEvent->pos()); + cursor.select(QTextCursor::WordUnderCursor); + QString text = cursor.selectedText(); + // Remove trailing digits from METAR + while (text.size() > 0 && text.right(1)[0].isDigit()) { + text = text.left(text.size() - 1); + } + if (!text.isEmpty() && m_acronym.contains(text)) + { + QToolTip::showText(helpEvent->globalPos(), QString("%1 - %2").arg(text).arg(m_acronym.value(text))); + } + else + { + if (!text.isEmpty()) { + qDebug() << "AcronymView::event: No tooltip for " << text; + } + QToolTip::hideText(); + } + return true; + } + return QPlainTextEdit::event(event); +} + +void AcronymView::addAcronym(const QString& acronym, const QString& explanation) +{ + m_acronym.insert(acronym, explanation); +} + +void AcronymView::addAcronyms(const QHash& acronyms) +{ + m_acronym.insert(acronyms); +} diff --git a/sdrgui/gui/acronymview.h b/sdrgui/gui/acronymview.h new file mode 100644 index 000000000..1e2b5c57b --- /dev/null +++ b/sdrgui/gui/acronymview.h @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2023 Jon Beniston, M7RCE // +// // +// 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 as 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_GUI_ACRONYMVIEW_H +#define INCLUDE_GUI_ACRONYMVIEW_H + +#include +#include + +#include "export.h" + +// Displays text like a QPlainTextEdit, but adds tooltips for acronyms in the text +class SDRGUI_API AcronymView : public QPlainTextEdit { + Q_OBJECT + + QHash m_acronym; + +public: + + AcronymView(QWidget* parent = nullptr); + bool event(QEvent* event); + void addAcronym(const QString& acronym, const QString& explanation); + void addAcronyms(const QHash& acronyms); + +}; + +#endif // INCLUDE_GUI_ACRONYMVIEW_H