From 57efa91a5b4e97d10559d096326be1ee164051f2 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 29 Jul 2019 18:54:50 +0200 Subject: [PATCH] CW keyer keyboard input: GUI mods (1) --- sdrbase/dsp/cwkeyer.h | 4 + sdrbase/dsp/cwkeyersettings.cpp | 17 +++ sdrbase/dsp/cwkeyersettings.h | 7 +- sdrgui/gui/cwkeyergui.cpp | 171 +++++++++++++++++++++- sdrgui/gui/cwkeyergui.h | 23 ++- sdrgui/gui/cwkeyergui.ui | 249 +++++++++++++++++++++++++++++++- sdrgui/mainwindow.cpp | 20 ++- sdrgui/mainwindow.h | 2 + 8 files changed, 482 insertions(+), 11 deletions(-) diff --git a/sdrbase/dsp/cwkeyer.h b/sdrbase/dsp/cwkeyer.h index 2b1b84f0c..76b7f42c7 100644 --- a/sdrbase/dsp/cwkeyer.h +++ b/sdrbase/dsp/cwkeyer.h @@ -106,6 +106,10 @@ public: void setMode(CWKeyerSettings::CWMode mode); void setLoop(bool loop) { m_settings.m_loop = loop; } const CWKeyerSettings& getSettings() const { return m_settings; } + void setDotKey(Qt::Key key) { m_settings.m_dotKey = key; } + void setDotKeyModifiers(Qt::KeyboardModifiers keyboardModifiers) { m_settings.m_dotKeyModifiers = keyboardModifiers; } + void setDashKey(Qt::Key key) { m_settings.m_dashKey = key; } + void setDashKeyModifiers(Qt::KeyboardModifiers keyboardModifiers) { m_settings.m_dashKeyModifiers = keyboardModifiers; } void reset() { m_keyIambicState = KeySilent; } diff --git a/sdrbase/dsp/cwkeyersettings.cpp b/sdrbase/dsp/cwkeyersettings.cpp index bb8101d0e..26e5a733c 100644 --- a/sdrbase/dsp/cwkeyersettings.cpp +++ b/sdrbase/dsp/cwkeyersettings.cpp @@ -31,6 +31,10 @@ void CWKeyerSettings::resetToDefaults() m_sampleRate = 48000; m_text = ""; m_wpm = 13; + m_dotKey = Qt::Key_Period; + m_dotKeyModifiers = Qt::NoModifier; + m_dashKey = Qt::Key_Minus; + m_dashKeyModifiers = Qt::NoModifier; } QByteArray CWKeyerSettings::serialize() const @@ -42,6 +46,10 @@ QByteArray CWKeyerSettings::serialize() const s.writeS32(4, m_sampleRate); s.writeString(5, m_text); s.writeS32(6, m_wpm); + s.writeS32(7, (int) m_dotKey); + s.writeU32(8, (unsigned int) m_dotKeyModifiers); + s.writeS32(9, (int) m_dashKey); + s.writeU32(10, (unsigned int) m_dashKeyModifiers); return s.final(); } @@ -59,6 +67,7 @@ bool CWKeyerSettings::deserialize(const QByteArray& data) if (d.getVersion() == 1) { int intval; + unsigned int uintval; d.readBool(2, &m_loop, false); d.readS32(3, &intval, 0); @@ -66,6 +75,14 @@ bool CWKeyerSettings::deserialize(const QByteArray& data) d.readS32(4, &m_sampleRate, 48000); d.readString(5, &m_text, ""); d.readS32(6, &m_wpm, 13); + d.readS32(7, &intval, (int) Qt::Key_Period); + m_dotKey = (Qt::Key) (intval < 0 ? 0 : intval); + d.readU32(8, &uintval, 0); + m_dotKeyModifiers = (Qt::KeyboardModifiers) uintval; + d.readS32(9, &intval, (int) Qt::Key_Minus); + m_dashKey = (Qt::Key) (intval < 0 ? 0 : intval); + d.readU32(10, &uintval, 0); + m_dashKeyModifiers = (Qt::KeyboardModifiers) uintval; return true; } diff --git a/sdrbase/dsp/cwkeyersettings.h b/sdrbase/dsp/cwkeyersettings.h index 5cafd9c6d..f7a7f6a03 100644 --- a/sdrbase/dsp/cwkeyersettings.h +++ b/sdrbase/dsp/cwkeyersettings.h @@ -32,7 +32,8 @@ public: CWNone, CWText, CWDots, - CWDashes + CWDashes, + CWKeyboard } CWMode; bool m_loop; @@ -40,6 +41,10 @@ public: int m_sampleRate; QString m_text; int m_wpm; + Qt::Key m_dotKey; + Qt::KeyboardModifiers m_dotKeyModifiers; + Qt::Key m_dashKey; + Qt::KeyboardModifiers m_dashKeyModifiers; CWKeyerSettings(); void resetToDefaults(); diff --git a/sdrgui/gui/cwkeyergui.cpp b/sdrgui/gui/cwkeyergui.cpp index 3805ef41a..9ea397ac6 100644 --- a/sdrgui/gui/cwkeyergui.cpp +++ b/sdrgui/gui/cwkeyergui.cpp @@ -24,20 +24,27 @@ #include "dsp/cwkeyer.h" #include "util/simpleserializer.h" #include "util/messagequeue.h" +#include "commandkeyreceiver.h" +#include "mainwindow.h" CWKeyerGUI::CWKeyerGUI(QWidget* parent) : QWidget(parent), ui(new Ui::CWKeyerGUI), - m_messageQueue(0), - m_cwKeyer(0), - m_doApplySettings(true) + m_messageQueue(nullptr), + m_cwKeyer(nullptr), + m_doApplySettings(true), + m_keyScope(NoKeyScope) { ui->setupUi(this); + m_commandKeyReceiver = new CommandKeyReceiver(); + m_commandKeyReceiver->setRelease(true); + this->installEventFilter(m_commandKeyReceiver); } CWKeyerGUI::~CWKeyerGUI() { this->releaseKeyboard(); // just in case + m_commandKeyReceiver->deleteLater(); delete ui; } @@ -47,6 +54,7 @@ void CWKeyerGUI::setBuddies(MessageQueue* messageQueue, CWKeyer* cwKeyer) m_cwKeyer = cwKeyer; applySettings(); sendSettings(); + displaySettings(m_cwKeyer->getSettings()); } void CWKeyerGUI::resetToDefaults() @@ -130,6 +138,7 @@ void CWKeyerGUI::on_playDots_toggled(bool checked) //ui->playDots->setEnabled(!checked); // release other source inputs ui->playDashes->setEnabled(!checked); ui->playText->setEnabled(!checked); + ui->keyboardKeyer->setEnabled(!checked); if (m_doApplySettings) { @@ -143,6 +152,7 @@ void CWKeyerGUI::on_playDashes_toggled(bool checked) ui->playDots->setEnabled(!checked); // release other source inputs //ui->playDashes->setEnabled(!checked); ui->playText->setEnabled(!checked); + ui->keyboardKeyer->setEnabled(!checked); if (m_doApplySettings) { @@ -156,6 +166,7 @@ void CWKeyerGUI::on_playText_toggled(bool checked) ui->playDots->setEnabled(!checked); // release other source inputs ui->playDashes->setEnabled(!checked); //ui->playText->setEnabled(!checked); + ui->keyboardKeyer->setEnabled(!checked); if (m_doApplySettings) { @@ -188,6 +199,134 @@ void CWKeyerGUI::on_playStop_toggled(bool checked) } } +void CWKeyerGUI::on_keyDotCapture_toggled(bool checked) +{ + if (checked && ui->keyDashCapture->isChecked()) + { + ui->keyDotCapture->setChecked(false); + ui->keyDashCapture->setChecked(false); + return; + } + + if (checked) + { + m_keyScope = DotKeyScope; + setFocus(); + setFocusPolicy(Qt::StrongFocus); + connect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), + this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + } + else + { + m_keyScope = NoKeyScope; + disconnect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), + this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + setFocusPolicy(Qt::NoFocus); + clearFocus(); + } +} + +void CWKeyerGUI::on_keyDashCapture_toggled(bool checked) +{ + if (checked && ui->keyDotCapture->isChecked()) + { + ui->keyDotCapture->setChecked(false); + ui->keyDashCapture->setChecked(false); + return; + } + + if (checked) + { + m_keyScope = DashKeyScope; + m_commandKeyReceiver->setRelease(false); + setFocus(); + setFocusPolicy(Qt::StrongFocus); + connect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), + this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + } + else + { + m_keyScope = NoKeyScope; + m_commandKeyReceiver->setRelease(false); + disconnect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), + this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + setFocusPolicy(Qt::NoFocus); + clearFocus(); + } +} + +void CWKeyerGUI::commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release) +{ + (void) release; +// qDebug("CWKeyerGUI::commandKeyPressed: key: %x", m_key); +// qDebug("CWKeyerGUI::commandKeyPressed: has modifiers: %x", QFlags::Int(keyModifiers)); + + if (m_keyScope == DotKeyScope) + { + m_dotKey = key; + m_dotKeyModifiers = keyModifiers; + setKeyLabel(ui->keyDotLabel, key, keyModifiers); + ui->keyDotCapture->setChecked(false); + + if (m_doApplySettings) + { + m_cwKeyer->setDotKey(key); + m_cwKeyer->setDotKeyModifiers(keyModifiers); + sendSettings(); + } + } + else if (m_keyScope == DashKeyScope) + { + m_dashKey = key; + m_dashKeyModifiers = keyModifiers; + setKeyLabel(ui->keyDashLabel, key, keyModifiers); + ui->keyDashCapture->setChecked(false); + + if (m_doApplySettings) + { + m_cwKeyer->setDashKey(key); + m_cwKeyer->setDashKeyModifiers(keyModifiers); + sendSettings(); + } + } + + m_commandKeyReceiver->setRelease(true); +} + +void CWKeyerGUI::on_keyboardKeyer_toggled(bool checked) +{ + qDebug("CWKeyerGUI::on_keyboardKeyer_toggled: %s", checked ? "true" : "false"); + ui->playDots->setEnabled(!checked); // block or release other source inputs + ui->playDashes->setEnabled(!checked); + ui->playText->setEnabled(!checked); + + if (m_doApplySettings) + { + m_cwKeyer->setMode(checked ? CWKeyerSettings::CWKeyboard : CWKeyerSettings::CWNone); + sendSettings(); + } + + if (checked) { + MainWindow::getInstance()->commandKeysConnect(this, SLOT(keyboardKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + } else { + MainWindow::getInstance()->commandKeysDisconnect(this, SLOT(keyboardKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + } +} + +void CWKeyerGUI::keyboardKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release) +{ + const CWKeyerSettings& settings = m_cwKeyer->getSettings(); + + if ((key == settings.m_dotKey) && (keyModifiers == settings.m_dotKeyModifiers)) + { + qDebug("CWKeyerGUI::keyboardKeyPressed: dot %s", release ? "released" : "pressed"); + } + else if ((key == settings.m_dashKey) && (keyModifiers == settings.m_dashKeyModifiers)) + { + qDebug("CWKeyerGUI::keyboardKeyPressed: dash %s", release ? "released" : "pressed"); + } +} + // === End SLOTS ============================================================== void CWKeyerGUI::applySettings() @@ -199,6 +338,11 @@ void CWKeyerGUI::applySettings() value = ui->cwSpeed->value(); ui->cwSpeedText->setText(QString("%1").arg(value)); m_cwKeyer->setWPM(value); + + m_cwKeyer->setDotKey(m_dotKey); + m_cwKeyer->setDotKeyModifiers(m_dotKeyModifiers); + m_cwKeyer->setDashKey(m_dashKey); + m_cwKeyer->setDashKeyModifiers(m_dashKeyModifiers); } void CWKeyerGUI::displaySettings(const CWKeyerSettings& settings) @@ -220,9 +364,30 @@ void CWKeyerGUI::displaySettings(const CWKeyerSettings& settings) ui->cwSpeed->setValue(settings.m_wpm); ui->cwSpeedText->setText(QString("%1").arg(settings.m_wpm)); + setKeyLabel(ui->keyDotLabel, settings.m_dotKey, settings.m_dotKeyModifiers); + setKeyLabel(ui->keyDashLabel, settings.m_dashKey, settings.m_dashKeyModifiers); + blockApplySettings(false); } +void CWKeyerGUI::setKeyLabel(QLabel *label, Qt::Key key, Qt::KeyboardModifiers keyModifiers) +{ + if (key == 0) + { + label->setText(""); + } + else if (keyModifiers != Qt::NoModifier) + { + QString altGrStr = keyModifiers & Qt::GroupSwitchModifier ? "Gr " : ""; + int maskedModifiers = (keyModifiers & 0x3FFFFFFF) + ((keyModifiers & 0x40000000)>>3); + label->setText(altGrStr + QKeySequence(maskedModifiers, key).toString()); + } + else + { + label->setText(QKeySequence(key).toString()); + } +} + void CWKeyerGUI::blockApplySettings(bool block) { m_doApplySettings = !block; diff --git a/sdrgui/gui/cwkeyergui.h b/sdrgui/gui/cwkeyergui.h index 82b4058a9..07f234a0b 100644 --- a/sdrgui/gui/cwkeyergui.h +++ b/sdrgui/gui/cwkeyergui.h @@ -28,15 +28,17 @@ namespace Ui { class CWKeyerGUI; } +class QLabel; class MessageQueue; class CWKeyer; class CWKeyerSettings; +class CommandKeyReceiver; class SDRGUI_API CWKeyerGUI : public QWidget, public Serializable { Q_OBJECT public: - explicit CWKeyerGUI(QWidget* parent = NULL); + explicit CWKeyerGUI(QWidget* parent = nullptr); ~CWKeyerGUI(); void setBuddies(MessageQueue* messageQueue, CWKeyer* cwKeyer); @@ -48,15 +50,29 @@ public: void displaySettings(const CWKeyerSettings& settings); private: + enum KeyScope + { + NoKeyScope, + DotKeyScope, + DashKeyScope + }; + Ui::CWKeyerGUI* ui; MessageQueue* m_messageQueue; CWKeyer* m_cwKeyer; bool m_doApplySettings; + CommandKeyReceiver *m_commandKeyReceiver; + KeyScope m_keyScope; + Qt::Key m_dotKey; + Qt::KeyboardModifiers m_dotKeyModifiers; + Qt::Key m_dashKey; + Qt::KeyboardModifiers m_dashKeyModifiers; void applySettings(); void sendSettings(); void blockApplySettings(bool block); + void setKeyLabel(QLabel *label, Qt::Key key, Qt::KeyboardModifiers keyModifiers); private slots: void on_cwTextClear_clicked(bool checked); @@ -67,6 +83,11 @@ private slots: void on_playText_toggled(bool checked); void on_playLoopCW_toggled(bool checked); void on_playStop_toggled(bool checked); + void on_keyDotCapture_toggled(bool checked); + void on_keyDashCapture_toggled(bool checked); + void on_keyboardKeyer_toggled(bool checked); + void commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release); + void keyboardKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release); }; diff --git a/sdrgui/gui/cwkeyergui.ui b/sdrgui/gui/cwkeyergui.ui index cdd0867ce..fa01e02f1 100644 --- a/sdrgui/gui/cwkeyergui.ui +++ b/sdrgui/gui/cwkeyergui.ui @@ -7,7 +7,7 @@ 0 0 375 - 60 + 91 @@ -373,6 +373,13 @@ + + + + Qt::Vertical + + + @@ -431,6 +438,246 @@ + + + + + + + 24 + 24 + + + + Activate keyboard keyer key bindings + + + + + + + :/keyboard.png:/keyboard.png + + + true + + + + + + + + 24 + 24 + + + + Keying style straight or iambic + + + + + + + :/iambickey.png + :/morsekey.png:/iambickey.png + + + true + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 190 + 190 + 190 + + + + + + + + + 12 + 75 + true + + + + Enter key to associate dots with + + + . + + + true + + + + + + + + 60 + 0 + + + + ... + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 190 + 190 + 190 + + + + + + + + + 12 + 75 + true + + + + Enter key to associate dashes with + + + - + + + true + + + + + + + + 60 + 0 + + + + ... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index 18f3363c4..21e47853e 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -1273,20 +1273,30 @@ void MainWindow::on_commandsSave_clicked() m_settings.save(); } +void MainWindow::commandKeysConnect(QObject *object, const char *slot) +{ + setFocus(); + connect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), + object, slot); +} + +void MainWindow::commandKeysDisconnect(QObject *object, const char *slot) +{ + disconnect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), + object, slot); +} + void MainWindow::on_commandKeyboardConnect_toggled(bool checked) { qDebug("on_commandKeyboardConnect_toggled: %s", checked ? "true" : "false"); if (checked) { - setFocus(); - connect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), - this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + commandKeysConnect(this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); } else { - disconnect(m_commandKeyReceiver, SIGNAL(capturedKey(Qt::Key, Qt::KeyboardModifiers, bool)), - this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); + commandKeysDisconnect(this, SLOT(commandKeyPressed(Qt::Key, Qt::KeyboardModifiers, bool))); } } diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index b91943bf1..69b410988 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -81,6 +81,8 @@ public: const QTimer& getMasterTimer() const { return m_masterTimer; } const MainSettings& getMainSettings() const { return m_settings; } + void commandKeysConnect(QObject *object, const char *slot); + void commandKeysDisconnect(QObject *object, const char *slot); friend class WebAPIAdapterGUI;