diff --git a/aboutbox.cpp b/aboutbox.cpp
index 4c3549e..6fa2f1f 100644
--- a/aboutbox.cpp
+++ b/aboutbox.cpp
@@ -15,8 +15,7 @@ aboutbox::aboutbox(QWidget *parent) :
ui->topText->setText("wfview version " + QString(WFVIEW_VERSION));
QString head = QString("
");
- QString copyright = QString("Copyright 2017-2022 Elliott H. Liggett, W6EL. All rights reserved. wfview source code is licensed under the GNU GPLv3.");
- QString nacode = QString(" Networking, audio, rigctl server, and much more written by Phil Taylor, M0VSE");
+ QString copyright = QString("Copyright 2017-2023 Elliott H. Liggett, W6EL and Phil E. Taylor, M0VSE. All rights reserved. wfview source code is licensed under the GNU GPLv3.");
QString scm = QString(" Source code and issues managed by Roeland Jansen, PA3MET");
QString doctest = QString(" Testing and development mentorship from Jim Nijkamp, PA8E.");
@@ -86,7 +85,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.");
// String it all together:
- QString aboutText = head + copyright + "\n" + nacode + "\n" + scm + "\n" + doctest + dedication + wfviewcommunityack;
+ QString aboutText = head + copyright + "\n" + "\n" + scm + "\n" + doctest + dedication + wfviewcommunityack;
aboutText.append(website + "\n" + donate + "\n"+ docs + support + contact +"\n");
aboutText.append("\n" + ssCredit + "\n" + rsCredit + "\n");
diff --git a/controllersetup.cpp b/controllersetup.cpp
index dcc1a9f..ffa0f73 100644
--- a/controllersetup.cpp
+++ b/controllersetup.cpp
@@ -7,157 +7,321 @@ controllerSetup::controllerSetup(QWidget* parent) :
ui(new Ui::controllerSetup)
{
ui->setupUi(this);
- scene = new controllerScene();
- connect(scene, SIGNAL(mousePressed(QPoint)), this, SLOT(mousePressed(QPoint)));
- ui->graphicsView->setScene(scene);
- ui->qkBrightCombo->setVisible(false);
- ui->qkOrientCombo->setVisible(false);
- ui->qkSpeedCombo->setVisible(false);
- ui->qkColorButton->setVisible(false);
- ui->qkTimeoutSpin->setVisible(false);
- ui->qkTimeoutLabel->setVisible(false);
- textItem = scene->addText("No USB controller found");
- textItem->setDefaultTextColor(Qt::gray);
+ ui->tabWidget->clear();
+ ui->tabWidget->hide();
+ noControllersText = new QLabel("No USB controller found");
+ noControllersText->setStyleSheet("QLabel { color : gray; }");
+ ui->hboxLayout->addWidget(noControllersText);
this->resize(this->sizeHint());
}
controllerSetup::~controllerSetup()
{
- /*
- // Remove any existing button text:
- for (QGraphicsItem* item : scene->items())
+ qInfo(logUsbControl()) << "Deleting controllerSetup() window";
+ delete noControllersText;
+ delete updateDialog;
+ delete ui; // Will delete all content in all tabs
+ tabs.clear();
+ // Step through ALL buttons and knobs setting their text to NULL (just in case)
+ for (auto b = buttons->begin(); b != buttons->end(); b++)
{
- QGraphicsTextItem* txt = qgraphicsitem_cast(item);
- if (!txt || txt == textItem)
- continue;
- scene->removeItem(txt);
- delete txt;
+ b->text=Q_NULLPTR;
+ b->bgRect=Q_NULLPTR;
}
- if (onEventProxy != Q_NULLPTR) {
- scene->removeItem(onEventProxy);
- onEventProxy = Q_NULLPTR;
- delete onEvent;
- onEvent = Q_NULLPTR;
+ for (auto k= knobs->begin(); k != knobs->end(); k++)
+ {
+ k->text=Q_NULLPTR;
}
- if (offEventProxy != Q_NULLPTR) {
- scene->removeItem(offEventProxy);
- offEventProxy = Q_NULLPTR;
- delete offEvent;
- offEvent = Q_NULLPTR;
- }
- if (knobEventProxy != Q_NULLPTR) {
- scene->removeItem(knobEventProxy);
- knobEventProxy = Q_NULLPTR;
- delete knobEvent;
- knobEvent = Q_NULLPTR;
- }
- */
-
- if (bgImage != Q_NULLPTR) {
- scene->removeItem(bgImage);
- delete bgImage;
- bgImage = Q_NULLPTR;
- }
-
- delete textItem;
- delete scene;
- delete ui;
}
-void controllerSetup::mousePressed(QPoint p)
+void controllerSetup::hideEvent(QHideEvent *event)
{
- // Receive mouse event from the scene
- qDebug() << "Looking for button Point x=" << p.x() << " y=" << p.y();
- if (onEvent == Q_NULLPTR|| offEvent == Q_NULLPTR|| knobEvent == Q_NULLPTR)
- {
- qInfo(logUsbControl()) << "Event missing, cannot continue...";
- return;
- }
-
- bool found = false;
- QMutexLocker locker(mutex);
+ Q_UNUSED(event)
+ qDebug(logUsbControl()) << "Controller window hideEvent()";
+ updateDialog->hide();
+}
-
- for (BUTTON& b : *buttons)
- {
- if (b.dev == currentDevice && b.pos.contains(p))
+void controllerSetup::on_tabWidget_currentChanged(int index)
+{
+ // We may get the indexChanged event before the tabWidget has been initialized
+ if (ui->tabWidget->widget(index) != Q_NULLPTR) {
+ QString path = ui->tabWidget->widget(index)->objectName();
+ auto tab = tabs.find(path);
+ if (tab != tabs.end())
{
- found = true;
- currentButton = &b;
- qDebug() << "Button" << currentButton->num << "On Event" << currentButton->onCommand->text << "Off Event" << currentButton->offCommand->text;
- onEvent->blockSignals(true);
- onEvent->move(p);
- onEvent->setCurrentIndex(onEvent->findData(currentButton->onCommand->index));
- onEvent->show();
- onEvent->blockSignals(false);
-
- p.setY(p.y() + 40);
- offEvent->blockSignals(true);
- offEvent->move(p);
- offEvent->setCurrentIndex(offEvent->findData(currentButton->offCommand->index));
- offEvent->show();
- offEvent->blockSignals(false);
- knobEvent->hide();
- break;
+ this->resize(this->sizeHint());
}
}
- if (!found) {
- for (KNOB& k : *knobs)
- {
- if (k.dev == currentDevice && k.pos.contains(p))
- {
- found = true;
- currentKnob = &k;
- qDebug() << "Knob" << currentKnob->num << "Event" << currentKnob->command->text;
- knobEvent->blockSignals(true);
- knobEvent->move(p);
- knobEvent->setCurrentIndex(knobEvent->findData(currentKnob->command->index));
- knobEvent->show();
- knobEvent->blockSignals(false);
- onEvent->hide();
- offEvent->hide();
- break;
+ if (updateDialog != Q_NULLPTR)
+ {
+ updateDialog->hide();
+ }
+
+}
+
+void controllerSetup::init(usbDevMap* dev, QVector* but, QVector* kb, QVector* cmd, QMutex* mut)
+{
+ // Store pointers to all current settings
+ devices = dev;
+ buttons = but;
+ knobs = kb;
+ commands = cmd;
+ mutex = mut;
+
+ updateDialog = new QDialog(this);
+ // Not sure if I like it Frameless or not?
+ updateDialog->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
+
+ QGridLayout* udLayout = new QGridLayout(updateDialog);
+
+ onLabel = new QLabel("On");
+ udLayout->addWidget(onLabel,0,0);
+ onEvent = new QComboBox();
+ udLayout->addWidget(onEvent,0,1);
+ onLabel->setBuddy(onEvent);
+
+ offLabel = new QLabel("Off");
+ udLayout->addWidget(offLabel,1,0);
+ offEvent = new QComboBox();
+ udLayout->addWidget(offEvent,1,1);
+ offLabel->setBuddy(offEvent);
+
+ knobLabel = new QLabel("Knob");
+ udLayout->addWidget(knobLabel,2,0);
+ knobEvent = new QComboBox();
+ udLayout->addWidget(knobEvent,2,1);
+ knobLabel->setBuddy(knobEvent);
+
+ ledNumber = new QSpinBox();
+ ledNumber->setPrefix("LED: ");
+ ledNumber->setMinimum(0);
+ udLayout->addWidget(ledNumber,3,1);
+
+ buttonLatch = new QCheckBox();
+ buttonLatch->setText("Toggle");
+ udLayout->addWidget(buttonLatch,4,0);
+
+ QHBoxLayout* colorLayout = new QHBoxLayout();
+ udLayout->addLayout(colorLayout,4,1);
+
+ buttonOnColor = new QPushButton("Color");
+ colorLayout->addWidget(buttonOnColor);
+
+ buttonOffColor = new QPushButton("Pressed");
+ colorLayout->addWidget(buttonOffColor);
+
+ buttonIcon = new QPushButton("Icon");
+ udLayout->addWidget(buttonIcon,5,0);
+ iconLabel = new QLabel("");
+ udLayout->addWidget(iconLabel,5,1);
+ udLayout->setAlignment(iconLabel,Qt::AlignCenter);
+ udLayout->setSizeConstraint(QLayout::SetFixedSize);
+
+ updateDialog->hide();
+
+ onEvent->clear();
+ offEvent->clear();
+ knobEvent->clear();
+
+ for (COMMAND& c : *commands) {
+ if (c.cmdType == commandButton || c.cmdType == commandAny) {
+ if (c.command == cmdSeparator) {
+ onEvent->insertSeparator(onEvent->count());
+ offEvent->insertSeparator(offEvent->count());
+
+ } else {
+ onEvent->addItem(c.text, c.index);
+ offEvent->addItem(c.text, c.index);
+ }
+ }
+ if (c.cmdType == commandKnob || c.cmdType == commandAny) {
+ if (c.command == cmdSeparator) {
+ knobEvent->insertSeparator(knobEvent->count());
+ } else {
+ knobEvent->addItem(c.text, c.index);
}
}
}
- if (!found) {
- onEvent->hide();
- offEvent->hide();
+ connect(offEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(offEventIndexChanged(int)));
+ connect(onEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(onEventIndexChanged(int)));
+ connect(knobEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(knobEventIndexChanged(int)));
+ connect(buttonOnColor, SIGNAL(clicked()), this, SLOT(buttonOnColorClicked()));
+ connect(buttonOffColor, SIGNAL(clicked()), this, SLOT(buttonOffColorClicked()));
+ connect(buttonIcon, SIGNAL(clicked()), this, SLOT(buttonIconClicked()));
+ connect(buttonLatch, SIGNAL(stateChanged(int)), this, SLOT(latchStateChanged(int)));
+ connect(ledNumber, SIGNAL(valueChanged(int)), this, SLOT(ledNumberChanged(int)));
+}
+
+void controllerSetup::showMenu(controllerScene* scene, QPoint p)
+{
+ Q_UNUSED (scene) // We might want it in the future?
+
+ // Receive mouse event from the scene
+ qDebug() << "Looking for knob or button at Point x=" << p.x() << " y=" << p.y();
+
+ QPoint gp = this->mapToGlobal(p);
+
+
+ // Did the user click on a button?
+ auto but = std::find_if(buttons->begin(), buttons->end(), [p, this](BUTTON& b)
+ { return (b.parent != Q_NULLPTR && b.pos.contains(p) && b.page == b.parent->currentPage && ui->tabWidget->currentWidget()->objectName() == b.path ); });
+
+ if (but != buttons->end())
+ {
+ currentButton = &(*but);
+ currentKnob = Q_NULLPTR;
+ qDebug() << "Button" << currentButton->num << "On Event" << currentButton->onCommand->text << "Off Event" << currentButton->offCommand->text;
+
+ updateDialog->setWindowTitle(QString("Update button %0").arg(but->num));
+
+ onEvent->blockSignals(true);
+ onEvent->setCurrentIndex(onEvent->findData(currentButton->onCommand->index));
+ onEvent->show();
+ onLabel->show();
+ onEvent->blockSignals(false);
+
+ offEvent->blockSignals(true);
+ offEvent->setCurrentIndex(offEvent->findData(currentButton->offCommand->index));
+ offEvent->show();
+ offLabel->show();
+ offEvent->blockSignals(false);
knobEvent->hide();
+ knobLabel->hide();
+
+ buttonLatch->blockSignals(true);
+ buttonLatch->setChecked(currentButton->toggle);
+ buttonLatch->blockSignals(false);
+ buttonLatch->show();
+
+ ledNumber->blockSignals(true);
+ ledNumber->setMaximum(currentButton->parent->type.leds);
+ ledNumber->setValue(currentButton->led);
+ ledNumber->blockSignals(false);
+
+ switch (currentButton->parent->type.model)
+ {
+ case RC28:
+ case eCoderPlus:
+ ledNumber->show();
+ buttonOnColor->hide();
+ buttonOffColor->hide();
+ buttonIcon->hide();
+ iconLabel->hide();
+ break;
+ case StreamDeckMini:
+ case StreamDeckMiniV2:
+ case StreamDeckOriginal:
+ case StreamDeckOriginalV2:
+ case StreamDeckOriginalMK2:
+ case StreamDeckXL:
+ case StreamDeckXLV2:
+ case StreamDeckPlus:
+ buttonOnColor->setStyleSheet(QString("background-color: %1").arg(currentButton->backgroundOn.name(QColor::HexArgb)));
+ buttonOffColor->setStyleSheet(QString("background-color: %1").arg(currentButton->backgroundOff.name(QColor::HexArgb)));
+ buttonOnColor->show();
+ buttonOffColor->show();
+ buttonIcon->show();
+ iconLabel->setText(currentButton->iconName);
+ iconLabel->show();
+ break;
+ default:
+ buttonOnColor->hide();
+ buttonOffColor->hide();
+ buttonIcon->hide();
+ iconLabel->hide();
+ ledNumber->hide();
+ break;
+ }
+
+ updateDialog->show();
+ updateDialog->move(gp);
+ updateDialog->adjustSize();
+ updateDialog->raise();
+ } else {
+ // It wasn't a button so was it a knob?
+ auto kb = std::find_if(knobs->begin(), knobs->end(), [p, this](KNOB& k)
+ { return (k.parent != Q_NULLPTR && k.pos.contains(p) && k.page == k.parent->currentPage && ui->tabWidget->currentWidget()->objectName() == k.path ); });
+
+ if (kb != knobs->end())
+ {
+ currentKnob = &(*kb);
+ currentButton = Q_NULLPTR;
+ qDebug() << "Knob" << currentKnob->num << "Event" << currentKnob->command->text;
+
+ updateDialog->setWindowTitle(QString("Update knob %0").arg(kb->num));
+
+ knobEvent->blockSignals(true);
+ knobEvent->setCurrentIndex(knobEvent->findData(currentKnob->command->index));
+ knobEvent->show();
+ knobLabel->show();
+ knobEvent->blockSignals(false);
+ onEvent->hide();
+ offEvent->hide();
+ onLabel->hide();
+ offLabel->hide();
+ buttonLatch->hide();
+ buttonOnColor->hide();
+ buttonOffColor->hide();
+ buttonIcon->hide();
+ iconLabel->hide();
+ ledNumber->hide();
+
+ updateDialog->show();
+ updateDialog->move(gp);
+ updateDialog->adjustSize();
+ updateDialog->raise();
+ }
+ else
+ {
+ // It wasn't either so hide the updateDialog();
+ updateDialog->hide();
+ currentButton = Q_NULLPTR;
+ currentKnob = Q_NULLPTR;
+ }
}
}
+
void controllerSetup::onEventIndexChanged(int index) {
Q_UNUSED(index);
-
+ // If command is changed, delete current command and deep copy the new command
if (currentButton != Q_NULLPTR && onEvent->currentData().toInt() < commands->size()) {
QMutexLocker locker(mutex);
currentButton->onCommand = &commands->at(onEvent->currentData().toInt());
- currentButton->onText->setPlainText(currentButton->onCommand->text);
- currentButton->onText->setPos(currentButton->pos.center().x() - currentButton->onText->boundingRect().width() / 2,
- (currentButton->pos.center().y() - currentButton->onText->boundingRect().height() / 2)-6);
+ currentButton->text->setPlainText(currentButton->onCommand->text);
+ currentButton->text->setPos(currentButton->pos.center().x() - currentButton->text->boundingRect().width() / 2,
+ (currentButton->pos.center().y() - currentButton->text->boundingRect().height() / 2));
// Signal that any button programming on the device should be completed.
- emit programButton(currentButton->num, currentButton->onCommand->text);
+ if (currentButton->icon == Q_NULLPTR) {
+ emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,Q_NULLPTR,¤tButton->backgroundOn);
+ }
}
}
void controllerSetup::offEventIndexChanged(int index) {
Q_UNUSED(index);
+ // If command is changed, delete current command and deep copy the new command
if (currentButton != Q_NULLPTR && offEvent->currentData().toInt() < commands->size()) {
QMutexLocker locker(mutex);
currentButton->offCommand = &commands->at(offEvent->currentData().toInt());
- currentButton->offText->setPlainText(currentButton->offCommand->text);
- currentButton->offText->setPos(currentButton->pos.center().x() - currentButton->offText->boundingRect().width() / 2,
- (currentButton->pos.center().y() - currentButton->offText->boundingRect().height() / 2)+6);
}
}
+void controllerSetup::ledNumberChanged(int index) {
+ if (currentButton != Q_NULLPTR) {
+ QMutexLocker locker(mutex);
+ currentButton->led = index;
+ }
+}
+
+
void controllerSetup::knobEventIndexChanged(int index) {
Q_UNUSED(index);
+ // If command is changed, delete current command and deep copy the new command
if (currentKnob != Q_NULLPTR && knobEvent->currentData().toInt() < commands->size()) {
QMutexLocker locker(mutex);
currentKnob->command = &commands->at(knobEvent->currentData().toInt());
@@ -169,292 +333,664 @@ void controllerSetup::knobEventIndexChanged(int index) {
}
-void controllerSetup::newDevice(unsigned char devType, QVector* but, QVector* kb, QVector* cmd, QMutex* mut)
+void controllerSetup::buttonOnColorClicked()
{
- buttons = but;
- knobs = kb;
- commands = cmd;
- mutex = mut;
-
- QMutexLocker locker(mutex);
-
- // Remove any existing button text:
- for (QGraphicsItem* item : scene->items())
- {
- QGraphicsTextItem* txt = qgraphicsitem_cast(item);
- if (!txt || txt==textItem)
- continue;
- scene->removeItem(txt);
- delete txt;
- }
-
- if (bgImage != Q_NULLPTR) {
- scene->removeItem(bgImage);
- delete bgImage;
- bgImage = Q_NULLPTR;
- }
- if (onEventProxy != Q_NULLPTR) {
- scene->removeItem(onEventProxy);
- onEventProxy = Q_NULLPTR;
- delete onEvent;
- onEvent = Q_NULLPTR;
- }
- if (offEventProxy != Q_NULLPTR) {
- scene->removeItem(offEventProxy);
- offEventProxy = Q_NULLPTR;
- delete offEvent;
- offEvent = Q_NULLPTR;
- }
- if (knobEventProxy != Q_NULLPTR) {
- scene->removeItem(knobEventProxy);
- knobEventProxy = Q_NULLPTR;
- delete knobEvent;
- knobEvent = Q_NULLPTR;
- }
-
- QImage image;
-
- switch (devType) {
- case shuttleXpress:
- image.load(":/resources/shuttlexpress.png");
- deviceName = "shuttleXpress";
- break;
- case shuttlePro2:
- image.load(":/resources/shuttlepro.png");
- deviceName = "shuttlePro2";
- break;
- case RC28:
- image.load(":/resources/rc28.png");
- deviceName = "RC28";
- break;
- case xBoxGamepad:
- image.load(":/resources/xbox.png");
- deviceName = "XBox";
- break;
- case eCoderPlus:
- image.load(":/resources/ecoder.png");
- deviceName = "eCoderPlus";
- break;
- case QuickKeys:
- image.load(":/resources/quickkeys.png");
- deviceName = "QuickKeys";
- break;
- default:
- textItem->show();
- ui->graphicsView->setSceneRect(scene->itemsBoundingRect());
- this->adjustSize();
- break;
- }
-
- textItem->hide();
- bgImage = new QGraphicsPixmapItem(QPixmap::fromImage(image));
- scene->addItem(bgImage);
-
- ui->graphicsView->setMinimumSize(bgImage->boundingRect().width() + 100, bgImage->boundingRect().height() + 2);
- currentDevice = devType;
-
- if (currentDevice == QuickKeys) {
- ui->qkBrightCombo->setVisible(true);
- ui->qkOrientCombo->setVisible(true);
- ui->qkSpeedCombo->setVisible(true);
- ui->qkColorButton->setVisible(true);
- ui->qkTimeoutSpin->setVisible(true);
- ui->qkTimeoutLabel->setVisible(true);
- }
- else
- {
- ui->qkBrightCombo->setVisible(false);
- ui->qkOrientCombo->setVisible(false);
- ui->qkSpeedCombo->setVisible(false);
- ui->qkColorButton->setVisible(false);
- ui->qkTimeoutSpin->setVisible(false);
- ui->qkTimeoutLabel->setVisible(false);
- }
-
- if (currentDevice != usbNone)
- {
- offEvent = new QComboBox;
- onEvent = new QComboBox;
- knobEvent = new QComboBox;
-
- onEvent->blockSignals(true);
- offEvent->blockSignals(true);
- knobEvent->blockSignals(true);
-
- onEvent->clear();
- offEvent->clear();
- knobEvent->clear();
-
- onEvent->setMaxVisibleItems(5);
- offEvent->setMaxVisibleItems(5);
- knobEvent->setMaxVisibleItems(5);
-
- onEvent->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- offEvent->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- knobEvent->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-
- onEvent->setStyleSheet("combobox-popup: 0;");
- offEvent->setStyleSheet("combobox-popup: 0;");
- knobEvent->setStyleSheet("combobox-popup: 0;");
-
- for (COMMAND& c : *commands) {
- if (c.cmdType == commandButton || c.text == "None") {
- onEvent->addItem(c.text, c.index);
- offEvent->addItem(c.text, c.index);
- }
-
- if (c.cmdType == commandKnob || c.text == "None") {
- knobEvent->addItem(c.text, c.index);
- }
- }
-
- onEvent->blockSignals(false);
- offEvent->blockSignals(false);
- knobEvent->blockSignals(false);
-
- onEvent->hide();
- offEvent->hide();
- knobEvent->hide();
-
- // Set button text
- for (BUTTON& b : *buttons)
- {
-
- if (b.dev == currentDevice) {
- b.onText = new QGraphicsTextItem(b.onCommand->text);
- b.onText->setDefaultTextColor(b.textColour);
- scene->addItem(b.onText);
- b.onText->setPos(b.pos.center().x() - b.onText->boundingRect().width() / 2,
- (b.pos.center().y() - b.onText->boundingRect().height() / 2) - 6);
- emit programButton(b.num, b.onCommand->text); // Program the button with ontext if supported
-
- b.offText = new QGraphicsTextItem(b.offCommand->text);
- b.offText->setDefaultTextColor(b.textColour);
- scene->addItem(b.offText);
- b.offText->setPos(b.pos.center().x() - b.offText->boundingRect().width() / 2,
- (b.pos.center().y() - b.onText->boundingRect().height() / 2) + 6);
- }
- }
-
- // Set knob text
-
- for (KNOB& k : *knobs)
- {
- if (k.dev == currentDevice) {
- k.text = new QGraphicsTextItem(k.command->text);
- k.text->setDefaultTextColor(k.textColour);
- scene->addItem(k.text);
- k.text->setPos(k.pos.center().x() - k.text->boundingRect().width() / 2,
- (k.pos.center().y() - k.text->boundingRect().height() / 2));
- }
- }
- ui->graphicsView->setSceneRect(scene->itemsBoundingRect());
- ui->graphicsView->resize(ui->graphicsView->sizeHint());
- //this->resize(this->sizeHint());
- this->adjustSize();
-
- // Add comboboxes to scene after everything else.
- offEventProxy = scene->addWidget(offEvent);
- connect(offEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(offEventIndexChanged(int)));
- onEventProxy = scene->addWidget(onEvent);
- connect(onEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(onEventIndexChanged(int)));
- knobEventProxy = scene->addWidget(knobEvent);
- connect(knobEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(knobEventIndexChanged(int)));
-
- if (currentDevice == QuickKeys) {
- // Finally update the device with the default values
- emit programBrightness((quint8)ui->qkBrightCombo->currentIndex() - 1);
- emit programOrientation((quint8)ui->qkOrientCombo->currentIndex());
- emit programSpeed((quint8)ui->qkSpeedCombo->currentIndex());
- emit programTimeout((quint8)ui->qkTimeoutSpin->value());
- emit programWheelColour((quint8)initialColor.red(), (quint8)initialColor.green(), (quint8)initialColor.blue());
- }
- }
-}
-
-void controllerSetup::receiveSensitivity(int val)
-{
- ui->sensitivitySlider->blockSignals(true);
- ui->sensitivitySlider->setValue(val);
- ui->sensitivitySlider->blockSignals(false);
-}
-
-void controllerSetup::on_sensitivitySlider_valueChanged(int val)
-{
- emit sendSensitivity(val);
-}
-
-void controllerSetup::on_qkBrightCombo_currentIndexChanged(int index)
-{
- if (index) {
- emit programBrightness((quint8)index - 1);
- }
- emit updateSettings((quint8)ui->qkBrightCombo->currentIndex(), (quint8)ui->qkOrientCombo->currentIndex(),
- (quint8)ui->qkSpeedCombo->currentIndex(), (quint8)ui->qkTimeoutSpin->value(), initialColor);
-}
-
-void controllerSetup::on_qkOrientCombo_currentIndexChanged(int index)
-{
- if (index) {
- emit programOrientation((quint8)index);
- emit programOverlay(3, QString("Orientation set to %0").arg(ui->qkOrientCombo->currentText()));
- }
- emit updateSettings((quint8)ui->qkBrightCombo->currentIndex(), (quint8)ui->qkOrientCombo->currentIndex(),
- (quint8)ui->qkSpeedCombo->currentIndex(), (quint8)ui->qkTimeoutSpin->value(), initialColor);
-}
-
-void controllerSetup::on_qkSpeedCombo_currentIndexChanged(int index)
-{
- if (index) {
- emit programSpeed((quint8)index);
- emit programOverlay(3, QString("Dial speed set to %0").arg(ui->qkSpeedCombo->currentText()));
- }
- emit updateSettings((quint8)ui->qkBrightCombo->currentIndex(), (quint8)ui->qkOrientCombo->currentIndex(),
- (quint8)ui->qkSpeedCombo->currentIndex(), (quint8)ui->qkTimeoutSpin->value(), initialColor);
-}
-
-void controllerSetup::on_qkColorButton_clicked()
-{
-
QColorDialog::ColorDialogOptions options;
options.setFlag(QColorDialog::ShowAlphaChannel, false);
options.setFlag(QColorDialog::DontUseNativeDialog, false);
- QColor selColor = QColorDialog::getColor(initialColor, this, "Select Color", options);
+ QColor selColor = QColorDialog::getColor(currentButton->backgroundOn, this, "Select Color to use for unpressed button", options);
- if(!selColor.isValid())
+ if(selColor.isValid() && currentButton != Q_NULLPTR)
{
- selColor = initialColor;
+ QMutexLocker locker(mutex);
+ currentButton->backgroundOn = selColor;
+ if (currentButton->graphics && currentButton->bgRect != Q_NULLPTR)
+ {
+ currentButton->bgRect->setBrush(currentButton->backgroundOn);
+ }
+ buttonOnColor->setStyleSheet(QString("background-color: %1").arg(currentButton->backgroundOn.name(QColor::HexArgb)));
+ emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,currentButton->icon,¤tButton->backgroundOn);
}
- initialColor = selColor;
- emit programWheelColour((quint8)selColor.red(), (quint8)selColor.green(), (quint8)initialColor.blue());
- emit updateSettings((quint8)ui->qkBrightCombo->currentIndex(), (quint8)ui->qkOrientCombo->currentIndex(),
- (quint8)ui->qkSpeedCombo->currentIndex(), (quint8)ui->qkTimeoutSpin->value(), initialColor);
}
-void controllerSetup::on_qkTimeoutSpin_valueChanged(int arg1)
+void controllerSetup::buttonOffColorClicked()
{
- emit programTimeout((quint8)arg1);
- emit programOverlay(3, QString("Sleep timeout set to %0 minutes").arg(arg1));
- emit updateSettings((quint8)ui->qkBrightCombo->currentIndex(), (quint8)ui->qkOrientCombo->currentIndex(),
- (quint8)ui->qkSpeedCombo->currentIndex(), (quint8)ui->qkTimeoutSpin->value(), initialColor);
+ QColorDialog::ColorDialogOptions options;
+ options.setFlag(QColorDialog::ShowAlphaChannel, false);
+ options.setFlag(QColorDialog::DontUseNativeDialog, false);
+ QColor selColor = QColorDialog::getColor(currentButton->backgroundOff, this, "Select Color to use for pressed button", options);
+
+ if(selColor.isValid() && currentButton != Q_NULLPTR)
+ {
+ QMutexLocker locker(mutex);
+ currentButton->backgroundOff = selColor;
+ buttonOffColor->setStyleSheet(QString("background-color: %1").arg(currentButton->backgroundOff.name(QColor::HexArgb)));
+ }
}
-void controllerSetup::setDefaults(quint8 bright, quint8 orient, quint8 speed, quint8 timeout, QColor color)
+void controllerSetup::buttonIconClicked()
{
- ui->qkBrightCombo->blockSignals(true);
- ui->qkSpeedCombo->blockSignals(true);
- ui->qkOrientCombo->blockSignals(true);
- ui->qkTimeoutSpin->blockSignals(true);
+ QString file = QFileDialog::getOpenFileName(this,"Select Icon Filename",".","Images (*png *.jpg)");
+ if (!file.isEmpty()) {
+ QFileInfo info = QFileInfo(file);
+ currentButton->iconName = info.fileName();
+ iconLabel->setText(currentButton->iconName);
+ QImage image;
+ image.load(file);
+ if (currentButton->icon != Q_NULLPTR)
+ delete currentButton->icon;
+ currentButton->icon = new QImage(image.scaled(currentButton->parent->type.iconSize,currentButton->parent->type.iconSize));
+ } else {
+ if (currentButton->icon != Q_NULLPTR)
+ {
+ currentButton->iconName = "";
+ delete currentButton->icon;
+ currentButton->icon = Q_NULLPTR;
+ }
+ }
+ iconLabel->setText(currentButton->iconName);
+ emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,currentButton->icon, ¤tButton->backgroundOn);
+}
- ui->qkBrightCombo->setCurrentIndex((int)bright);
- ui->qkOrientCombo->setCurrentIndex((int)orient);
- ui->qkSpeedCombo->setCurrentIndex((int)speed);
- ui->qkTimeoutSpin->setValue((int)timeout);
- initialColor = color;
+void controllerSetup::latchStateChanged(int state)
+{
+ if (currentButton != Q_NULLPTR) {
+ QMutexLocker locker(mutex);
+ currentButton->toggle=(int)state;
+ }
+}
- ui->qkBrightCombo->blockSignals(false);
- ui->qkSpeedCombo->blockSignals(false);
- ui->qkOrientCombo->blockSignals(false);
- ui->qkTimeoutSpin->blockSignals(false);
+void controllerSetup::removeDevice(USBDEVICE* dev)
+{
+ QMutexLocker locker(mutex);
+
+ /* We need to manually delete everything that has been created for this tab */
+ auto tab = tabs.find(dev->path);
+ if (tab == tabs.end())
+ {
+ qWarning(logUsbControl()) << "Cannot find tabContent for deleted tab" << dev->path;
+ return;
+ }
+
+ for (auto b = buttons->begin();b != buttons->end(); b++)
+ {
+ if (b->parent == dev && b->page == dev->currentPage)
+ {
+ if (b->text != Q_NULLPTR) {
+ tab.value()->scene->removeItem(b->text);
+ delete b->text;
+ b->text = Q_NULLPTR;
+ }
+ b->offCommand = Q_NULLPTR;
+ b->onCommand = Q_NULLPTR;
+ if (b->icon != Q_NULLPTR) {
+ delete b->icon;
+ b->icon=Q_NULLPTR;
+ }
+ if (b->bgRect != Q_NULLPTR) {
+ tab.value()->scene->removeItem(b->bgRect);
+ delete b->bgRect;
+ b->bgRect = Q_NULLPTR;
+ }
+
+ }
+ }
+
+ for (auto k = knobs->begin();k != knobs->end(); k++)
+ {
+ if (k->parent == dev && k->page == dev->currentPage)
+ {
+ if (k->text != Q_NULLPTR) {
+ tab.value()->scene->removeItem(k->text);
+ delete k->text;
+ k->text = Q_NULLPTR;
+ k->command = Q_NULLPTR;
+ }
+ }
+ }
+
+
+ qDebug(logUsbControl()) << "Removing tab content" << dev->product;
+
+ if (tab.value()->bgImage != Q_NULLPTR) {
+ tab.value()->scene->removeItem(tab.value()->bgImage);
+ delete tab.value()->bgImage;
+ }
+ delete tab.value()->scene;
+
+ // Find the tab within the tabWidget
+ for (int i = 0; i < ui->tabWidget->count(); i++) {
+ auto widget = ui->tabWidget->widget(i);
+ if (widget->objectName() == dev->path) {
+ ui->tabWidget->removeTab(i);
+ break;
+ }
+ }
+
+ delete tab.value();
+ tabs.remove(dev->path);
+
+ // Hide the tabWidget if no tabs exist
+ if (ui->tabWidget->count() == 0)
+ {
+ ui->tabWidget->hide();
+ noControllersText->show();
+ this->adjustSize();
+ }
+}
+
+void controllerSetup::newDevice(USBDEVICE* dev)
+{
+ QMutexLocker locker(mutex);
+
+ for (int i=0; itabWidget->count();i++) {
+ if (ui->tabWidget->widget(i)->objectName() == dev->path)
+ {
+ qInfo(logUsbControl()) <<"Tab for " << dev->product << "("<< dev->path << ") Already exists!";
+ return;
+ }
+ }
+
+ auto tab = tabs.find(dev->path);
+ if (tab != tabs.end())
+ {
+ qInfo(logUsbControl()) <<"Tab content for " << dev->product << "("<< dev->path << ") Already exists!";
+ return;
+ }
+
+
+ qDebug(logUsbControl()) << "Adding new tab for" << dev->product;
+ noControllersText->hide();
+
+ tabContent* c = new tabContent();
+
+ c->tab = new QWidget();
+ c->widget = new QWidget();
+
+ c->tab->setObjectName(dev->path);
+ ui->tabWidget->addTab(c->tab,dev->product);
+
+ // Create the different layouts required
+ c->mainLayout = new QVBoxLayout(c->tab);
+ c->layout = new QVBoxLayout();
+ c->topLayout = new QHBoxLayout();
+ c->sensLayout = new QHBoxLayout();
+ c->grid = new QGridLayout();
+
+ c->mainLayout->addLayout(c->topLayout);
+ c->mainLayout->addWidget(c->widget);
+ c->widget->setLayout(c->layout);
+
+ c->disabled = new QCheckBox("Disable");
+ c->topLayout->addWidget(c->disabled);
+ connect(c->disabled, qOverload(&QCheckBox::clicked),
+ [dev,this,c](bool checked) { this->disableClicked(dev,checked,c->widget); });
+ c->disabled->setChecked(dev->disabled);
+
+ c->message = new QLabel();
+ if (dev->connected) {
+ c->message->setStyleSheet("QLabel { color : green; }");
+ c->message->setText("Connected");
+ } else {
+ c->message->setStyleSheet("QLabel { color : red; }");
+ c->message->setText("Not Connected");
+ }
+ c->topLayout->addWidget(c->message);
+ c->message->setAlignment(Qt::AlignRight);
+
+ c->view = new QGraphicsView();
+ c->layout->addWidget(c->view);
+
+ c->layout->addLayout(c->sensLayout);
+ c->sensLabel = new QLabel("Sensitivity");
+ c->sensLayout->addWidget(c->sensLabel);
+ c->sens = new QSlider(Qt::Horizontal);
+ c->sens->setMinimum(1);
+ c->sens->setMaximum(21);
+ c->sens->setInvertedAppearance(true);
+ c->sensLayout->addWidget(c->sens);
+ c->sens->setValue(dev->sensitivity);
+ connect(c->sens, &QSlider::valueChanged,
+ [dev,this](int val) { this->sensitivityMoved(dev,val); });
+
+ c->sensLayout->addStretch(0);
+
+ c->pageLabel = new QLabel("Page:");
+ c->sensLayout->addWidget(c->pageLabel);
+ c->page = new QSpinBox();
+ c->page->setValue(1);
+ c->page->setMinimum(1);
+ c->page->setMaximum(dev->pages);
+ c->page->setToolTip("Select current page to edit");
+ c->sensLayout->addWidget(c->page);
+ dev->pageSpin = c->page;
+
+ c->image = new QImage();
+ switch (dev->type.model) {
+ case shuttleXpress:
+ c->image->load(":/resources/shuttlexpress.png");
+ break;
+ case shuttlePro2:
+ c->image->load(":/resources/shuttlepro.png");
+ break;
+ case RC28:
+ c->image->load(":/resources/rc28.png");
+ break;
+ case xBoxGamepad:
+ c->image->load(":/resources/xbox.png");
+ break;
+ case eCoderPlus:
+ c->image->load(":/resources/ecoder.png");
+ break;
+ case QuickKeys:
+ c->image->load(":/resources/quickkeys.png");
+ break;
+ case StreamDeckOriginal:
+ case StreamDeckOriginalV2:
+ case StreamDeckOriginalMK2:
+ c->image->load(":/resources/streamdeck.png");
+ break;
+ case StreamDeckMini:
+ case StreamDeckMiniV2:
+ c->image->load(":/resources/streamdeckmini.png");
+ break;
+ case StreamDeckXL:
+ case StreamDeckXLV2:
+ c->image->load(":/resources/streamdeckxl.png");
+ break;
+ case StreamDeckPlus:
+ c->image->load(":/resources/streamdeckplus.png");
+ break;
+ case StreamDeckPedal:
+ c->image->load(":/resources/streamdeckpedal.png");
+ break;
+ default:
+ this->adjustSize();
+ break;
+ }
+
+ c->bgImage = new QGraphicsPixmapItem(QPixmap::fromImage(*c->image));
+ c->view->setMinimumSize(c->bgImage->boundingRect().width() + 2, c->bgImage->boundingRect().height() + 2);
+ ui->tabWidget->show();
+
+ c->scene = new controllerScene();
+ c->view->setScene(c->scene);
+ connect(c->scene, SIGNAL(showMenu(controllerScene*,QPoint)), this, SLOT(showMenu(controllerScene*,QPoint)));
+ c->scene->addItem(c->bgImage);
+
+
+ c->layout->addLayout(c->grid);
+
+ c->brightLabel = new QLabel("Brightness");
+ c->grid->addWidget(c->brightLabel,0,0);
+ c->brightness = new QComboBox();
+ c->brightness->addItem("Off");
+ c->brightness->addItem("Low");
+ c->brightness->addItem("Medium");
+ c->brightness->addItem("High");
+ c->brightness->setCurrentIndex(dev->brightness);
+ c->grid->addWidget(c->brightness,1,0);
+ connect(c->brightness, qOverload(&QComboBox::currentIndexChanged),
+ [dev,this](int index) { this->brightnessChanged(dev,index); });
+
+ c->speedLabel = new QLabel("Speed");
+ c->grid->addWidget(c->speedLabel,0,1);
+ c->speed = new QComboBox();
+ c->speed->addItem("Fastest");
+ c->speed->addItem("Faster");
+ c->speed->addItem("Normal");
+ c->speed->addItem("Slower");
+ c->speed->addItem("Slowest");
+ c->speed->setCurrentIndex(dev->speed);
+ c->grid->addWidget(c->speed,1,1);
+ connect(c->speed, qOverload(&QComboBox::currentIndexChanged),
+ [dev,this](int index) { this->speedChanged(dev,index); });
+
+ c->orientLabel = new QLabel("Orientation");
+ c->grid->addWidget(c->orientLabel,0,2);
+ c->orientation = new QComboBox();
+ c->orientation->addItem("Rotate 0");
+ c->orientation->addItem("Rotate 90");
+ c->orientation->addItem("Rotate 180");
+ c->orientation->addItem("Rotate 270");
+ c->orientation->setCurrentIndex(dev->orientation);
+ c->grid->addWidget(c->orientation,1,2);
+ connect(c->orientation, qOverload(&QComboBox::currentIndexChanged),
+ [dev,this](int index) { this->orientationChanged(dev,index); });
+
+ c->color = new QPushButton("Color");
+ c->color->setStyleSheet(QString("background-color: %1").arg(dev->color.name(QColor::HexArgb)));
+ c->grid->addWidget(c->color,1,3);
+ connect(c->color, &QPushButton::clicked,
+ [dev,c,this]() { this->colorPicker(dev,c->color,dev->color); });
+
+ c->timeoutLabel = new QLabel("Timeout");
+ c->grid->addWidget(c->timeoutLabel,0,4);
+ c->timeout = new QSpinBox();
+ c->timeout->setValue(dev->timeout);
+ c->grid->addWidget(c->timeout,1,4);
+ connect(c->timeout, qOverload(&QSpinBox::valueChanged),
+ [dev,this](int index) { this->timeoutChanged(dev,index); });
+
+ c->pagesLabel = new QLabel("Num Pages");
+ c->grid->addWidget(c->pagesLabel,0,5);
+ c->pages = new QSpinBox();
+ c->pages->setValue(dev->pages);
+ c->pages->setMinimum(1);
+ c->grid->addWidget(c->pages,1,5);
+ connect(c->pages, qOverload(&QSpinBox::valueChanged),
+ [dev,this](int index) { this->pagesChanged(dev,index); });
+
+ for (int i=0;i<6;i++)
+ c->grid->setColumnStretch(i,1);
+
+ c->helpText = new QLabel();
+ c->helpText->setText("Button configuration: Right-click on each button to configure it.
");
+ c->helpText->setAlignment(Qt::AlignCenter);
+ c->layout->addWidget(c->helpText);
+
+
+ c->view->setSceneRect(c->scene->itemsBoundingRect());
+
+ this->adjustSize();
+
+ numTabs++;
+ tabs.insert(dev->path,c);
+
+ dev->uiCreated = true;
+
+ // Finally update the device with the default values
+ emit sendRequest(dev,usbFeatureType::featureSensitivity,dev->sensitivity);
+ emit sendRequest(dev,usbFeatureType::featureBrightness,dev->brightness);
+ emit sendRequest(dev,usbFeatureType::featureOrientation,dev->orientation);
+ emit sendRequest(dev,usbFeatureType::featureSpeed,dev->speed);
+ emit sendRequest(dev,usbFeatureType::featureTimeout,dev->timeout);
+ emit sendRequest(dev,usbFeatureType::featureColor,0,"", Q_NULLPTR, &dev->color);
+
+
+
+ // Attach pageChanged() here so we have access to all necessary vars
+ connect(c->page, qOverload(&QSpinBox::valueChanged),
+ [dev, this](int index) { this->pageChanged(dev, index); });
+
+// Hide all controls that are not relevant to this controller
+// We rely on being able to fallthrough case
+#if defined __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
+
+ switch (dev->type.model) {
+ case QuickKeys:
+ break;
+ case StreamDeckPedal:
+ c->sensLabel->setVisible(false);
+ c->sens->setVisible(false);
+ case shuttleXpress:
+ case shuttlePro2:
+ case RC28:
+ case xBoxGamepad:
+ case eCoderPlus:
+ c->brightLabel->setVisible(false);
+ c->speedLabel->setVisible(false);
+ c->timeoutLabel->setVisible(false);
+ c->orientLabel->setVisible(false);
+ c->brightness->setVisible(false);
+ c->speed->setVisible(false);
+ c->timeout->setVisible(false);
+ c->orientation->setVisible(false);
+ c->color->setVisible(false);
+ break;
+ case StreamDeckOriginal:
+ case StreamDeckOriginalV2:
+ case StreamDeckOriginalMK2:
+ case StreamDeckMini:
+ case StreamDeckMiniV2:
+ case StreamDeckXL:
+ case StreamDeckXLV2:
+ c->sensLabel->setVisible(false);
+ c->sens->setVisible(false); // No knobs!
+ case StreamDeckPlus:
+ c->speedLabel->setVisible(false);
+ c->timeoutLabel->setVisible(false);
+ c->orientLabel->setVisible(false);
+ c->speed->setVisible(false);
+ c->timeout->setVisible(false);
+ c->orientation->setVisible(false);
+ break;
+ default:
+ break;
+ }
+
+// Don't allow fallthrough elsewhere in the file.
+#if defined __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+ // pageChanged will update the buttons/knobs for the tab (using qTimer ensures mutex is unlocked first)
+ QTimer::singleShot(0, this, [=]() { pageChanged(dev,1); });
+
+}
+
+void controllerSetup::sensitivityMoved(USBDEVICE* dev, int val)
+{
+ qInfo(logUsbControl()) << "Setting sensitivity" << val <<"for device" << dev->product;
+ emit sendRequest(dev,usbFeatureType::featureSensitivity,val);
+}
+
+void controllerSetup::brightnessChanged(USBDEVICE* dev, int index)
+{
+ emit sendRequest(dev,usbFeatureType::featureBrightness,index);
+}
+
+void controllerSetup::orientationChanged(USBDEVICE* dev, int index)
+{
+ emit sendRequest(dev,usbFeatureType::featureOrientation,index);
+}
+
+void controllerSetup::speedChanged(USBDEVICE* dev, int index)
+{
+ emit sendRequest(dev,usbFeatureType::featureSpeed,index);
+}
+
+void controllerSetup::colorPicker(USBDEVICE* dev, QPushButton* btn, QColor current)
+{
+ QColorDialog::ColorDialogOptions options;
+ options.setFlag(QColorDialog::ShowAlphaChannel, false);
+ options.setFlag(QColorDialog::DontUseNativeDialog, false);
+ QColor selColor = QColorDialog::getColor(current, this, "Select Color", options);
+
+ if(selColor.isValid())
+ {
+ btn->setStyleSheet(QString("background-color: %1").arg(selColor.name(QColor::HexArgb)));
+ emit sendRequest(dev,usbFeatureType::featureColor,0, "", Q_NULLPTR, &selColor);
+ }
+}
+
+void controllerSetup::timeoutChanged(USBDEVICE* dev, int val)
+{
+ emit sendRequest(dev,usbFeatureType::featureTimeout,val);
+ emit sendRequest(dev,usbFeatureType::featureOverlay,val,QString("Sleep timeout set to %0 minutes").arg(val));
+}
+
+void controllerSetup::pagesChanged(USBDEVICE* dev, int val)
+{
+ emit programPages(dev,val);
+ dev->pageSpin->setMaximum(val); // Update pageSpin
+}
+
+void controllerSetup::pageChanged(USBDEVICE* dev, int val)
+{
+
+ QMutexLocker locker(mutex);
+
+ auto tab = tabs.find(dev->path);
+ if (tab == tabs.end())
+ {
+ qWarning(logUsbControl()) << "Cannot find tabContent while changing page" << dev->path;
+ return;
+ }
+
+
+ if (val > dev->pages)
+ val=1;
+ if (val < 1)
+ val = dev->pages;
+
+ updateDialog->hide(); // Hide the dialog if the page changes.
+
+ dev->currentPage=val;
+
+ // Need to block signals so this isn't called recursively.
+ dev->pageSpin->blockSignals(true);
+ dev->pageSpin->setValue(val);
+ dev->pageSpin->blockSignals(false);
+
+ // (re)set button text
+ for (auto b = buttons->begin();b != buttons->end(); b++)
+ {
+ if (b->parent == dev)
+ {
+ // Make sure we delete any other pages content and then update to latest.
+ if (b->text != Q_NULLPTR) {
+ tab.value()->scene->removeItem(b->text);
+ delete b->text;
+ b->text = Q_NULLPTR;
+ }
+ if (b->graphics && b->bgRect != Q_NULLPTR) {
+ tab.value()->scene->removeItem(b->bgRect);
+ delete b->bgRect;
+ b->bgRect = Q_NULLPTR;
+ }
+ if (b->page == dev->currentPage)
+ {
+ if (b->graphics)
+ {
+ b->bgRect = new QGraphicsRectItem(b->pos);
+ b->bgRect->setBrush(b->backgroundOn);
+ tab.value()->scene->addItem(b->bgRect);
+ }
+ b->text = new QGraphicsTextItem(b->onCommand->text);
+ b->text->setDefaultTextColor(b->textColour);
+ tab.value()->scene->addItem(b->text);
+ b->text->setPos(b->pos.center().x() - b->text->boundingRect().width() / 2,
+ (b->pos.center().y() - b->text->boundingRect().height() / 2));
+ emit sendRequest(dev,usbFeatureType::featureButton,b->num,b->onCommand->text,b->icon,&b->backgroundOn);
+ }
+ }
+ }
+ // Set knob text
+
+ for (auto k = knobs->begin();k != knobs->end(); k++)
+ {
+ if (k->parent == dev) {
+ if (k->text != Q_NULLPTR) {
+ tab.value()->scene->removeItem(k->text);
+ delete k->text;
+ k->text = Q_NULLPTR;
+ }
+ if (k->page == dev->currentPage)
+ {
+ k->text = new QGraphicsTextItem(k->command->text);
+ k->text->setDefaultTextColor(k->textColour);
+ tab.value()->scene->addItem(k->text);
+ k->text->setPos(k->pos.center().x() - k->text->boundingRect().width() / 2,
+ (k->pos.center().y() - k->text->boundingRect().height() / 2));
+ }
+ }
+ }
+}
+
+void controllerSetup::disableClicked(USBDEVICE* dev, bool clicked, QWidget* widget)
+{
+ // Disable checkbox has been clicked
+ emit programDisable(dev, clicked);
+
+ widget->setEnabled(!clicked);
+
+}
+
+void controllerSetup::setConnected(USBDEVICE* dev)
+{
+ QMutexLocker locker(mutex);
+
+
+ auto tab = tabs.find(dev->path);
+ if (tab != tabs.end())
+ {
+ if (dev->connected)
+ {
+ tab.value()->message->setStyleSheet("QLabel { color : green; }");
+ tab.value()->message->setText("Connected");
+ } else {
+ tab.value()->message->setStyleSheet("QLabel { color : red; }");
+ tab.value()->message->setText("Not Connected");
+ }
+ }
+}
+
+void controllerSetup::on_backupButton_clicked()
+{
+ QString file = QFileDialog::getSaveFileName(this,"Select Backup Filename",".","Backup Files (*.ini)");
+ if (!file.isEmpty()) {
+ auto devIt = devices->find(ui->tabWidget->currentWidget()->objectName());
+ if (devIt==devices->end())
+ {
+ qWarning(logUsbControl) << "on_restoreButton_clicked() Cannot find existing controller, aborting!";
+ }
+ else
+ {
+ emit backup(&devIt.value(), file);
+ }
+ }
+}
+
+void controllerSetup::on_restoreButton_clicked()
+{
+ QMutexLocker locker(mutex);
+
+ QString file = QFileDialog::getOpenFileName(this,"Select Backup Filename",".","Backup Files (*.ini)");
+ if (!file.isEmpty()) {
+ QString path = ui->tabWidget->currentWidget()->objectName();
+
+ auto devIt = devices->find(path);
+ if (devIt==devices->end())
+ {
+ qWarning(logUsbControl) << "on_restoreButton_clicked() Cannot find existing controller, aborting!";
+ return;
+ }
+ auto dev = &devIt.value();
+
+ QSettings* settings = new QSettings(file, QSettings::Format::IniFormat);
+ QString version = settings->value("Version", "").toString();
+ settings->beginGroup("Controller");
+ QString model = settings->value("Model","").toString();
+ delete settings;
+
+ if (model != dev->product) {
+ QMessageBox msgBox;
+ msgBox.setText("Stored controller does not match");
+ msgBox.setInformativeText(QString("Backup: %0 \nCurrent: %1\n\nThis will probably not work!").arg(model,dev->product));
+ msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ msgBox.setDefaultButton(QMessageBox::Cancel);
+ int ret= msgBox.exec();
+ if (ret == QMessageBox::Cancel) {
+ return;
+ }
+ }
+ if (version != QString(WFVIEW_VERSION))
+ {
+ QMessageBox msgBox;
+ msgBox.setText("Version mismatch");
+ msgBox.setInformativeText(QString("Backup was from a different version of wfview\nBackup: %0 \nCurrent: %1\n\nPlease verify compatibility").arg(version, QString(WFVIEW_VERSION)));
+ msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
+ msgBox.setDefaultButton(QMessageBox::Cancel);
+ int ret= msgBox.exec();
+ if (ret == QMessageBox::Cancel) {
+ return;
+ }
+ }
+ emit restore(dev, file);
+ }
+}
-}
\ No newline at end of file
diff --git a/controllersetup.h b/controllersetup.h
index 350fee7..cc33c59 100644
--- a/controllersetup.h
+++ b/controllersetup.h
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -14,14 +15,99 @@
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
#include
#include
+#include
+#include
+#include
#include "usbcontroller.h"
+class controllerScene : public QGraphicsScene
+{
+ Q_OBJECT
+ QGraphicsLineItem* item = Q_NULLPTR;
+
+signals:
+ void showMenu(controllerScene* scene, QPoint p);
+ void buttonAction(bool pressed, QPoint p);
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent* event) {
+
+ if (event->button() == Qt::RightButton)
+ {
+ emit showMenu(this, event->scenePos().toPoint());
+ }
+ else if (event->button() == Qt::LeftButton)
+ {
+ // Simulate a button press
+ emit buttonAction(true,event->scenePos().toPoint());
+ }
+ else
+ {
+ QGraphicsScene::mousePressEvent(event);
+ }
+ }
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) {
+
+ if (event->button() == Qt::LeftButton)
+ {
+ // Simulate a button release
+ emit buttonAction(false,event->scenePos().toPoint());
+ }
+ else
+ {
+ QGraphicsScene::mouseReleaseEvent(event);
+ }
+ }
+};
+
+
+struct tabContent {
+ QWidget* tab;
+ QVBoxLayout* mainLayout;
+ QHBoxLayout* topLayout;
+ QWidget* widget;
+ QVBoxLayout* layout;
+ QCheckBox* disabled;
+ QLabel* message;
+ QGraphicsView* view;
+ QLabel* pageLabel;
+ QSpinBox* page;
+ QHBoxLayout* sensLayout;
+ QLabel* sensLabel;
+ QSlider* sens;
+ QImage* image;
+ QGraphicsItem* bgImage = Q_NULLPTR;
+ controllerScene* scene = Q_NULLPTR;
+ QGridLayout* grid;
+ QLabel* brightLabel;
+ QComboBox* brightness;
+ QLabel* speedLabel;
+ QComboBox* speed;
+ QLabel* orientLabel;
+ QComboBox* orientation;
+ QLabel* colorLabel;
+ QPushButton* color;
+ QLabel* timeoutLabel;
+ QSpinBox* timeout;
+ QLabel* pagesLabel;
+ QSpinBox* pages;
+ QLabel* helpText;
+};
+
+
namespace Ui {
class controllerSetup;
@@ -36,81 +122,102 @@ public:
~controllerSetup();
signals:
- void sendSensitivity(int val);
- void programButton(quint8 but, QString text);
- void programBrightness(quint8 level);
- void programWheelColour(quint8 r, quint8 g, quint8 b);
- void programOverlay(quint8 duration, QString text);
- void programOrientation(quint8 value);
- void programSpeed(quint8 value);
- void programTimeout(quint8 value);
- void updateSettings(quint8 bright, quint8 orient, quint8 speed, quint8 timeout, QColor color);
+ void started();
+ void sendRequest(USBDEVICE* dev, usbFeatureType request, int val=0, QString text="", QImage* img=Q_NULLPTR, QColor* color=Q_NULLPTR);
+ void programDisable(USBDEVICE* dev, bool disable);
+ void programPages(USBDEVICE* dev, int pages);
+ void backup(USBDEVICE* dev, QString path);
+ void restore(USBDEVICE *dev, QString path);
public slots:
- void newDevice(unsigned char devType, QVector* but, QVector* kb, QVector* cmd, QMutex* mut);
- void mousePressed(QPoint p);
+ void init(usbDevMap* dev, QVector* but, QVector* kb, QVector* cmd, QMutex* mut);
+ void newDevice(USBDEVICE* dev);
+ void removeDevice(USBDEVICE* dev);
+ void showMenu(controllerScene *scene,QPoint p);
void onEventIndexChanged(int index);
void offEventIndexChanged(int index);
void knobEventIndexChanged(int index);
- void receiveSensitivity(int val);
- void on_sensitivitySlider_valueChanged(int val);
- void on_qkBrightCombo_currentIndexChanged(int index);
- void on_qkOrientCombo_currentIndexChanged(int index);
- void on_qkSpeedCombo_currentIndexChanged(int index);
- void on_qkColorButton_clicked();
- void on_qkTimeoutSpin_valueChanged(int arg1);
- void setDefaults(quint8 bright, quint8 orient, quint8 speed, quint8 timeout, QColor color);
+ void ledNumberChanged(int index);
+ void sensitivityMoved(USBDEVICE* dev, int val);
+ void brightnessChanged(USBDEVICE* dev, int index);
+ void orientationChanged(USBDEVICE* dev, int index);
+ void speedChanged(USBDEVICE* dev, int index);
+ void colorPicker(USBDEVICE* dev, QPushButton* btn, QColor color);
+ void buttonOnColorClicked();
+ void buttonOffColorClicked();
+ void buttonIconClicked();
+ void latchStateChanged(int state);
+
+ void timeoutChanged(USBDEVICE* dev, int val);
+ void pageChanged(USBDEVICE* dev, int val);
+ void pagesChanged(USBDEVICE* dev, int val);
+ void disableClicked(USBDEVICE* dev, bool clicked, QWidget* widget);
+ void setConnected(USBDEVICE* dev);
+ void hideEvent(QHideEvent *event);
+ void on_tabWidget_currentChanged(int index);
+ void on_backupButton_clicked();
+ void on_restoreButton_clicked();
private:
- usbDeviceType usbDevice = usbNone;
+ usbDeviceType type = usbNone;
Ui::controllerSetup* ui;
- QGraphicsScene* scene;
QGraphicsTextItem* textItem;
- QGraphicsItem* bgImage = Q_NULLPTR;
QLabel* imgLabel;
unsigned char currentDevice = 0;
QVector* buttons;
QVector* knobs;
QVector* commands;
+ usbDevMap* devices;
+
BUTTON* currentButton = Q_NULLPTR;
KNOB* currentKnob = Q_NULLPTR;
- QComboBox* onEvent = Q_NULLPTR;
- QComboBox* offEvent = Q_NULLPTR;
- QComboBox* knobEvent = Q_NULLPTR;
- QComboBox* qkBright = Q_NULLPTR;
- QGraphicsProxyWidget* onEventProxy = Q_NULLPTR;
- QGraphicsProxyWidget* offEventProxy = Q_NULLPTR;
- QGraphicsProxyWidget* knobEventProxy = Q_NULLPTR;
- QGraphicsProxyWidget* qkBrightProxy = Q_NULLPTR;
+
+ // Update Dialog
+ QDialog * updateDialog = Q_NULLPTR;
+ QComboBox* onEvent;
+ QComboBox* offEvent;
+ QComboBox* knobEvent;
+ QLabel* onLabel;
+ QLabel* offLabel;
+ QLabel* knobLabel;
+ QPushButton* buttonOnColor;
+ QPushButton* buttonOffColor;
+ QCheckBox *buttonLatch;
+ QPushButton* buttonIcon;
+ QLabel* iconLabel;
+ QSpinBox* ledNumber;
+
QString deviceName;
QMutex* mutex;
QColor initialColor = Qt::white;
+
+ QLabel* noControllersText;
+
+ int numTabs=0;
+ QMap tabs;
+
+ // Below are used for each tab:
+ /*
+ QList tabs;
+ QList layouts;
+ QList widgets;
+ QList graphicsViews;
+ QList scenes;
+ QList bgImages;
+ QListsensitivitys;
+
+ // Just used for QuickKeys device
+ QListbrightCombos;
+ QListspeedCombos;
+ QListorientCombos;
+ QListcolorButtons;
+ QListtimeoutSpins;
+*/
};
-class controllerScene : public QGraphicsScene
-{
- Q_OBJECT
- QGraphicsLineItem* item = Q_NULLPTR;
-
-signals:
- void mousePressed(QPoint p);
-protected:
- void mousePressEvent(QGraphicsSceneMouseEvent* event) {
-
- if (event->button() == Qt::RightButton)
- {
- emit mousePressed(event->scenePos().toPoint());
- }
- else
- {
- QGraphicsScene::mousePressEvent(event);
- }
- }
-};
-
-#endif
\ No newline at end of file
+#endif
diff --git a/controllersetup.ui b/controllersetup.ui
index 7520cb0..7414551 100644
--- a/controllersetup.ui
+++ b/controllersetup.ui
@@ -6,15 +6,35 @@
0
0
- 442
- 343
+ 788
+ 646
Controller setup
- -
+
-
+
+
+ QTabWidget::North
+
+
+ 1
+
+
+
+ Tab 1
+
+
+
+
+ Tab 2
+
+
+
+
+ -
6
@@ -31,6 +51,20 @@
0
+ -
+
+
+ Backup
+
+
+
+ -
+
+
+ Restore
+
+
+
-
@@ -60,197 +94,6 @@
- -
-
- -
-
-
- true
-
- -
-
- Brightness
-
-
- -
-
- Off
-
-
- -
-
- Low
-
-
- -
-
- Medium
-
-
- -
-
- High
-
-
-
-
- -
-
- -
-
- Speed
-
-
- -
-
- Fastest
-
-
- -
-
- Faster
-
-
- -
-
- Normal
-
-
- -
-
- Slower
-
-
- -
-
- Slowest
-
-
-
-
- -
-
- -
-
- Orientation
-
-
- -
-
- Rotate 0
-
-
- -
-
- Rotate 90
-
-
- -
-
- Rotate 180
-
-
- -
-
- Rotate 270
-
-
-
-
- -
-
-
- Color
-
-
-
- -
-
-
- Timeout
-
-
-
- -
-
-
- 255
-
-
-
-
-
- -
-
-
-
-
-
-
- -
-
- -
-
-
- Sensitivity
-
-
-
- -
-
-
- 1
-
-
- 21
-
-
- Qt::Horizontal
-
-
- true
-
-
-
-
-
- -
-
- -
-
-
- <html><head/><body><p align="center"><span style=" font-weight:700;">Button configuration: </span>Right-click on each button to configure it.</p><p align="center">Top selection is command to send when button is pressed and bottom is (optional) command to send when button is released.</p></body></html>
-
-
- Qt::AlignCenter
-
-
- true
-
-
-
-
-
- -
-
- -
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
diff --git a/packettypes.h b/packettypes.h
index 5607adf..112b6ac 100644
--- a/packettypes.h
+++ b/packettypes.h
@@ -399,6 +399,49 @@ typedef union capabilities_packet {
} *capabilities_packet_t;
+typedef union streamdeck_image_header {
+ struct
+ {
+ quint8 cmd;
+ quint8 suffix;
+ quint8 button;
+ quint8 isLast;
+ quint16 length;
+ quint16 index;
+ };
+ char packet[8];
+} *streamdeck_image_header_t;
+
+typedef union streamdeck_v1_image_header {
+ struct
+ {
+ quint8 cmd;
+ quint8 suffix;
+ quint16 index;
+ quint8 isLast;
+ quint8 button;
+ quint8 unused[10];
+ };
+ char packet[16];
+} *streamdeck_v1_image_header_t;
+
+typedef union streamdeck_lcd_header {
+ struct
+ {
+ quint8 cmd;
+ quint8 suffix;
+ quint16 x;
+ quint16 y;
+ quint16 width;
+ quint16 height;
+ quint8 isLast;
+ quint16 index;
+ quint16 length;
+ quint8 unused;
+ };
+ char packet[16];
+} *streamdeck_lcd_header_t;
+
#pragma pack(pop)
diff --git a/prefs.h b/prefs.h
index 4118cdd..35764e3 100644
--- a/prefs.h
+++ b/prefs.h
@@ -2,9 +2,11 @@
#define PREFS_H
#include
-
+#include
+#include
#include "wfviewtypes.h"
+
struct preferences {
// Program:
QString version;
@@ -15,6 +17,7 @@ struct preferences {
// Interface:
bool useFullScreen;
bool useSystemTheme;
+ int wfEnable;
bool drawPeaks;
underlay_t underlayMode = underlayNone;
int underlayBufferSize = 64;
@@ -46,12 +49,6 @@ struct preferences {
bool niceTS;
bool automaticSidebandSwitching = true;
bool enableUSBControllers;
- int usbSensitivity;
- quint8 usbSpeed;
- quint8 usbTimeout;
- quint8 usbBrightness;
- quint8 usbOrientation;
- QColor usbColor;
// LAN:
bool enableLAN;
diff --git a/resources/resources.qrc b/resources/resources.qrc
index e332d7e..151a3ac 100644
--- a/resources/resources.qrc
+++ b/resources/resources.qrc
@@ -7,5 +7,10 @@
ecoder.png
quickkeys.png
xbox.png
+ streamdeck.png
+ streamdeckmini.png
+ streamdeckxl.png
+ streamdeckpedal.png
+ streamdeckplus.png
diff --git a/resources/streamdeck.png b/resources/streamdeck.png
new file mode 100644
index 0000000..5c45c5f
Binary files /dev/null and b/resources/streamdeck.png differ
diff --git a/resources/streamdeckmini.png b/resources/streamdeckmini.png
new file mode 100644
index 0000000..d514570
Binary files /dev/null and b/resources/streamdeckmini.png differ
diff --git a/resources/streamdeckpedal.png b/resources/streamdeckpedal.png
new file mode 100644
index 0000000..84a0e88
Binary files /dev/null and b/resources/streamdeckpedal.png differ
diff --git a/resources/streamdeckplus.png b/resources/streamdeckplus.png
new file mode 100644
index 0000000..5acbd7a
Binary files /dev/null and b/resources/streamdeckplus.png differ
diff --git a/resources/streamdeckxl.png b/resources/streamdeckxl.png
new file mode 100644
index 0000000..424999a
Binary files /dev/null and b/resources/streamdeckxl.png differ
diff --git a/rigcommander.cpp b/rigcommander.cpp
index 9f0f490..8600b76 100644
--- a/rigcommander.cpp
+++ b/rigcommander.cpp
@@ -872,6 +872,18 @@ void rigCommander::setDataMode(bool dataOn, unsigned char filter)
prepDataAndSend(payload);
}
+void rigCommander::getFrequency(unsigned char vfo)
+{
+ if (rigCaps.hasVFOAB || rigCaps.hasVFOMS)
+ {
+ QByteArray payload("\x25");
+ payload.append(vfo);
+ prepDataAndSend(payload);
+ } else {
+ getFrequency();
+ }
+}
+
void rigCommander::getFrequency()
{
// figure out frequency and then respond with haveFrequency();
@@ -1675,11 +1687,9 @@ void rigCommander::parseCommand()
parseFrequency();
break;
case '\x25':
- if((int)payloadIn[1] == 0)
- {
- emit haveFrequency(parseFrequency(payloadIn, 5));
- }
- break;
+ // Parse both VFOs
+ emit haveFrequency(parseFrequency(payloadIn, 5));
+ break;
case '\x01':
//qInfo(logRig()) << "Have mode data";
this->parseMode();
@@ -1844,6 +1854,11 @@ void rigCommander::parseLevels()
emit haveTPBFOuter(level);
state.set(PBTOUT, level, false);
break;
+ case '\x06':
+ // NR Level
+ emit haveNRLevel(level);
+ state.set(NR, level, false);
+ break;
case '\x09':
// CW Pitch
emit haveCwPitch(level);
@@ -1874,12 +1889,12 @@ void rigCommander::parseLevels()
state.set(COMPLEVEL, level, false);
break;
case '\x12':
- // NB level - ignore for now
+ emit haveNB((bool)level);
state.set(NB, level, false);
break;
case '\x15':
// monitor level
- emit haveMonitorLevel(level);
+ emit haveMonitorGain(level);
state.set(MONITORLEVEL, level, false);
break;
case '\x16':
@@ -2399,9 +2414,9 @@ void rigCommander::setCompLevel(unsigned char compLevel)
prepDataAndSend(payload);
}
-void rigCommander::setMonitorLevel(unsigned char monitorLevel)
+void rigCommander::setMonitorGain(unsigned char monitorLevel)
{
- QByteArray payload("\x14\x0E");
+ QByteArray payload("\x14\x15");
payload.append(bcdEncodeInt(monitorLevel));
prepDataAndSend(payload);
}
@@ -2420,6 +2435,22 @@ void rigCommander::setAntiVoxGain(unsigned char gain)
prepDataAndSend(payload);
}
+void rigCommander::setNBLevel(unsigned char level)
+{
+ if (rigCaps.hasNB) {
+ QByteArray payload(rigCaps.nbCommand);
+ payload.append(bcdEncodeInt(level));
+ prepDataAndSend(payload);
+ }
+}
+
+void rigCommander::setNRLevel(unsigned char level)
+{
+ QByteArray payload("\x14\x06");
+ payload.append(bcdEncodeInt(level));
+ prepDataAndSend(payload);
+}
+
void rigCommander::getRfGain()
{
@@ -2429,8 +2460,13 @@ void rigCommander::getRfGain()
void rigCommander::getAfGain()
{
- QByteArray payload("\x14\x01");
- prepDataAndSend(payload);
+ if (udp == Q_NULLPTR) {
+ QByteArray payload("\x14\x01");
+ prepDataAndSend(payload);
+ }
+ else {
+ emit haveAfGain(localVolume);
+ }
}
void rigCommander::getIFShift()
@@ -2475,7 +2511,7 @@ void rigCommander::getCompLevel()
prepDataAndSend(payload);
}
-void rigCommander::getMonitorLevel()
+void rigCommander::getMonitorGain()
{
QByteArray payload("\x14\x15");
prepDataAndSend(payload);
@@ -2493,6 +2529,19 @@ void rigCommander::getAntiVoxGain()
prepDataAndSend(payload);
}
+void rigCommander::getNBLevel()
+{
+ if (rigCaps.hasNB) {
+ prepDataAndSend(rigCaps.nbCommand);
+ }
+}
+
+void rigCommander::getNRLevel()
+{
+ QByteArray payload("\x14\x06");
+ prepDataAndSend(payload);
+}
+
void rigCommander::getLevels()
{
// Function to grab all levels
@@ -2502,7 +2551,7 @@ void rigCommander::getLevels()
getTxLevel(); // 0x0A
getMicGain(); // 0x0B
getCompLevel(); // 0x0E
-// getMonitorLevel(); // 0x15
+// getMonitorGain(); // 0x15
// getVoxGain(); // 0x16
// getAntiVoxGain(); // 0x17
}
@@ -3026,9 +3075,11 @@ void rigCommander::parseRegister16()
state.set(PREAMP, (quint8)payloadIn.at(2), false);
break;
case '\x22':
+ emit haveNB(payloadIn.at(2) != 0);
state.set(NBFUNC, payloadIn.at(2) != 0, false);
break;
case '\x40':
+ emit haveNR(payloadIn.at(2) != 0);
state.set(NRFUNC, payloadIn.at(2) != 0, false);
break;
case '\x41': // Auto notch
@@ -3055,12 +3106,15 @@ void rigCommander::parseRegister16()
emit haveRptAccessMode(ra);
break;
case '\x44':
+ emit haveComp(payloadIn.at(2) != 0);
state.set(COMPFUNC, payloadIn.at(2) != 0, false);
break;
case '\x45':
+ emit haveMonitor(payloadIn.at(2) != 0);
state.set(MONFUNC, payloadIn.at(2) != 0, false);
break;
case '\x46':
+ emit haveVox(payloadIn.at(2) != 0);
state.set(VOXFUNC, payloadIn.at(2) != 0, false);
break;
case '\x47':
@@ -3104,6 +3158,10 @@ void rigCommander::parseBandStackReg()
freqt freqs = parseFrequency(payloadIn, 7);
//float freq = (float)freqs.MHzDouble;
+ // The Band Stacking command returns the regCode in the position that VFO is expected.
+ // As BSR is always on the active VFO, just set that.
+ freqs.VFO = selVFO_t::activeVFO;
+
bool dataOn = (payloadIn[11] & 0x10) >> 4; // not sure...
char mode = payloadIn[9];
char filter = payloadIn[10];
@@ -4644,6 +4702,7 @@ void rigCommander::parseFrequency()
// payloadIn[01] = ; // . XX KHz
// printHex(payloadIn, false, true);
+
frequencyMhz = 0.0;
if (payloadIn.length() == 7)
{
@@ -4733,40 +4792,25 @@ freqt rigCommander::parseFrequency(QByteArray data, unsigned char lastPosition)
// NOTE: This function was written on the IC-7300, which has no need for 100 MHz and 1 GHz.
// Therefore, this function has to go to position +1 to retrieve those numbers for the IC-9700.
- // TODO: 64-bit value is incorrect, multiplying by wrong numbers.
-
- float freq = 0.0;
-
freqt freqs;
freqs.MHzDouble = 0;
freqs.Hz = 0;
- // MHz:
- freq += 100*(data[lastPosition+1] & 0x0f);
- freq += (1000*((data[lastPosition+1] & 0xf0) >> 4));
-
- freq += data[lastPosition] & 0x0f;
- freq += 10*((data[lastPosition] & 0xf0) >> 4);
-
- freqs.Hz += (data[lastPosition] & 0x0f) * 1E6;
- freqs.Hz += ((data[lastPosition] & 0xf0) >> 4) * 1E6 * 10; // 10 MHz
-
+ // Does Frequency contain 100 MHz/1 GHz data?
if(data.length() >= lastPosition+1)
{
freqs.Hz += (data[lastPosition+1] & 0x0f) * 1E6 * 100; // 100 MHz
freqs.Hz += ((data[lastPosition+1] & 0xf0) >> 4) * 1E6 * 1000; // 1000 MHz
}
+ // Does Frequency contain VFO data? (\x25 command)
+ if (lastPosition-4 >= 0 && (quint8)data[lastPosition-4] < 0x02)
+ {
+ freqs.VFO=(selVFO_t)(quint8)data[lastPosition-4];
+ }
- // Hz:
- freq += ((data[lastPosition-1] & 0xf0) >>4)/10.0 ;
- freq += (data[lastPosition-1] & 0x0f) / 100.0;
-
- freq += ((data[lastPosition-2] & 0xf0) >> 4) / 1000.0;
- freq += (data[lastPosition-2] & 0x0f) / 10000.0;
-
- freq += ((data[lastPosition-3] & 0xf0) >> 4) / 100000.0;
- freq += (data[lastPosition-3] & 0x0f) / 1000000.0;
+ freqs.Hz += (data[lastPosition] & 0x0f) * 1E6;
+ freqs.Hz += ((data[lastPosition] & 0xf0) >> 4) * 1E6 * 10; // 10 MHz
freqs.Hz += (data[lastPosition-1] & 0x0f) * 10E3; // 10 KHz
freqs.Hz += ((data[lastPosition-1] & 0xf0) >> 4) * 100E3; // 100 KHz
@@ -4947,26 +4991,26 @@ void rigCommander::setAntenna(unsigned char ant, bool rx)
prepDataAndSend(payload);
}
-void rigCommander::setNb(bool enabled) {
+void rigCommander::setNB(bool enabled) {
QByteArray payload("\x16\x22");
payload.append((unsigned char)enabled);
prepDataAndSend(payload);
}
-void rigCommander::getNb()
+void rigCommander::getNB()
{
QByteArray payload;
payload.setRawData("\x16\x22", 2);
prepDataAndSend(payload);
}
-void rigCommander::setNr(bool enabled) {
+void rigCommander::setNR(bool enabled) {
QByteArray payload("\x16\x40");
payload.append((unsigned char)enabled);
prepDataAndSend(payload);
}
-void rigCommander::getNr()
+void rigCommander::getNR()
{
QByteArray payload;
payload.setRawData("\x16\x40", 2);
@@ -5342,9 +5386,9 @@ void rigCommander::stateUpdated()
break;
case MONITORLEVEL:
if (i.value()._valid) {
- setMonitorLevel(state.getChar(MONITORLEVEL));
+ setMonitorGain(state.getChar(MONITORLEVEL));
}
- getMonitorLevel();
+ getMonitorGain();
break;
case VOXGAIN:
if (i.value()._valid) {
@@ -5360,15 +5404,15 @@ void rigCommander::stateUpdated()
break;
case NBFUNC:
if (i.value()._valid) {
- setNb(state.getBool(NBFUNC));
+ setNB(state.getBool(NBFUNC));
}
- getNb();
+ getNB();
break;
case NRFUNC:
if (i.value()._valid) {
- setNr(state.getBool(NRFUNC));
+ setNR(state.getBool(NRFUNC));
}
- getNr();
+ getNR();
break;
case ANFFUNC:
if (i.value()._valid) {
diff --git a/rigcommander.h b/rigcommander.h
index bc40264..dda8bec 100644
--- a/rigcommander.h
+++ b/rigcommander.h
@@ -70,6 +70,7 @@ public slots:
// Frequency, Mode, BSR:
void setFrequency(unsigned char vfo, freqt freq);
+ void getFrequency(unsigned char vfo);
void getFrequency();
void selectVFO(vfo_t vfo);
void equalizeVFOsAB();
@@ -103,10 +104,10 @@ public slots:
void setAttenuator(unsigned char att);
void setPreamp(unsigned char pre);
void setAntenna(unsigned char ant, bool rx);
- void setNb(bool enabled);
- void getNb();
- void setNr(bool enabled);
- void getNr();
+ void setNB(bool enabled);
+ void getNB();
+ void setNR(bool enabled);
+ void getNR();
void setAutoNotch(bool enabled);
void getAutoNotch();
void setToneEnabled(bool enabled);
@@ -127,7 +128,8 @@ public slots:
void getManualNotch();
void getPassband();
- void getCwPitch();
+ void getNBLevel();
+ void getNRLevel(); void getCwPitch();
void setCwPitch(unsigned char pitch);
void getDashRatio();
void setDashRatio(unsigned char ratio);
@@ -166,7 +168,7 @@ public slots:
void getTxLevel();
void getMicGain();
void getCompLevel();
- void getMonitorLevel();
+ void getMonitorGain();
void getVoxGain();
void getAntiVoxGain();
void getUSBGain();
@@ -192,13 +194,15 @@ public slots:
void setACCGain(unsigned char gain);
void setACCGain(unsigned char gain, unsigned char ab);
void setCompLevel(unsigned char compLevel);
- void setMonitorLevel(unsigned char monitorLevel);
+ void setMonitorGain(unsigned char monitorLevel);
void setVoxGain(unsigned char gain);
void setAntiVoxGain(unsigned char gain);
void setModInput(rigInput input, bool dataOn);
void setModInputLevel(rigInput input, unsigned char level);
void setAfMute(bool muteOn);
void setDialLock(bool lockOn);
+ void setNBLevel(unsigned char level);
+ void setNRLevel(unsigned char level);
// NB, NR, IP+:
void setIPP(bool enabled);
@@ -330,9 +334,16 @@ signals:
void haveTxPower(unsigned char level);
void haveMicGain(unsigned char level);
void haveCompLevel(unsigned char level);
- void haveMonitorLevel(unsigned char level);
+ void haveMonitorGain(unsigned char level);
void haveVoxGain(unsigned char gain);
void haveAntiVoxGain(unsigned char gain);
+ void haveNBLevel(unsigned char level);
+ void haveNRLevel(unsigned char level);
+ void haveVox(bool en);
+ void haveMonitor(bool en);
+ void haveComp(bool en);
+ void haveNB(bool en);
+ void haveNR(bool en);
// Modulation source and gain:
void haveModInput(rigInput input, bool isData);
diff --git a/rigctld.h b/rigctld.h
index 372b09f..2379401 100644
--- a/rigctld.h
+++ b/rigctld.h
@@ -360,7 +360,7 @@ signals:
void setMicGain(quint8);
void setCompLevel(quint8);
void setTxPower(quint8);
- void setMonitorLevel(quint8);
+ void setMonitorGain(quint8);
void setVoxGain(quint8);
void setAntiVoxGain(quint8);
void setSpectrumRefLevel(int);
diff --git a/rigidentities.h b/rigidentities.h
index 2502e8f..5d5131a 100644
--- a/rigidentities.h
+++ b/rigidentities.h
@@ -137,6 +137,9 @@ struct rigCapabilities {
quint16 spectAmpMax;
quint16 spectLenMax;
+ bool hasNB = false;
+ QByteArray nbCommand;
+
bool hasDD;
bool hasDV;
bool hasATU;
diff --git a/usbcontroller.cpp b/usbcontroller.cpp
index 6f9715c..10477cf 100644
--- a/usbcontroller.cpp
+++ b/usbcontroller.cpp
@@ -1,4 +1,3 @@
-
#if defined(USB_CONTROLLER)
#include "usbcontroller.h"
@@ -12,24 +11,54 @@
usbController::usbController()
{
- // As this is run in it's own thread, don't do anything in the constructor
- qInfo(logUsbControl()) << "Starting usbController()";
+ // As this is run in it's own thread, don't do anything important in the constructor.
+ qInfo(logUsbControl()) << "Starting usbController()";
+ loadCommands();
+ loadButtons();
+ loadKnobs();
+
+ // This is a the "master" list of supported devices. Maybe move to settings at some point?
+ // usbDeviceType, manufacturer, product, usage, usagePage, butons, knobs, leds, maxPayload, iconSize
+ knownDevices.append(USBTYPE(shuttleXpress,0x0b33,0x0020,0x0000,0x0000,15,2,0,5,0));
+ knownDevices.append(USBTYPE(shuttlePro2,0x0b33,0x0030,0x0000,0x0000,15,2,0,5,0));
+ knownDevices.append(USBTYPE(shuttlePro2,0x0b33,0x0011,0x0000,0x0000,15,2,0,5,0)); // Actually a ShuttlePro but hopefully will work?
+ knownDevices.append(USBTYPE(RC28,0x0c26,0x001e,0x0000,0x0000,3,1,3,64,0));
+ knownDevices.append(USBTYPE(eCoderPlus, 0x1fc9, 0x0003,0x0000,0x0000,22,4,0,32,0)); // Actually 20 but some bit0 and bit15 aren't used
+ knownDevices.append(USBTYPE(QuickKeys, 0x28bd, 0x5202,0x0001,0xff0a,10,1,0,32,0));
+ knownDevices.append(USBTYPE(StreamDeckMini, 0x0fd9, 0x0063, 0x0000, 0x0000,6,0,0,1024,80));
+ knownDevices.append(USBTYPE(StreamDeckMiniV2, 0x0fd9, 0x0090, 0x0000, 0x0000,6,0,0,1024,80));
+ knownDevices.append(USBTYPE(StreamDeckOriginal, 0x0fd9, 0x0060, 0x0000, 0x0000,15,0,0,8191,72));
+ knownDevices.append(USBTYPE(StreamDeckOriginalV2, 0x0fd9, 0x006d, 0x0000, 0x0000,15,0,0,1024,72));
+ knownDevices.append(USBTYPE(StreamDeckOriginalMK2, 0x0fd9, 0x0080, 0x0000, 0x0000,15,0,0,1024,72));
+ knownDevices.append(USBTYPE(StreamDeckXL, 0x0fd9, 0x006c, 0x0000, 0x0000,32,0,0,1024,96));
+ knownDevices.append(USBTYPE(StreamDeckXLV2, 0x0fd9, 0x008f, 0x0000, 0x0000,32,0,0,1024,96));
+ knownDevices.append(USBTYPE(StreamDeckPedal, 0x0fd9, 0x0086, 0x0000, 0x0000,3,0,0,1024,0));
+ knownDevices.append(USBTYPE(StreamDeckPlus, 0x0fd9, 0x0084, 0x0000, 0x0000,12,4,0,1024,120));
}
usbController::~usbController()
{
qInfo(logUsbControl) << "Ending usbController()";
+ auto devIt = devices->begin();
+ while (devIt != devices->end())
+ {
+ auto dev = &devIt.value();
+ if (dev->handle) {
+ sendRequest(dev,usbFeatureType::featureOverlay,60,"Goodbye from wfview");
- if (handle) {
- programOverlay(60, "Goodbye from wfview");
-
- if (usbDevice == RC28) {
- ledControl(false, 3);
+ if (dev->type.model == RC28) {
+ sendRequest(dev,usbFeatureType::featureLEDControl,4,"0");
+ }
+ hid_close(dev->handle);
+ dev->handle = NULL;
+ dev->connected = false;
+ dev->detected = false;
+ dev->uiCreated = false;
+ devicesConnected--;
}
-
- hid_close(handle);
+ ++devIt;
}
-
+
hid_exit();
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
if (gamepad != Q_NULLPTR)
@@ -40,26 +69,35 @@ usbController::~usbController()
#endif
}
-void usbController::init(int sens, QMutex* mut)
+void usbController::init(QMutex* mut,usbDevMap* devs ,QVector* buts,QVector* knobs)
{
- this->mutex = mut;
- this->sensitivity = sens;
- emit sendSensitivity(sensitivity);
+ mutex = mut;
+ this->devices = devs;
+ this->buttonList = buts;
+ this->knobList = knobs;
+
+ emit initUI(this->devices, this->buttonList, this->knobList,&this->commands,this->mutex);
+
+ QMutexLocker locker(mutex);
+
+ // We need to make sure that all buttons/knobs have a command assigned, this is a fairly expensive operation
+ // Perform a deep copy of the command to ensure that each controller is using a unique copy of the command.
+
#ifdef HID_API_VERSION_MAJOR
if (HID_API_VERSION == HID_API_MAKE_VERSION(hid_version()->major, hid_version()->minor, hid_version()->patch)) {
qInfo(logUsbControl) << QString("Compile-time version matches runtime version of hidapi: %0.%1.%2")
- .arg(hid_version()->major)
- .arg(hid_version()->minor)
- .arg(hid_version()->patch);
+ .arg(hid_version()->major)
+ .arg(hid_version()->minor)
+ .arg(hid_version()->patch);
}
else {
qInfo(logUsbControl) << QString("Compile-time and runtime versions of hidapi do not match (%0.%1.%2 vs %0.%1.%2)")
- .arg(HID_API_VERSION_MAJOR)
- .arg(HID_API_VERSION_MINOR)
- .arg(HID_API_VERSION_PATCH)
- .arg(hid_version()->major)
- .arg(hid_version()->minor)
- .arg(hid_version()->patch);
+ .arg(HID_API_VERSION_MAJOR)
+ .arg(HID_API_VERSION_MINOR)
+ .arg(HID_API_VERSION_PATCH)
+ .arg(hid_version()->major)
+ .arg(hid_version()->minor)
+ .arg(hid_version()->patch);
}
#endif
hidStatus = hid_init();
@@ -67,7 +105,7 @@ void usbController::init(int sens, QMutex* mut)
qInfo(logUsbControl()) << "Failed to intialize HID Devices";
}
else {
-
+
#ifdef HID_API_VERSION_MAJOR
#if defined(__APPLE__) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 12, 0)
hid_darwin_set_open_exclusive(0);
@@ -79,13 +117,11 @@ void usbController::init(int sens, QMutex* mut)
devs = hid_enumerate(0x0, 0x0);
while (devs) {
qInfo(logUsbControl()) << QString("Device found: (%0:%1) %2 manufacturer: (%3)%4 usage: 0x%5 usage_page 0x%6")
- .arg(devs->vendor_id, 4, 16, QChar('0'))
- .arg(devs->product_id, 4, 16, QChar('0'))
- .arg(QString::fromWCharArray(devs->product_string))
- .arg(QString::fromWCharArray(devs->product_string))
- .arg(QString::fromWCharArray(devs->manufacturer_string))
- .arg(devs->usage, 4, 16, QChar('0'))
- .arg(devs->usage_page, 4, 16, QChar('0'));
+ .arg(devs->vendor_id, 4, 16, QChar('0'))
+ .arg(devs->product_id, 4, 16, QChar('0'))
+ .arg(QString::fromWCharArray(devs->product_string),QString::fromWCharArray(devs->product_string),QString::fromWCharArray(devs->manufacturer_string))
+ .arg(devs->usage, 4, 16, QChar('0'))
+ .arg(devs->usage_page, 4, 16, QChar('0'));
devs = devs->next;
}
hid_free_enumeration(devs);
@@ -96,12 +132,17 @@ void usbController::init(int sens, QMutex* mut)
/* run() is called every 2s and attempts to connect to a supported controller */
void usbController::run()
{
- if (commands == Q_NULLPTR || hidStatus) {
- // We are not ready yet, commands haven't been loaded or hid hasn't been initialized!
- QTimer::singleShot(1000, this, SLOT(run()));
+ QMutexLocker locker(mutex);
+ if (hidStatus) {
+ // We are not ready yet, hid hasn't been initialized!
+ QTimer::singleShot(2000, this, SLOT(run()));
return;
}
+#ifdef USB_HOTPLUG
+ qDebug(logUsbControl()) << "Re-enumerating USB devices due to program startup or hotplug event";
+#endif
+
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
if (gamepad == Q_NULLPTR) {
auto gamepads = QGamepadManager::instance()->connectedGamepads();
@@ -110,14 +151,19 @@ void usbController::run()
// If we got here, we have detected a gamepad of some description!
gamepad = new QGamepad(*gamepads.begin(), this);
qInfo(logUsbControl()) << "Gamepad 0 is " << gamepad->name();
-
+
+ USBDEVICE newDev;
if (gamepad->name() == "Microsoft X-Box 360 pad 0")
{
- usbDevice = xBoxGamepad;
+ newDev.type.model = xBoxGamepad;
}
else {
- usbDevice = unknownGamepad;
+ newDev.type.model = unknownGamepad;
}
+
+ newDev.product = gamepad->name();
+ newDev.path = gamepad->name();
+
connect(gamepad, &QGamepad::buttonDownChanged, this, [this](bool pressed) {
qInfo(logUsbControl()) << "Button Down" << pressed;
this->buttonState("DOWN", pressed);
@@ -198,8 +244,10 @@ void usbController::run()
qInfo(logUsbControl()) << "Button Guide" << pressed;
});
- emit newDevice(usbDevice, buttonList, knobList, commands, mutex); // Let the UI know we have a new controller
- return;
+ newDev.connected=true;
+ devices->insert(newDev.path,newDev);
+
+ emit newDevice(&newDev); // Let the UI know we have a new controller
}
}
else if (!gamepad->isConnected()) {
@@ -210,562 +258,1527 @@ void usbController::run()
struct hid_device_info* devs;
devs = hid_enumerate(0x0, 0x0);
- usbDeviceType tempDev = usbDevice;
- this->path = "";
- // Always only look for the first device and then exit
- // Maybe in the future we could add support for multiple devices?
-
-
+ // Step through all currenly connected devices and add any newly discovered ones to usbDevices.
while (devs) {
- for (int i = 0; i < (int)sizeof knownUsbDevices / (int)sizeof knownUsbDevices[0]; i++) {
- if (devs->vendor_id == knownUsbDevices[i][1] && devs->product_id == knownUsbDevices[i][2]
- && (knownUsbDevices[i][3] == 0x00 || devs->usage == knownUsbDevices[i][3])
- && (knownUsbDevices[i][4] == 0x00 || devs->usage_page == knownUsbDevices[i][4]))
+ auto i = std::find_if(knownDevices.begin(), knownDevices.end(), [devs](const USBTYPE& d)
+ { return ((devs->vendor_id == d.manufacturerId) && (devs->product_id == d.productId)
+ && (d.usage == 0x00 || devs->usage == d.usage)
+ && (d.usagePage == 0x00 || devs->usage_page == d.usagePage));});
+
+ if (i != knownDevices.end())
+ {
+ auto it = devices->find(QString::fromLocal8Bit(devs->path));
+ if (it == devices->end())
{
- this->manufacturer = QString::fromWCharArray(devs->manufacturer_string);
- this->vendorId = devs->vendor_id;
- this->productId = devs->product_id;
- this->product = QString::fromWCharArray(devs->product_string);
- this->serial = QString::fromWCharArray(devs->serial_number);
- this->path = QString::fromLocal8Bit(devs->path);
- this->deviceId = QString("0x%1").arg(this->productId, 4, 16, QChar('0'));
- this->usbDevice = (usbDeviceType)knownUsbDevices[i][0];
- break;
+ USBDEVICE newDev(*i);
+ newDev.manufacturer = QString::fromWCharArray(devs->manufacturer_string);
+ newDev.product = QString::fromWCharArray(devs->product_string);
+ if (newDev.product.isEmpty())
+ {
+ newDev.product = "";
+ }
+ newDev.serial = QString::fromWCharArray(devs->serial_number);
+ newDev.path = QString::fromLocal8Bit(devs->path);
+ newDev.deviceId = QString("0x%1").arg(newDev.type.productId, 4, 16, QChar('0'));
+ newDev.detected = true;
+ qDebug(logUsbControl()) << "New device detected" << newDev.product;
+ devices->insert(newDev.path,newDev);
+ } else if (!it->detected){
+ // This is a known device
+ auto dev = &it.value();
+ dev->type = *i;
+ dev->manufacturer = QString::fromWCharArray(devs->manufacturer_string);
+ dev->product = QString::fromWCharArray(devs->product_string);
+ if (dev->product.isEmpty())
+ {
+ dev->product = "";
+ }
+ dev->serial = QString::fromWCharArray(devs->serial_number);
+ dev->deviceId = QString("0x%1").arg(dev->type.productId, 4, 16, QChar('0'));
+ dev->detected = true;
+ qDebug(logUsbControl()) << "Known device detected" << dev->product;
}
- }
+ }
devs = devs->next;
}
-
+
hid_free_enumeration(devs);
-
- if (!this->path.isEmpty()) {
- qInfo(logUsbControl()) << QString("Attempting to connect to %0").arg(this->product);
- this->handle = hid_open_path(this->path.toLocal8Bit());
- }
-
- if (this->handle)
+
+ for (auto devIt = devices->begin(); devIt != devices->end(); devIt++)
{
- qInfo(logUsbControl()) << QString("Connected to device: %0 from %1 S/N %2").arg(this->product).arg(this->manufacturer).arg(this->serial);
- hid_set_nonblocking(this->handle, 1);
+ auto dev = &devIt.value();
- // Set RC28 LEDs to default state
- if (usbDevice == RC28) {
- getVersion();
- ledControl(false, 0);
- ledControl(false, 1);
- ledControl(false, 2);
- ledControl(true, 3);
- }
- else if (usbDevice == eCoderPlus)
+ // If device is not detected, ignore it.
+ if (dev->detected)
{
- knobValues.clear();
- knobSend.clear();
- knobValues.append({ 0,0,0 });
- knobSend.append({ 0,0,0 });
- }
- else if (usbDevice == QuickKeys) {
- // Subscribe to event streams
-
- QByteArray b(32,0x0);
- b[0] = (qint8)0x02;
- b[1] = (qint8)0xb0;
- b[2] = (qint8)0x04;
+ if (!dev->disabled && !dev->connected)
+ {
+
+ qInfo(logUsbControl()) << QString("Attempting to connect to %0").arg(dev->product);
+ dev->handle = hid_open_path(dev->path.toLocal8Bit());
- b.replace(10, sizeof(this->deviceId), this->deviceId.toLocal8Bit());
- hid_write(this->handle, (const unsigned char*)b.constData(), b.size());
+ if (dev->handle)
+ {
+ qInfo(logUsbControl()) << QString("Connected to device: %0 from %1 S/N %2").arg(dev->product,dev->manufacturer,dev->serial);
+ hid_set_nonblocking(dev->handle, 1);
+ devicesConnected++;
+ dev->connected=true;
- b[0] = (qint8)0x02;
- b[1] = (qint8)0xb4;
- b[2] = (qint8)0x10;
- b.replace(10, sizeof(this->deviceId), this->deviceId.toLocal8Bit());
+ if (dev->type.model == RC28)
+ {
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,1,"0"); });
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,2,"0"); });
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,3,"0"); });
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,4,"1"); });
+ }
+ else if (dev->type.model == QuickKeys)
+ {
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureEventsA); });
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureEventsB); });
+ }
- hid_write(this->handle, (const unsigned char*)b.constData(), b.size());
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureSerial); });
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureFirmware); });
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureOverlay,5,"Hello from wfview"); });
+ }
+ else
+ {
+ // This should only get displayed once if we fail to connect to a device
+ qInfo(logUsbControl()) << QString("Error connecting to %0: %1")
+ .arg(dev->product,QString::fromWCharArray(hid_error(dev->handle)));
+ }
+ }
+
+ if (!dev->uiCreated) // Create ui for all detected devices (even disabled)
+ {
+ for (int i=0;itype.knobs;i++)
+ {
+ dev->knobValues.append(KNOBVALUE());
+ }
+
+
+ // Find our defaults/knobs/buttons for this controller:
+ // First see if we have any stored and add them to the list if not.
+
+ if (dev->type.buttons > 0)
+ {
+ auto bti = std::find_if(buttonList->begin(), buttonList->end(), [dev](const BUTTON& b)
+ { return (b.path == dev->path); });
+ if (bti == buttonList->end())
+ {
+ // List doesn't contain any buttons for this device so add default buttons to the end of buttonList
+ qInfo(logUsbControl()) << "No stored buttons found, loading defaults";
+ for (auto but=defaultButtons.begin();but!=defaultButtons.end();but++)
+ {
+ if (but->dev == dev->type.model)
+ {
+ but->path = dev->path;
+ buttonList->append(BUTTON(*but));
+ }
+ }
+ } else {
+ qInfo(logUsbControl()) << "Found stored buttons for this device, loading.";
+ }
+
+ // We need to set the parent device for all buttons belonging to this device!
+ for (auto but = buttonList->begin(); but != buttonList->end(); but++)
+ {
+ if (but->path == dev->path)
+ {
+ auto bon = std::find_if(commands.begin(), commands.end(), [but](const COMMAND& c) { return (c.text == but->on); });
+ if (bon != commands.end())
+ but->onCommand = &(*bon);
+ else
+ qWarning(logUsbControl()) << "On Command" << but->on << "not found";
+
+ auto boff = std::find_if(commands.begin(), commands.end(), [but](const COMMAND& c) { return (c.text == but->off); });
+ if (boff != commands.end())
+ but->offCommand = &(*boff);
+ else
+ qWarning(logUsbControl()) << "Off Command" << but->off << "not found";
+
+ but->parent = dev;
+ }
+ }
+ }
+
+ if (dev->type.knobs > 0)
+ {
+ auto kbi = std::find_if(knobList->begin(), knobList->end(), [dev](const KNOB& k)
+ { return (k.path == dev->path); });
+ if (kbi == knobList->end())
+ {
+ qInfo(logUsbControl()) << "No stored knobs found, loading defaults";
+ for (auto kb = defaultKnobs.begin();kb != defaultKnobs.end(); kb++)
+ {
+ if (kb->dev == dev->type.model) {
+ kb->path = dev->path;
+ knobList->append(KNOB(*kb));
+ }
+ }
+ } else {
+ qInfo(logUsbControl()) << "Found stored knobs for this device, loading.";
+ }
+
+ for (auto kb = knobList->begin(); kb != knobList->end(); kb++)
+ {
+ if (kb->path == dev->path)
+ {
+ auto k = std::find_if(commands.begin(), commands.end(), [kb](const COMMAND& c) { return (c.text == kb->cmd); });
+ if (k != commands.end())
+ kb->command = &(*k);
+ else
+ qWarning(logUsbControl()) << "Knob Command" << kb->cmd << "not found";
+
+ kb->parent = dev;
+ if (kb->page == 1)
+ dev->knobValues[kb->num].name = kb->cmd;
+ }
+ }
+ }
+ // Let the UI know we have a new controller
+ emit newDevice(dev);
+
+ } else {
+ emit setConnected(dev);
+ }
}
-
-
- // Let the UI know we have a new controller
- emit newDevice(usbDevice, buttonList, knobList, commands, mutex);
- // Run the periodic timer to get data
- QTimer::singleShot(25, this, SLOT(runTimer()));
}
- else
- {
-
- // This should only get displayed once if we fail to connect to a device
- if (usbDevice != usbNone && tempDev != usbDevice)
- {
- qInfo(logUsbControl()) << QString("Error connecting to %0: %1")
- .arg(this->product)
- .arg(QString::fromWCharArray(hid_error(this->handle)));
- }
- // Call me again in 2 seconds to try connecting again
- QTimer::singleShot(2000, this, SLOT(run()));
+
+ if (devicesConnected>0 && dataTimer == Q_NULLPTR) {
+ dataTimer = new QTimer(this);
+ connect(dataTimer, &QTimer::timeout, this, &usbController::runTimer);
+ dataTimer->start(25);
}
-
+
+#ifndef USB_HOTPLUG
+ // Run the periodic timer to check for new devices
+ QTimer::singleShot(2000, this, SLOT(run()));
+#endif
}
-/* runTimer is called every 25ms once a connection to a supported controller is established */
+
+/*
+ * runTimer is called every 25ms once a connection to a supported controller is established
+ * It will then step through each connected controller and request any data
+*/
+
void usbController::runTimer()
{
- int res=1;
-
- if (!this->handle) {
- // Something bad happened!
- QTimer::singleShot(25, this, SLOT(runTimer()));
- res = 0;
- }
-
QMutexLocker locker(mutex);
- while (res > 0) {
- QByteArray data(HIDDATALENGTH, 0x0);
- res = hid_read(this->handle, (unsigned char*)data.data(), HIDDATALENGTH);
- if (res < 0)
- {
- qInfo(logUsbControl()) << "USB Device disconnected" << this->product;
- emit newDevice(0, buttonList, knobList, commands, mutex);
- this->product = "";
- this->manufacturer = "";
- this->serial = "";
- hid_close(this->handle);
- this->handle = NULL;
- QTimer::singleShot(1000, this, SLOT(run()));
- return;
- }
- else if (res == 5 && (usbDevice == shuttleXpress || usbDevice == shuttlePro2))
- {
- data.resize(res);
+ for (auto devIt = devices->begin(); devIt != devices->end(); devIt++)
+ {
+ auto dev = &devIt.value();
- /*qDebug(logUsbControl()) << "usbController Data received " << hex << (unsigned char)data[0] << ":"
- << hex << (unsigned char)data[1] << ":"
- << hex << (unsigned char)data[2] << ":"
- << hex << (unsigned char)data[3] << ":"
- << hex << (unsigned char)data[4];
+ if (dev->disabled || !dev->detected || !dev->connected || !dev->handle) {
+ // This device isn't currently connected.
+ continue;
+ }
+
+ int res=1;
+
+ while (res > 0) {
+ quint32 tempButtons = 0;
+ QByteArray data(HIDDATALENGTH, 0x0);
+ res = hid_read(dev->handle, (unsigned char*)data.data(), HIDDATALENGTH);
+ if (res < 0)
+ {
+ qInfo(logUsbControl()) << "USB Device disconnected" << dev->product;
+ hid_close(dev->handle);
+ dev->handle = NULL;
+ dev->detected = false;
+ dev->connected = false;
+ dev->detected = false;
+ dev->remove = true;
+ dev->uiCreated = false;
+ devicesConnected--;
+ if (devicesConnected == 0) {
+ dataTimer->stop();
+ delete dataTimer;
+ dataTimer = Q_NULLPTR;
+ }
+ emit removeDevice(dev);
+ QTimer::singleShot(250, this, SLOT(run())); // Cleanup
+ break;
+ }
+
+ if (res == 5 && (dev->type.model == shuttleXpress || dev->type.model == shuttlePro2))
+ {
+ tempButtons = ((quint8)data[4] << 8) | ((quint8)data[3] & 0xff);
+ unsigned char tempJogpos = (unsigned char)data[1];
+ unsigned char tempShutpos = (unsigned char)data[0];
+
+ /* Button matrix:
+ 1000000000000000 = button15
+ 0100000000000000 = button14
+ 0010000000000000 = button13
+ 0001000000000000 = button12
+ 0000100000000000 = button11
+ 0000010000000000 = button10
+ 0000001000000000 = button9
+ 0000000100000000 = button8 - xpress0
+ 0000000010000000 = button7 - xpress1
+ 0000000001000000 = button6 - xpress2
+ 0000000000100000 = button5 - xpress3
+ 0000000000010000 = button4 - xpress4
+ 0000000000001000 = button3
+ 0000000000000100 = button2
+ 0000000000000010 = button1
+ 0000000000000001 = button0
*/
- quint32 tempButtons = ((quint8)data[4] << 8) | ((quint8)data[3] & 0xff);
- unsigned char tempJogpos = (unsigned char)data[1];
- unsigned char tempShutpos = (unsigned char)data[0];
- if (tempJogpos == jogpos + 1 || (tempJogpos == 0 && jogpos == 0xff))
- {
- jogCounter++;
- //qDebug(logUsbControl()) << "JOG PLUS" << jogCounter;
+ if (tempJogpos == dev->jogpos + 1 || (tempJogpos == 0 && dev->jogpos == 0xff))
+ {
+ dev->knobValues[0].value++;
+ }
+ else if (tempJogpos != dev->jogpos) {
+ dev->knobValues[0].value--;
+ }
+
+ dev->jogpos = tempJogpos;
+ dev->shutpos = tempShutpos;
}
- else if (tempJogpos != jogpos) {
- jogCounter--;
- //qDebug(logUsbControl()) << "JOG MINUS" << jogCounter;
+ else if ((res > 31) && dev->type.model == RC28)
+ {
+ // This is a response from the Icom RC28
+ if ((unsigned char)data[0] == 0x02) {
+ qInfo(logUsbControl()) << QString("Received RC-28 Firmware Version: %0").arg(QString(data.mid(1,data.indexOf(" ")-1)));
+ }
+ else
+ {
+ tempButtons |= !((quint8)data[5] ^ 0x06) << 0;
+ tempButtons |= !((quint8)data[5] ^ 0x05) << 1;
+ tempButtons |= !((quint8)data[5] ^ 0x03) << 2;
+ if ((unsigned char)data[5] == 0x07)
+ {
+ if ((unsigned char)data[3] == 0x01)
+ {
+ dev->knobValues[0].value = dev->knobValues[0].value + data[1];
+ }
+ else if ((unsigned char)data[3] == 0x02)
+ {
+ dev->knobValues[0].value = dev->knobValues[0].value - data[1];
+ }
+ }
+ }
+ }
+ else if (res > 15 && dev->type.model == eCoderPlus && (quint8)data[0] == 0xff) {
+ tempButtons = ((quint8)data[3] << 16) | ((quint8)data[2] << 8) | ((quint8)data[1] & 0xff);
+ quint32 tempKnobs = ((quint8)data[16] << 24) | ((quint8)data[15] << 16) | ((quint8)data[14] << 8) | ((quint8)data[13] & 0xff);
+
+ for (unsigned char i = 0; i < dev->knobValues.size(); i++)
+ {
+ if (dev->knobs != tempKnobs) {
+ // One of the knobs has moved
+ for (unsigned char i = 0; i < 4; i++) {
+ if ((tempKnobs >> (i * 8) & 0xff) != (dev->knobs >> (i * 8) & 0xff)) {
+ dev->knobValues[i].value = dev->knobValues[i].value + (qint8)((dev->knobs >> (i * 8)) & 0xff);
+ }
+ }
+ dev->knobs = tempKnobs;
+ }
+ }
+ }
+ else if (res > 5 && dev->type.model == QuickKeys && (quint8)data[0] == 0x02) {
+
+ if ((quint8)data[1] == 0xf0) {
+
+ //qInfo(logUsbControl()) << "Received:" << data;
+ tempButtons = (data[3] << 8) | (data[2] & 0xff);
+
+ if (data[7] & 0x01) {
+ dev->knobValues[0].value++;
+ }
+ else if (data[7] & 0x02) {
+ dev->knobValues[0].value--;
+ }
+
+ }
+ else if ((quint8)data[1] == 0xf2 && (quint8)data[2] == 0x01)
+ {
+ // Battery level
+ quint8 battery = (quint8)data[3];
+ qDebug(logUsbControl()) << QString("Battery level %1 %").arg(battery);
+ }
+ }
+ // Is it any model of StreamDeck?
+ else if (res>=dev->type.buttons && dev->type.model != usbNone)
+ {
+ // Main buttons
+ if ((quint8)data[1] == 0x00)
+ {
+ for (int i=dev->type.buttons-dev->type.knobs;i>0;i--) {
+ tempButtons |= ((quint8)data[i+3] & 0x01) << (i-1);
+ }
+ }
+
+ // Knobs and secondary buttons
+ if (dev->type.model == StreamDeckPlus) {
+ if ((quint8)data[1] == 0x03 && (quint8)data[2] == 0x05)
+ {
+ // Knob action!
+ switch ((quint8)data[4])
+ {
+ case 0x00:
+ // Knob button
+ for (int i=dev->type.buttons;i>7;i--)
+ {
+ tempButtons |= ((quint8)data[i-4] & 0x01) << (i-1);
+ }
+ break;
+ case 0x01:
+ // Knob moved
+ for (int i=0;itype.knobs;i++)
+ {
+ dev->knobValues[i].value += (qint8)data[i+5];
+ }
+ break;
+ }
+ }
+ else if ((quint8)data[1] == 0x02 && (quint8)data[2] == 0x0E)
+ {
+ // LCD touch event
+ int x = ((quint8)data[7] << 8) | ((quint8)data[6] & 0xff);
+ int y = ((quint8)data[9] << 8) | ((quint8)data[8] & 0xff);
+ int x2=0;
+ int y2=0;
+ QString tt="";
+ switch ((quint8)data[4])
+ {
+ case 0x01:
+ tt="Short";
+ break;
+ case 0x02:
+ tt="Long";
+ break;
+ case 0x03:
+ tt="Swipe";
+ x2 = ((quint8)data[11] << 8) | ((quint8)data[10] & 0xff);
+ y2 = ((quint8)data[13] << 8) | ((quint8)data[12] & 0xff);
+ break;
+ }
+ qInfo(logUsbControl()) << QString("%0 touch: %1,%2 to %3,%4").arg(tt).arg(x).arg(y).arg(x2).arg(y2);
+ }
+
+ }
}
- /* Button matrix:
- 1000000000000000 = button15
- 0100000000000000 = button14
- 0010000000000000 = button13
- 0001000000000000 = button12
- 0000100000000000 = button11
- 0000010000000000 = button10
- 0000001000000000 = button9
- 0000000100000000 = button8 - xpress0
- 0000000010000000 = button7 - xpress1
- 0000000001000000 = button6 - xpress2
- 0000000000100000 = button5 - xpress3
- 0000000000010000 = button4 - xpress4
- 0000000000001000 = button3
- 0000000000000100 = button2
- 0000000000000010 = button1
- 0000000000000001 = button0
- */
- if (buttons != tempButtons)
+ // Step through all buttons and emit ones that have been pressed.
+ // Only do it if actual data has been received.
+ if (res > 0 && dev->buttons != tempButtons)
{
-
+ qDebug(logUsbControl()) << "Got Buttons:" << QString::number(tempButtons,2);
// Step through all buttons and emit ones that have been pressed.
-
- for (unsigned char i = 0; i < 16; i++)
+ for (unsigned char i = 0; i type.buttons; i++)
{
- auto but = std::find_if(buttonList->begin(), buttonList->end(), [this, i](const BUTTON& b)
- { return (b.dev == this->usbDevice && b.num == i); });
+ auto but = std::find_if(buttonList->begin(), buttonList->end(), [dev, i](const BUTTON& b)
+ { return (b.path == dev->path && b.page == dev->currentPage && b.num == i); });
if (but != buttonList->end()) {
- if ((tempButtons >> i & 1) && !(buttons >> i & 1))
+ if ((!but->isOn) && ((tempButtons >> i & 1) && !(dev->buttons >> i & 1)))
{
- qDebug(logUsbControl()) << "On Button event:" << but->onCommand->text;
- emit button(but->onCommand);
+ qDebug(logUsbControl()) << QString("On Button event for button %0: %1").arg(but->num).arg(but->onCommand->text);
+ if (but->onCommand->command == cmdPageUp)
+ emit changePage(dev, dev->currentPage+1);
+ else if (but->onCommand->command == cmdPageDown)
+ emit changePage(dev, dev->currentPage-1);
+ else if (but->onCommand->command == cmdLCDSpectrum)
+ dev->lcd = cmdLCDSpectrum;
+ else if (but->onCommand->command == cmdLCDWaterfall)
+ dev->lcd = cmdLCDWaterfall;
+ else if (but->onCommand->command == cmdLCDNothing) {
+ dev->lcd = cmdLCDNothing;
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureColor,i,"",Q_NULLPTR, &dev->color); });
+ }else {
+ emit button(but->onCommand);
+ }
+ // Change the button text to reflect the off Button
+ if (but->offCommand->index != 0) {
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureButton,i,but->offCommand->text, but->icon, &but->backgroundOff); });
+ }
+ but->isOn=true;
}
- else if ((buttons >> i & 1) && !(tempButtons >> i & 1))
+ else if ((but->toggle && but->isOn) && ((tempButtons >> i & 1) && !(dev->buttons >> i & 1)))
{
- qDebug(logUsbControl()) << "Off Button event:" << but->offCommand->text;
- emit button(but->offCommand);
+ qDebug(logUsbControl()) << QString("Off Button (toggle) event for button %0: %1").arg(but->num).arg(but->onCommand->text);
+ if (but->offCommand->command == cmdPageUp)
+ emit changePage(dev, dev->currentPage+1);
+ else if (but->offCommand->command == cmdPageDown)
+ emit changePage(dev, dev->currentPage-1);
+ else if (but->offCommand->command == cmdLCDSpectrum)
+ dev->lcd = cmdLCDSpectrum;
+ else if (but->offCommand->command == cmdLCDWaterfall)
+ dev->lcd = cmdLCDWaterfall;
+ else if (but->offCommand->command == cmdLCDNothing) {
+ dev->lcd = cmdLCDNothing;
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureColor,i,"",Q_NULLPTR, &dev->color); });
+ } else {
+ emit button(but->offCommand);
+ }
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureButton,i,but->onCommand->text, but->icon, &but->backgroundOn); });
+ but->isOn=false;
+ }
+ else if ((!but->toggle && but->isOn) && ((dev->buttons >> i & 1) && !(tempButtons >> i & 1)))
+ {
+ if (but->offCommand->command == cmdLCDSpectrum)
+ dev->lcd = cmdLCDSpectrum;
+ else if (but->offCommand->command == cmdLCDWaterfall)
+ dev->lcd = cmdLCDWaterfall;
+ else if (but->offCommand->command == cmdLCDNothing) {
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureColor,i,"",Q_NULLPTR, &dev->color); });
+ dev->lcd = cmdLCDNothing;
+ } else
+ {
+ qDebug(logUsbControl()) << QString("Off Button event for button %0: %1").arg(but->num).arg(but->offCommand->text);
+ emit button(but->offCommand);
+ }
+ // Change the button text to reflect the on Button
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureButton,i,but->onCommand->text, but->icon, &but->backgroundOn); });
+ but->isOn=false;
}
}
}
+ dev->buttons = tempButtons;
}
- buttons = tempButtons;
- jogpos = tempJogpos;
- shutpos = tempShutpos;
-
- }
- else if ((res > 31) && usbDevice == RC28)
- {
- // This is a response from the Icom RC28
- if ((unsigned char)data[0] == 0x02) {
- qInfo(logUsbControl()) << QString("Received RC-28 Firmware Version: %0").arg(QString(data.mid(1,data.indexOf(" ")-1)));
- }
- else
+ // As the knobs can move very fast, only send every 100ms so the rig isn't overwhelmed
+ if (dev->lastusbController.msecsTo(QTime::currentTime()) >= 100 || dev->lastusbController > QTime::currentTime())
{
-
- data.resize(8);
- // Buttons
-
- BUTTON* butptt = Q_NULLPTR;
- BUTTON* butf1 = Q_NULLPTR;
- BUTTON* butf2 = Q_NULLPTR;;
-
- for (BUTTON* but = buttonList->begin(); but != buttonList->end(); but++) {
- if (but->dev == usbDevice) {
-
- if (but->num == 0)
- {
- butptt = but;
- }
- else if (but->num == 1)
- {
- butf1 = but;
- }
- else if (but->num == 2)
- {
- butf2 = but;
- }
+ if (dev->type.model == shuttleXpress || dev->type.model == shuttlePro2)
+ {
+ if (dev->shutpos > 0 && dev->shutpos < 0x08)
+ {
+ dev->shutMult = dev->shutpos;
+ emit doShuttle(true, dev->shutMult);
+ qDebug(logUsbControl()) << "Shuttle PLUS" << dev->shutMult;
+
+ }
+ else if (dev->shutpos > 0xEF) {
+ dev->shutMult = abs(dev->shutpos - 0xff) + 1;
+ emit doShuttle(false, dev->shutMult);
+ qDebug(logUsbControl()) << "Shuttle MINUS" << dev->shutMult;
}
- }
-
- if (butptt != Q_NULLPTR && !((unsigned char)data[5] ^ 0x06) && ((unsigned char)lastData[5] ^ 0x06))
- {
- // TRANSMIT key down only (no other keys down)
- qDebug(logUsbControl()) << "PTT key down";
- qInfo(logUsbControl()) << "On Button event:" << butptt->onCommand->text;
- ledControl(true, 0);
- emit button(butptt->onCommand);
-
- }
- else if (butptt != Q_NULLPTR && ((unsigned char)data[5] ^ 0x06) && !((unsigned char)lastData[5] ^ 0x06))
- {
- // TRANSMIT key up only (no other keys down)
- //emit button(false, 6);
- qDebug(logUsbControl()) << "PTT key up";
- qInfo(logUsbControl()) << "Off Button event:" << butptt->offCommand->text;
- ledControl(false, 0);
- emit button(butptt->offCommand);
}
- if (butf1 != Q_NULLPTR && !((unsigned char)data[5] ^ 0x05) && ((unsigned char)lastData[5] ^ 0x05))
+ for (unsigned char i = 0; i < dev->knobValues.size(); i++)
{
- // F-1 key up only (no other keys down)
- //emit button(true, 5);
- qDebug(logUsbControl()) << "F-1 key down";
- qInfo(logUsbControl()) << "On Button event:" << butf1->onCommand->text;
- ledControl(true, 1);
- emit button(butf1->onCommand);
- }
- else if (butf1 != Q_NULLPTR && ((unsigned char)data[5] ^ 0x05) && !((unsigned char)lastData[5] ^ 0x05))
- {
- // F-1 key down only (no other keys down)
- //emit button(false, 5);
- qDebug(logUsbControl()) << "F-1 key up";
- qInfo(logUsbControl()) << "Off Button event:" << butf1->offCommand->text;
- ledControl(false, 1);
- emit button(butf1->offCommand);
+ auto kb = std::find_if(knobList->begin(), knobList->end(), [dev, i](const KNOB& k)
+ { return (k.command && k.path == dev->path && k.page == dev->currentPage && k.num == i && dev->knobValues[i].value != dev->knobValues[i].previous); });
+
+ if (kb != knobList->end()) {
+ // sendCommand mustn't be deleted so we ensure it stays in-scope by declaring it private (we will only ever send one command).
+ sendCommand = *kb->command;
+ if (sendCommand.command != cmdSetFreq) {
+ int tempVal = dev->knobValues[i].value * dev->sensitivity;
+ tempVal = qMin(qMax(tempVal,0),255);
+ sendCommand.suffix = quint8(tempVal);
+ dev->knobValues[i].value=tempVal/dev->sensitivity; // This ensures that dial can't go outside 0-255
+ dev->knobValues[i].name = kb->command->text;
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureGraph,i,"",Q_NULLPTR,&dev->color); });
+ }
+ else
+ {
+ sendCommand.value = dev->knobValues[i].value/dev->sensitivity;
+ }
+
+ emit button(&sendCommand);
+
+ if (sendCommand.command == cmdSetFreq) {
+ dev->knobValues[i].value = 0;
+ }
+ dev->knobValues[i].previous=dev->knobValues[i].value;
+ }
}
- if (butf2 != Q_NULLPTR && !((unsigned char)data[5] ^ 0x03) && ((unsigned char)lastData[5] ^ 0x03))
- {
- // F-2 key up only (no other keys down)
- //emit button(true, 7);
- qDebug(logUsbControl()) << "F-2 key down";
- qInfo(logUsbControl()) << "On Button event:" << butf2->onCommand->text;
- ledControl(true, 2);
- emit button(butf2->onCommand);
- }
- else if (butf2 != Q_NULLPTR && ((unsigned char)data[5] ^ 0x03) && !((unsigned char)lastData[5] ^ 0x03))
- {
- // F-2 key down only (no other keys down)
- //emit button(false, 7);
- qDebug(logUsbControl()) << "F-2 key up";
- qInfo(logUsbControl()) << "Off Button event:" << butf2->offCommand->text;
- ledControl(false, 2);
- emit button(butf2->offCommand);
- }
-
- if ((unsigned char)data[5] == 0x07)
- {
- if ((unsigned char)data[3] == 0x01)
- {
- jogCounter = jogCounter + data[1];
- }
- else if ((unsigned char)data[3] == 0x02)
- {
- jogCounter = jogCounter - data[1];
- }
- }
-
- lastData = data;
+ dev->lastusbController = QTime::currentTime();
}
+
}
- else if (usbDevice == eCoderPlus && data.length() > 0x0f && (quint8)data[0] == 0xff) {
- /* Button matrix:
- DATA3 DATA2 DATA 1
- 765432107654321076543210
- 001000000000000000000000 = Left CW
- 000100000000000000000000 = Right CW
- 000010000000000000000000 = PTT
- 000001000000000000000000 = Knob 3 Press
- 000000100000000000000000 = Knob 2 Press
- 000000010000000000000000 = Knob 1 Press
- 000000000100000000000000 = button14
- 000000000010000000000000 = button13
- 000000000001000000000000 = button12
- 000000000000100000000000 = button11
- 000000000000010000000000 = button10
- 000000000000001000000000 = button9
- 000000000000000100000000 = button8
- 000000000000000010000000 = button7
- 000000000000000001000000 = button6
- 000000000000000000100000 = button5
- 000000000000000000010000 = button4
- 000000000000000000001000 = button3
- 000000000000000000000100 = button2
- 000000000000000000000010 = button1
- */
- quint32 tempButtons = ((quint8)data[3] << 16) | ((quint8)data[2] << 8) | ((quint8)data[1] & 0xff);
- quint32 tempKnobs = ((quint8)data[16] << 16) | ((quint8)data[15] << 8) | ((quint8)data[14] & 0xff);
-
- if (buttons != tempButtons)
- {
- // Step through all buttons and emit ones that have been pressed.
- for (unsigned char i = 1; i < 23; i++)
- {
- auto but = std::find_if(buttonList->begin(), buttonList->end(), [this, i](const BUTTON& b)
- { return (b.dev == this->usbDevice && b.num == i); });
- if (but != buttonList->end()) {
- if ((tempButtons >> i & 1) && !(buttons >> i & 1))
- {
- qDebug(logUsbControl()) << "On Button event:" << but->onCommand->text;
- emit button(but->onCommand);
- }
- else if ((buttons >> i & 1) && !(tempButtons >> i & 1))
- {
- qDebug(logUsbControl()) << "Off Button event:" << but->offCommand->text;
- emit button(but->offCommand);
- }
- }
- }
- }
- buttons = tempButtons;
-
- if (knobs != tempKnobs) {
- // One of the knobs has moved
- for (unsigned char i = 0; i < 3; i++) {
- if ((tempKnobs >> (i * 8) & 0xff) != (knobs >> (i * 8) & 0xff)) {
- knobValues[i] = knobValues[i] + (qint8)((knobs >> (i * 8)) & 0xff);
- }
- }
- }
- knobs = tempKnobs;
-
- // Tuning knob
- jogCounter = jogCounter + (qint8)data[13];
-
- } else if (usbDevice == QuickKeys && (quint8)data[0] == 0x02) {
-
- if ((quint8)data[1] == 0xf0) {
-
- //qInfo(logUsbControl()) << "Received:" << data;
- quint32 tempButtons = (data[3] << 8) | (data[2] & 0xff);
-
- // Step through all buttons and emit ones that have been pressed.
- for (unsigned char i = 0; i < 10; i++)
- {
- auto but = std::find_if(buttonList->begin(), buttonList->end(), [this, i](const BUTTON& b)
- { return (b.dev == this->usbDevice && b.num == i); });
- if (but != buttonList->end()) {
- if ((tempButtons >> i & 1) && !(buttons >> i & 1))
- {
- qDebug(logUsbControl()) << "On Button event:" << but->onCommand->text;
- emit button(but->onCommand);
- programButton(but->num, but->offCommand->text);
- }
- else if ((buttons >> i & 1) && !(tempButtons >> i & 1))
- {
- qDebug(logUsbControl()) << "Off Button event:" << but->offCommand->text;
- emit button(but->offCommand);
- programButton(but->num, but->onCommand->text);
- }
- }
- }
-
- buttons = tempButtons;
-
- // Tuning knob
- if (data[7] & 0x01) {
- jogCounter++;
- }
- else if (data[7] & 0x02) {
- jogCounter--;
- }
- }
- else if ((quint8)data[1] == 0xf2 && (quint8)data[2] == 0x01)
- {
- // Battery level
- quint8 battery = (quint8)data[3];
- qDebug(logUsbControl()) << QString("Battery level %1 %").arg(battery);
- }
- }
-
- if (lastusbController.msecsTo(QTime::currentTime()) >= 100 || lastusbController > QTime::currentTime())
- {
- if (usbDevice == shuttleXpress || usbDevice == shuttlePro2)
- {
- if (shutpos > 0 && shutpos < 0x08)
- {
- shutMult = shutpos;
- emit doShuttle(true, shutMult);
- qDebug(logUsbControl()) << "Shuttle PLUS" << shutMult;
-
- }
- else if (shutpos > 0xEF) {
- shutMult = abs(shutpos - 0xff) + 1;
- emit doShuttle(false, shutMult);
- qDebug(logUsbControl()) << "Shuttle MINUS" << shutMult;
- }
- }
-
- if (usbDevice == eCoderPlus) {
- for (unsigned char i = 0; i < 3; i++) {
- for (KNOB* kb = knobList->begin(); kb != knobList->end(); kb++) {
- if (kb && kb->dev == usbDevice && kb->num == i + 1 && knobValues[i]) {
- COMMAND cmd;
- cmd.command = kb->command->command;
- if (knobSend[i] + (knobValues[i] * 10) <= 0)
- {
- knobSend[i] = 0;
- }
- else if (knobSend[i] + (knobValues[i] * 10) >= 255)
- {
- knobSend[i] = 255;
- }
- else {
- knobSend[i] = knobSend[i] + (knobValues[i] * 10);
- }
- cmd.suffix = knobSend[i];
- qInfo(logUsbControl()) << "Sending Knob:" << kb->num << "Command:" << cmd.command << " Value:" << cmd.suffix << "Raw value:" << knobValues[i];
- emit button(&cmd);
- knobValues[i] = 0;
- }
- }
- }
- }
-
- if (jogCounter != 0) {
- emit sendJog(jogCounter/sensitivity);
- qDebug(logUsbControl()) << "Change Frequency by" << jogCounter << "hz";
- jogCounter = 0;
- }
-
- lastusbController = QTime::currentTime();
- }
-
}
-
- // Run every 25ms
- QTimer::singleShot(25, this, SLOT(runTimer()));
-}
-
-
-/* Functions below receive various settings from other classes/threads */
-void usbController::receiveCommands(QVector* cmds)
-{
- qDebug(logUsbControl()) << "Receiving commands";
- commands = cmds;
-}
-
-void usbController::receiveButtons(QVector* buts)
-{
- qDebug(logUsbControl()) << "Receiving buttons";
- buttonList = buts;
-}
-
-void usbController::receiveKnobs(QVector* kbs)
-{
- qDebug(logUsbControl()) << "Receiving knobs";
- knobList = kbs;
-}
-
-void usbController::receiveSensitivity(int val)
-{
- sensitivity = val;
}
void usbController::receivePTTStatus(bool on) {
static QColor lastColour = currentColour;
static bool ptt;
- if (on && !ptt) {
- lastColour = currentColour;
- programWheelColour(255, 0, 0);
- }
- else {
- programWheelColour((quint8)lastColour.red(), (quint8)lastColour.green(), (quint8)lastColour.blue());
+
+ for (auto devIt = devices->begin(); devIt != devices->end(); devIt++)
+ {
+ auto dev = &devIt.value();
+ if (dev->lcd != cmdLCDSpectrum && dev->lcd != cmdLCDWaterfall) {
+ if (on && !ptt) {
+ lastColour = currentColour;
+ QColor newColor = QColor(255,0,0);
+ sendRequest(dev,usbFeatureType::featureLEDControl,1,"1");
+ sendRequest(dev,usbFeatureType::featureColor,0, "", Q_NULLPTR, &newColor);
+ }
+ else {
+ sendRequest(dev,usbFeatureType::featureLEDControl,1,"0");
+ sendRequest(dev,usbFeatureType::featureColor,0, "", Q_NULLPTR, &lastColour);
+ }
+ }
}
+
ptt = on;
}
-/*
- * All functions below here are for specific controllers
-*/
-
-/* Functions below are for RC28 */
-
-void usbController::ledControl(bool on, unsigned char num)
+void usbController::sendToLCD(QImage* img)
{
- if (usbDevice == RC28) {
- QByteArray data(3, 0x0);
- data[1] = 0x01;
- static unsigned char ledNum = 0x07;
- if (on)
- ledNum &= ~(1UL << num);
- else
- ledNum |= 1UL << num;
- data[2] = ledNum;
+ for (auto devIt = devices->begin(); devIt != devices->end(); devIt++)
+ {
+ auto dev = &devIt.value();
+ sendRequest(dev,usbFeatureType::featureLCD,0,"",img);
+ }
+}
- int res = hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
- if (res < 0) {
- qDebug(logUsbControl()) << "Unable to write(), Error:" << hid_error(this->handle);
+// We rely on being able to fallthrough case
+#if defined __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#endif
+
+/* This function will handle various commands for multiple models of controller
+ *
+ * Possible features are:
+ * featureInit, featureFirmware, featureSerial, featureButton, featureSensitivity, featureBrightness,
+ * featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featurePages, featureDisable
+*/
+void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, int val, QString text, QImage* img, QColor* color)
+{
+ if (dev == Q_NULLPTR || !dev->connected || dev->disabled || !dev->handle)
+ return;
+
+ QMutexLocker locker(mutex);
+
+ QByteArray data(64, 0x0);
+ QByteArray data2;
+ int res=0;
+ bool sdv1=false;
+
+ // If feature is sensitivity, this is not model dependant and will update the internal sensitivity divider.
+ if (feature == usbFeatureType::featureSensitivity)
+ {
+ dev->sensitivity=val;
+ return;
+ }
+
+ switch (dev->type.model)
+ {
+ case QuickKeys:
+ data.resize(32);
+ data[0] = (qint8)0x02;
+
+ switch (feature) {
+ case usbFeatureType::featureEventsA:
+ data[1] = (qint8)0xb0;
+ data[2] = (qint8)0x04;
+ break;
+ case usbFeatureType::featureEventsB:
+ data[1] = (qint8)0xb4;
+ data[2] = (qint8)0x10;
+ break;
+ case usbFeatureType::featureButton:
+ if (val > 7) {
+ return;
+ }
+ text = text.mid(0, 10); // Make sure text is no more than 10 characters.
+ qDebug(logUsbControl()) << QString("Programming button %0 with %1").arg(val).arg(text);
+ data[1] = (qint8)0xb1;
+ data[3] = val + 1;
+ data[5] = text.length() * 2;
+ data2 = qToLittleEndian(QByteArray::fromRawData(reinterpret_cast(text.constData()), text.size() * 2));
+ data.replace(16, data2.size(), data2);
+ break;
+ case usbFeatureType::featureBrightness:
+ qDebug(logUsbControl()) << QString("Setting brightness to %0").arg(val);
+ data[1] = (qint8)0xb1;
+ data[2] = (qint8)0x0a;
+ data[3] = (qint8)0x01;
+ data[4] = val;
+ dev->brightness = val;
+ break;
+ case usbFeatureType::featureOrientation:
+ data[1] = (qint8)0xb1;
+ data[2] = (qint8)val+1;
+ dev->orientation = val;
+ break;
+ case usbFeatureType::featureSpeed:
+ data[1] = (qint8)0xb4;
+ data[2] = (qint8)0x04;
+ data[3] = (qint8)0x01;
+ data[4] = (qint8)0x01;
+ data[5] = val+1;
+ dev->speed = val;
+ break;
+ case usbFeatureType::featureColor: {
+ data[1] = (qint8)0xb4;
+ data[2] = (qint8)0x01;
+ data[3] = (qint8)0x01;
+ data[6] = (qint8)color->red();
+ data[7] = (qint8)color->green();
+ data[8] = (qint8)color->blue();
+ if (val) {
+ currentColour = *color;
+ dev->color=currentColour;
+ }
+ break;
+ }
+ case usbFeatureType::featureOverlay:
+ data[1] = (qint8)0xb1;
+ data[3] = (qint8)val;
+ for (int i = 0; i < text.length(); i = i + 8)
+ {
+ data[2] = (i == 0) ? 0x05 : 0x06;
+ data2 = qToLittleEndian(QByteArray::fromRawData(reinterpret_cast(text.mid(i, 8).constData()), text.mid(i, 8).size() * 2));
+ data.replace(16, data2.size(), data2);
+ data[5] = text.mid(i, 8).length() * 2;
+ data[6] = (i > 0 && text.mid(i).size() > 8) ? 0x01 : 0x00;
+ hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ }
+ break;
+ case usbFeatureType::featureTimeout:
+ data[1] = (qint8)0xb4;
+ data[2] = (qint8)0x08;
+ data[3] = (qint8)0x01;
+ data[4] = val;
+ dev->timeout = val;
+ break;
+ default:
+ // Command not supported by this device so return.
return;
+ break;
+ }
+ data.replace(10, dev->deviceId.size(), dev->deviceId.toLocal8Bit());
+ hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ break;
+
+ // Below are Stream Deck Generation 1 h/w
+ case StreamDeckOriginal:
+ case StreamDeckMini:
+ case StreamDeckMiniV2:
+ data.resize(17);
+ sdv1=true;
+ // Below are StreamDeck Generation 2 h/w
+ case StreamDeckOriginalMK2:
+ case StreamDeckOriginalV2:
+ case StreamDeckXL:
+ case StreamDeckXLV2:
+ case StreamDeckPlus:
+ case StreamDeckPedal:
+ data.resize(32);
+ switch (feature)
+ {
+ case usbFeatureType::featureFirmware:
+ if (sdv1) {
+ data[0] = 0x04;
+ } else {
+ data[0] = 0x05;
+ }
+ hid_get_feature_report(dev->handle,(unsigned char*)data.data(),(size_t)data.size());
+ qInfo(logUsbControl()) << QString("%0: Firmware = %1").arg(dev->product,QString::fromLatin1(data.mid(2,12)));
+ break;
+ case usbFeatureType::featureSerial:
+ if (sdv1) {
+ data[0] = 0x03;
+ } else {
+ data[0] = 0x06;
+ }
+ hid_get_feature_report(dev->handle,(unsigned char*)data.data(),(size_t)data.size());
+ qInfo(logUsbControl()) << QString("%0: Serial Number = %1").arg(dev->product,QString::fromLatin1(data.mid(5,8)));
+ break;
+ case usbFeatureType::featureReset:
+ if (sdv1) {
+ data[0] = (qint8)0x0b;
+ data[1] = (qint8)0x63;
+ } else {
+ data[0] = (qint8)0x03;
+ data[1] = (qint8)0x02;
+ }
+ hid_send_feature_report(dev->handle, (const unsigned char*)data.constData(), data.size());
+ break;
+ case usbFeatureType::featureResetKeys:
+ data.resize(dev->type.maxPayload);
+ memset(data.data(),0x0,data.size());
+ data[0] = (qint8)0x02;
+ res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ break;
+ case usbFeatureType::featureBrightness:
+ if (sdv1) {
+ data[0] = (qint8)0x05;
+ data[1] = (qint8)0x55;
+ data[2] = (qint8)0xaa;
+ data[3] = (qint8)0xd1;
+ data[4] = (qint8)0x01;
+ data[5] = val*25;
+ } else {
+ data[0] = (qint8)0x03;
+ data[1] = (qint8)0x08;
+ data[2] = val*33; // Stream Deck brightness is in %
+ }
+ res = hid_send_feature_report(dev->handle, (const unsigned char*)data.constData(), data.size());
+ dev->brightness = val;
+ break;
+ case usbFeatureType::featureSensitivity:
+ dev->sensitivity=val;
+ break;
+ case usbFeatureType::featureGraph:
+ {
+ if (dev->type.model == usbDeviceType::StreamDeckPlus && val < dev->type.knobs)
+ {
+ QImage image(200,25, QImage::Format_RGB888);
+ if (text != "**REMOVE**") { // && dev->knobValues[val].lastChanged + 1900 < QDateTime::currentMSecsSinceEpoch()) {
+ image.fill(Qt::black);
+ QPainter paint(&image);
+ int x=qMin(190,(dev->knobValues[val].value * dev->sensitivity) * 190 / 255);
+ paint.fillRect(5,5,x,20, Qt::darkGreen);
+ paint.setFont(QFont("times",10));
+ paint.setPen(Qt::white);
+ int perc=qMin(100,(dev->knobValues[val].value * dev->sensitivity) * 100 / 255);
+ paint.drawText(5,5,190,20, Qt::AlignCenter | Qt::AlignVCenter, QString("%0 %1%").arg(dev->knobValues[val].name).arg(perc));
+ }
+ else if (dev->knobValues[val].lastChanged + 1900 < QDateTime::currentMSecsSinceEpoch())
+ {
+ image.fill(*color);
+ } else {
+ // Value has changed.
+ break;
+ }
+ data2.clear();
+ QBuffer buffer(&data2);
+ image.save(&buffer, "JPG");
+
+ quint32 rem = data2.size();
+ quint16 index = 0;
+
+ streamdeck_lcd_header h;
+ memset(h.packet, 0x0, sizeof(h)); // We can't be sure it is initialized with 0x00!
+ h.cmd = 0x02;
+ h.suffix = 0x0c;
+ h.x=val*200;
+ h.y=75;
+ h.width=200;
+ h.height=25;
+
+ while (rem > 0)
+ {
+ quint16 length = qMin(quint16(rem),quint16(dev->type.maxPayload-sizeof(h)));
+ data.clear();
+ h.isLast = (quint8)(rem <= dev->type.maxPayload-sizeof(h) ? 1 : 0); // isLast ? 1 : 0,3
+ h.length = length;
+ h.index = index;
+ rem -= length;
+ data.append(QByteArray::fromRawData((const char*)h.packet,sizeof(h)));
+ data.append(data2.mid(0,length));
+ data.resize(dev->type.maxPayload);
+ memset(data.data()+length+sizeof(h),0x0,data.size()-(length+sizeof(h)));
+ res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ //qInfo(logUsbControl()) << "Sending" << (((quint8)data[7] << 8) | ((quint8)data[6] & 0xff)) << "total=" << data.size() << "payload=" << (((quint8)data[5] << 8) | ((quint8)data[4] & 0xff)) << "last" << (quint8)data[3];
+ data2.remove(0,length);
+ index++;
+ }
+ if (text != "**REMOVE**") {
+ dev->knobValues[val].lastChanged = QDateTime::currentMSecsSinceEpoch();
+ if (dev->lcd != cmdLCDSpectrum && dev->lcd != cmdLCDWaterfall)
+ QTimer::singleShot(2000, this, [=]() { sendRequest(dev,usbFeatureType::featureGraph,val,"**REMOVE**",Q_NULLPTR,&dev->color); });
+ }
+
+ }
+ break;
+ }
+ case usbFeatureType::featureColor:
+ dev->color = *color;
+ case usbFeatureType::featureOverlay:
+ {
+ if (dev->type.model == usbDeviceType::StreamDeckPlus)
+ {
+ QImage image(800,100, QImage::Format_RGB888);
+ QPainter paint(&image);
+ if (val) {
+ paint.setFont(QFont("times",16));
+ paint.fillRect(image.rect(), dev->color);
+ paint.drawText(image.rect(),Qt::AlignCenter | Qt::AlignVCenter, text);
+ if (val)
+ QTimer::singleShot(val*1000, this, [=]() { sendRequest(dev,usbFeatureType::featureOverlay); });
+ } else {
+ paint.fillRect(image.rect(), dev->color);
+ }
+ QBuffer buffer(&data2);
+ image.save(&buffer, "JPG");
+ }
+ }
+ case usbFeatureType::featureLCD:
+ {
+ if (dev->type.model == usbDeviceType::StreamDeckPlus)
+ {
+ if (img != Q_NULLPTR)
+ {
+ QImage image = img->scaled(800,100,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
+ QPainter paint(&image);
+
+ for (int i=0;itype.knobs;i++) {
+ if (QDateTime::currentMSecsSinceEpoch() < dev->knobValues[i].lastChanged + 2000)
+ {
+ paint.fillRect(200*i,75,200,25, Qt::black);
+ int x=qMin(190,(dev->knobValues[i].value * dev->sensitivity) * 190 / 255);
+ paint.fillRect((200*i)+5,80,x,20, Qt::darkGreen);
+ paint.setFont(QFont("times",10));
+ paint.setPen(Qt::white);
+ int perc=qMin(100,(dev->knobValues[i].value * dev->sensitivity) * 100 / 255);
+ paint.drawText((200*i)+5,80,190,20, Qt::AlignCenter | Qt::AlignVCenter, QString("%0 %1%").arg(dev->knobValues[i].name).arg(perc));
+ }
+ }
+ data2.clear();
+ QBuffer buffer(&data2);
+ image.save(&buffer, "JPG");
+ }
+ quint32 rem = data2.size();
+ quint16 index = 0;
+
+ streamdeck_lcd_header h;
+ memset(h.packet, 0x0, sizeof(h)); // We can't be sure it is initialized with 0x00!
+ h.cmd = 0x02;
+ h.suffix = 0x0c;
+ h.x=0;
+ h.y=0;
+ h.width=800;
+ h.height=100;
+
+ while (rem > 0)
+ {
+ quint16 length = qMin(quint16(rem),quint16(dev->type.maxPayload-sizeof(h)));
+ data.clear();
+ h.isLast = (quint8)(rem <= dev->type.maxPayload-sizeof(h) ? 1 : 0); // isLast ? 1 : 0,3
+ h.length = length;
+ h.index = index;
+ rem -= length;
+ data.append(QByteArray::fromRawData((const char*)h.packet,sizeof(h)));
+ data.append(data2.mid(0,length));
+ data.resize(dev->type.maxPayload);
+ memset(data.data()+length+sizeof(h),0x0,data.size()-(length+sizeof(h)));
+ res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ //qInfo(logUsbControl()) << "Sending" << (((quint8)data[7] << 8) | ((quint8)data[6] & 0xff)) << "total=" << data.size() << "payload=" << (((quint8)data[5] << 8) | ((quint8)data[4] & 0xff)) << "last" << (quint8)data[3];
+ data2.remove(0,length);
+ index++;
+ }
+ }
+ break;
+ }
+ case usbFeatureType::featureButton: {
+ // StreamDeckPedal is the only model without oled buttons
+ // Plus has 12 buttons but only 8 oled
+ if (dev->type.model != usbDeviceType::StreamDeckPedal &&
+ ((dev->type.model == usbDeviceType::StreamDeckPlus && val < 8) ||
+ (val < dev->type.buttons)))
+ {
+ if (val < 8) {
+ QImage butImage(dev->type.iconSize,dev->type.iconSize, QImage::Format_RGB888);
+ if (color != Q_NULLPTR)
+ butImage.fill(*color);
+ else
+ butImage.fill(dev->color);
+
+ QPainter butPaint(&butImage);
+
+ if ( img == Q_NULLPTR) {
+ butPaint.setFont(QFont("times",16));
+ butPaint.drawText(butImage.rect(),Qt::AlignCenter | Qt::AlignVCenter, text);
+ } else {
+ butPaint.setCompositionMode(QPainter::CompositionMode_SourceAtop);
+ butPaint.drawImage(0, 0, *img);
+ }
+
+ QBuffer butBuffer(&data2);
+
+ if (sdv1)
+ {
+ butImage.save(&butBuffer, "BMP");
+ quint32 rem = data2.size();
+ quint16 index = 0;
+ streamdeck_v1_image_header h1;
+ memset(h1.packet, 0x0, sizeof(h1)); // We can't be sure it is initialized with 0x00!
+ h1.cmd = 0x02;
+ h1.suffix = 0x01;
+ h1.button = val;
+ while (rem > 0)
+ {
+ quint16 length = qMin(quint16(rem),quint16(dev->type.maxPayload-sizeof(h1)));
+ data.clear();
+ h1.isLast = (quint8)(rem <= dev->type.maxPayload-sizeof(h1) ? 1 : 0); // isLast ? 1 : 0,3
+ h1.index = index;
+ data.append(QByteArray::fromRawData((const char*)h1.packet,sizeof(h1)));
+ rem -= length;
+ data.append(data2.mid(0,length));
+ data.resize(dev->type.maxPayload);
+ memset(data.data()+length+sizeof(h1),0x0,data.size()-(length+sizeof(h1)));
+ res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ //qInfo(logUsbControl()) << "Sending" << (((quint8)data[7] << 8) | ((quint8)data[6] & 0xff)) << "total=" << data.size() << "payload=" << (((quint8)data[5] << 8) | ((quint8)data[4] & 0xff)) << "last" << (quint8)data[3];
+ data2.remove(0,length);
+ index++;
+ }
+ }
+ else
+ {
+ butImage.save(&butBuffer, "JPG");
+ quint32 rem = data2.size();
+ quint16 index = 0;
+ streamdeck_image_header h;
+ memset(h.packet, 0x0, sizeof(h)); // We can't be sure it is initialized with 0x00!
+ h.cmd = 0x02;
+ h.suffix = 0x07;
+ h.button = val;
+ while (rem > 0)
+ {
+ quint16 length = qMin(quint16(rem),quint16(dev->type.maxPayload-sizeof(h)));
+ data.clear();
+ h.isLast = (quint8)(rem <= dev->type.maxPayload-sizeof(h) ? 1 : 0); // isLast ? 1 : 0,3
+ h.length = length;
+ h.index = index;
+ data.append(QByteArray::fromRawData((const char*)h.packet,sizeof(h)));
+ rem -= length;
+ data.append(data2.mid(0,length));
+ data.resize(dev->type.maxPayload);
+ memset(data.data()+length+sizeof(h),0x0,data.size()-(length+sizeof(h)));
+ res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ //qInfo(logUsbControl()) << "Sending" << (((quint8)data[7] << 8) | ((quint8)data[6] & 0xff)) << "total=" << data.size() << "payload=" << (((quint8)data[5] << 8) | ((quint8)data[4] & 0xff)) << "last" << (quint8)data[3];
+ data2.remove(0,length);
+ index++;
+ }
+ }
+ }
+ }
+ }
+ default:
+ break;
+ }
+ break;
+ case RC28:
+ data.resize(3);
+ memset(data.data(),0x0,data.size());
+ switch (feature)
+ {
+ case usbFeatureType::featureFirmware:
+ data[0] = 63;
+ data[1] = 0x02;
+ break;
+ case usbFeatureType::featureLEDControl:
+ data[1] = 0x01;
+ if (text == "0")
+ dev->ledStatus |= 1UL << (val-1);
+ else
+ dev->ledStatus &= ~(1UL << (val-1));
+ data[2] = dev->ledStatus;
+ break;
+ default:
+ return; // No command
+ break;
+ }
+ res = hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
+ break;
+ default:
+ break;
+ }
+
+ if (res == -1)
+ qInfo(logUsbControl()) << "Command" << feature << "returned" << res;
+}
+
+// Don't allow fallthrough elsewhere in the file.
+#if defined __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+void usbController::programDisable(USBDEVICE* dev, bool disabled)
+{
+ dev->disabled = disabled;
+
+ if (disabled)
+ {
+ // Disconnect the device:
+ if (dev->handle) {
+ qInfo(logUsbControl()) << "Disconnecting device:" << dev->product;
+ sendRequest(dev,usbFeatureType::featureOverlay,60,"Goodbye from wfview");
+
+ if (dev->type.model == RC28) {
+ sendRequest(dev,usbFeatureType::featureLEDControl,4,"1");
+ }
+
+ QMutexLocker locker(mutex);
+
+ hid_close(dev->handle);
+ dev->connected=false;
+ dev->handle=NULL;
+ }
+ } else {
+ qInfo(logUsbControl()) << "Enabling device:" << dev->product;
+ }
+ QTimer::singleShot(250, this, SLOT(run())); // Call run disconnect/reconnect after 250ms
+}
+
+
+/* Button/Knob/Command defaults */
+
+void usbController::loadButtons()
+{
+ defaultButtons.clear();
+
+ // ShuttleXpress
+ defaultButtons.append(BUTTON(shuttleXpress, 4, QRect(25, 199, 89, 169), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttleXpress, 5, QRect(101, 72, 83, 88), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttleXpress, 6, QRect(238, 26, 134, 69), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttleXpress, 7, QRect(452, 72, 77, 86), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttleXpress, 8, QRect(504, 199, 89, 169), Qt::red, &commands[0], &commands[0]));
+
+ // ShuttlePro2
+ defaultButtons.append(BUTTON(shuttlePro2, 0, QRect(60, 66, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 1, QRect(114, 50, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 2, QRect(169, 47, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 3, QRect(225, 59, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 4, QRect(41, 132, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 5, QRect(91, 105, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 6, QRect(144, 93, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 7, QRect(204, 99, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 8, QRect(253, 124, 40, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 9, QRect(50, 270, 70, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 10, QRect(210, 270, 70, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 11, QRect(50, 335, 70, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 12, QRect(210, 335, 70, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 13, QRect(30, 195, 25, 80), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(shuttlePro2, 14, QRect(280, 195, 25, 80), Qt::red, &commands[0], &commands[0]));
+
+ // RC28
+ defaultButtons.append(BUTTON(RC28, 0, QRect(52, 445, 238, 64), Qt::red, &commands[1], &commands[2],false,1)); // PTT On/OFF
+ defaultButtons.append(BUTTON(RC28, 1, QRect(52, 373, 98, 46), Qt::red, &commands[0], &commands[0],false,2));
+ defaultButtons.append(BUTTON(RC28, 2, QRect(193, 373, 98, 46), Qt::red, &commands[0], &commands[0],false,3));
+
+ // Xbox Gamepad
+ defaultButtons.append(BUTTON(xBoxGamepad, "UP", QRect(256, 229, 50, 50), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "DOWN", QRect(256, 316, 50, 50), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "LEFT", QRect(203, 273, 50, 50), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "RIGHT", QRect(303, 273, 50, 50), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "SELECT", QRect(302, 160, 40, 40), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "START", QRect(412, 163, 40, 40), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "Y", QRect(534, 104, 53, 53), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "X", QRect(485, 152, 53, 53), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "B", QRect(590, 152, 53, 53), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "A", QRect(534, 202, 53, 53), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "L1", QRect(123, 40, 70, 45), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "R1", QRect(562, 40, 70, 45), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "LEFTX", QRect(143, 119, 83, 35), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "LEFTY", QRect(162, 132, 50, 57), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "RIGHTX", QRect(430, 298, 83, 35), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(xBoxGamepad, "RIGHTY", QRect(453, 233, 50, 57), Qt::red, &commands[0], &commands[0]));
+
+ // eCoder
+ defaultButtons.append(BUTTON(eCoderPlus, 1, QRect(87, 190, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 2, QRect(168, 190, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 3, QRect(249, 190, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 4, QRect(329, 190, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 5, QRect(410, 190, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 6, QRect(87, 270, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 7, QRect(168, 270, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 8, QRect(249, 270, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 9, QRect(329, 270, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 10, QRect(410, 270, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 11, QRect(87, 351, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 12, QRect(410, 351, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 13, QRect(87, 512, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 14, QRect(410, 512, 55, 55), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 16, QRect(128, 104, 45, 47), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 17, QRect(256, 104, 45, 47), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 18, QRect(380, 104, 45, 47), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 19, QRect(124, 2, 55, 30), Qt::red, &commands[1], &commands[2]));
+ defaultButtons.append(BUTTON(eCoderPlus, 20, QRect(290, 2, 55, 30), Qt::red, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(eCoderPlus, 21, QRect(404, 2, 55, 30), Qt::red, &commands[0], &commands[0]));
+
+ // QuickKeys
+ defaultButtons.append(BUTTON(QuickKeys, 0, QRect(77, 204, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 1, QRect(77, 276, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 2, QRect(77, 348, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 3, QRect(77, 422, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 4, QRect(230, 204, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 5, QRect(230, 276, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 6, QRect(230, 348, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 7, QRect(230, 422, 39, 63), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 8, QRect(143, 515, 55, 40), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(QuickKeys, 9, QRect(139, 68, 65, 65), Qt::white, &commands[0], &commands[0]));
+
+ // StreamDeckOriginal
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 0, QRect(65, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 1, QRect(165, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 2, QRect(263, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 3, QRect(364, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 4, QRect(462, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 5, QRect(65, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 6, QRect(165, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 7, QRect(263, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 8, QRect(364, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 9, QRect(462, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 10, QRect(332, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 11, QRect(462, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 12, QRect(74, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 13, QRect(204, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginal, 14, QRect(332, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+
+ // StreamDeckOriginalMK2
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 0, QRect(65, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 1, QRect(165, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 2, QRect(263, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 3, QRect(364, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 4, QRect(462, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 5, QRect(65, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 6, QRect(165, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 7, QRect(263, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 8, QRect(364, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 9, QRect(462, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 10, QRect(332, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 11, QRect(462, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 12, QRect(74, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 13, QRect(204, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalMK2, 14, QRect(332, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+
+ // StreamDeckOriginalV2
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 0, QRect(65, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 1, QRect(165, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 2, QRect(263, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 3, QRect(364, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 4, QRect(462, 91, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 5, QRect(65, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 6, QRect(165, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 7, QRect(263, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 8, QRect(364, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 9, QRect(462, 190, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 10, QRect(332, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 11, QRect(462, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 12, QRect(74, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 13, QRect(204, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckOriginalV2, 14, QRect(332, 291, 75, 75), Qt::white, &commands[0], &commands[0],true));
+
+ // StreamDeckMini
+ defaultButtons.append(BUTTON(StreamDeckMini, 0, QRect(113, 86, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMini, 1, QRect(252, 86, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMini, 2, QRect(388, 86, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMini, 3, QRect(113, 204, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMini, 4, QRect(252, 204, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMini, 5, QRect(388, 204, 100, 80), Qt::white, &commands[0], &commands[0],true));
+
+ // StreamDeckMiniV2
+ defaultButtons.append(BUTTON(StreamDeckMiniV2, 0, QRect(113, 86, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMiniV2, 1, QRect(252, 86, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMiniV2, 2, QRect(388, 86, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMiniV2, 3, QRect(113, 204, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMiniV2, 4, QRect(252, 204, 100, 80), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckMiniV2, 5, QRect(388, 204, 100, 80), Qt::white, &commands[0], &commands[0],true));
+
+ // StreamDeckXL
+ defaultButtons.append(BUTTON(StreamDeckXL, 0, QRect(80, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 1, QRect(168, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 2, QRect(258, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 3, QRect(349, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 4, QRect(438, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 5, QRect(529, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 6, QRect(618, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 7, QRect(711, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 8, QRect(80, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 9, QRect(168, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 10, QRect(258, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 11, QRect(349, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 12, QRect(438, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 13, QRect(529, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 14, QRect(618, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 15, QRect(711, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 16, QRect(80, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 17, QRect(168, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 18, QRect(258, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 19, QRect(349, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 20, QRect(438, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 21, QRect(529, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 22, QRect(618, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 23, QRect(711, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 24, QRect(80, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 25, QRect(168, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 26, QRect(258, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 27, QRect(349, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 28, QRect(438, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 29, QRect(529, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 30, QRect(618, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXL, 31, QRect(711, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+
+ // StreamDeckXLV2
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 0, QRect(80, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 1, QRect(168, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 2, QRect(258, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 3, QRect(349, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 4, QRect(438, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 5, QRect(529, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 6, QRect(618, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 7, QRect(711, 106, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 8, QRect(80, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 9, QRect(168, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 10, QRect(258, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 11, QRect(349, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 12, QRect(438, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 13, QRect(529, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 14, QRect(618, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 15, QRect(711, 195, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 16, QRect(80, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 17, QRect(168, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 18, QRect(258, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 19, QRect(349, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 20, QRect(438, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 21, QRect(529, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 22, QRect(618, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 23, QRect(711, 287, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 24, QRect(80, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 25, QRect(168, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 26, QRect(258, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 27, QRect(349, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 28, QRect(438, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 29, QRect(529, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 30, QRect(618, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckXLV2, 31, QRect(711, 376, 61, 61), Qt::white, &commands[0], &commands[0],true));
+
+ // StreamDeckPedal
+ defaultButtons.append(BUTTON(StreamDeckPedal, 0, QRect(7, 47, 115, 347), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(StreamDeckPedal, 1, QRect(155, 47, 291, 353), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(StreamDeckPedal, 2, QRect(475, 47, 115, 347), Qt::white, &commands[0], &commands[0]));
+
+ // StreamDeckPlus
+ defaultButtons.append(BUTTON(StreamDeckPlus, 0, QRect(75, 45, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 1, QRect(202, 45, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 2, QRect(330, 45, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 3, QRect(458, 45, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 4, QRect(75, 128, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 5, QRect(202, 128, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 6, QRect(330, 128, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 7, QRect(458, 128, 63, 63), Qt::white, &commands[0], &commands[0],true));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 8, QRect(74, 358, 64, 52), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 9, QRect(204, 358, 64, 52), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 10, QRect(332, 358, 64, 52), Qt::white, &commands[0], &commands[0]));
+ defaultButtons.append(BUTTON(StreamDeckPlus, 11, QRect(462, 358, 64, 52), Qt::white, &commands[0], &commands[0]));
+}
+
+void usbController::loadKnobs()
+{
+ defaultKnobs.clear();
+ defaultKnobs.append(KNOB(shuttleXpress, 0, QRect(205, 189, 203, 203), Qt::green, &commands[3]));
+ defaultKnobs.append(KNOB(shuttlePro2, 0, QRect(104, 164, 124, 119), Qt::green, &commands[3]));
+ defaultKnobs.append(KNOB(RC28, 0, QRect(78, 128, 184, 168), Qt::green, &commands[3]));
+ defaultKnobs.append(KNOB(QuickKeys, 0, QRect(114, 130, 121, 43), Qt::green, &commands[3]));
+
+ // eCoder
+ defaultKnobs.append(KNOB(eCoderPlus, 0, QRect(173, 360, 205, 209), Qt::green, &commands[3]));
+ defaultKnobs.append(KNOB(eCoderPlus, 1, QRect(120, 153, 72, 27), Qt::green, &commands[0]));
+ defaultKnobs.append(KNOB(eCoderPlus, 2, QRect(242, 153, 72, 27), Qt::green, &commands[0]));
+ defaultKnobs.append(KNOB(eCoderPlus, 3, QRect(362, 153, 72, 27), Qt::green, &commands[0]));
+
+ // StreamDeckPlus
+ defaultKnobs.append(KNOB(StreamDeckPlus, 0, QRect(74, 413, 64, 28), Qt::green, &commands[3]));
+ defaultKnobs.append(KNOB(StreamDeckPlus, 1, QRect(204, 413, 64, 28), Qt::green, &commands[0]));
+ defaultKnobs.append(KNOB(StreamDeckPlus, 2, QRect(332, 413, 64, 28), Qt::green, &commands[0]));
+ defaultKnobs.append(KNOB(StreamDeckPlus, 3, QRect(462, 413, 64, 28), Qt::green, &commands[0]));
+}
+
+void usbController::loadCommands()
+{
+ commands.clear();
+ int num = 0;
+ // Important commands at the top!
+ commands.append(COMMAND(num++, "None", commandAny, cmdNone, (quint8)0x0));
+ commands.append(COMMAND(num++, "PTT On", commandButton, cmdSetPTT, cmdGetPTT, (quint8)0x1));
+ commands.append(COMMAND(num++, "PTT Off", commandButton, cmdSetPTT, cmdGetPTT, (quint8)0x0));
+ commands.append(COMMAND(num++, "VFOA", commandKnob, cmdSetFreq, cmdGetFreq, (quint8)0x0));
+ commands.append(COMMAND(num++, "VFOB", commandKnob, cmdSetFreq, cmdGetFreq, (quint8)0x1));
+ commands.append(COMMAND(num++, "Freq Down", commandButton, cmdSetFreq, cmdGetFreq, (int)-1));
+ commands.append(COMMAND(num++, "Freq Up", commandButton, cmdSetFreq, cmdGetFreq, (int)1));
+ commands.append(COMMAND(num++, "PTT Off", commandButton, cmdSetPTT, cmdGetPTT, (quint8)0x0));
+ commands.append(COMMAND(num++, "PTT Toggle", commandButton, cmdPTTToggle, cmdGetPTT, (quint8)0x0));
+ commands.append(COMMAND(num++, "Span/Step", commandKnob, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "Tune", commandButton, cmdStartATU, (quint8)0x0));
+ commands.append(COMMAND(num++, "Span/Step", commandButton, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "Step+", commandButton, cmdSetStepUp, (quint8)0x0));
+ commands.append(COMMAND(num++, "Step-", commandButton, cmdSetStepDown, (quint8)0x0));
+ commands.append(COMMAND(num++, "Span+", commandButton, cmdSetSpanUp, (quint8)0x0));
+ commands.append(COMMAND(num++, "Span-", commandButton, cmdSetSpanDown, (quint8)0x0));
+ commands.append(COMMAND(num++, "Modes", commandButton, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "Mode+", commandButton, cmdSetModeUp, (quint8)0x0));
+ commands.append(COMMAND(num++, "Mode-", commandButton, cmdSetModeDown, (quint8)0x0));
+ commands.append(COMMAND(num++, "Mode LSB", commandButton, cmdSetMode, modeLSB));
+ commands.append(COMMAND(num++, "Mode USB", commandButton, cmdSetMode, modeUSB));
+ commands.append(COMMAND(num++, "Mode LSBD", commandButton, cmdSetMode, modeLSB_D));
+ commands.append(COMMAND(num++, "Mode USBD", commandButton, cmdSetMode, modeUSB_D));
+ commands.append(COMMAND(num++, "Mode CW", commandButton, cmdSetMode, modeCW));
+ commands.append(COMMAND(num++, "Mode CWR", commandButton, cmdSetMode, modeCW_R));
+ commands.append(COMMAND(num++, "Mode FM", commandButton, cmdSetMode, modeFM));
+ commands.append(COMMAND(num++, "Mode AM", commandButton, cmdSetMode, modeAM));
+ commands.append(COMMAND(num++, "Mode RTTY", commandButton, cmdSetMode, modeRTTY));
+ commands.append(COMMAND(num++, "Mode RTTYR", commandButton, cmdSetMode, modeRTTY_R));
+ commands.append(COMMAND(num++, "Mode PSK", commandButton, cmdSetMode, modePSK));
+ commands.append(COMMAND(num++, "Mode PSKR", commandButton, cmdSetMode, modePSK_R));
+ commands.append(COMMAND(num++, "Mode DV", commandButton, cmdSetMode, modeDV));
+ commands.append(COMMAND(num++, "Mode DD", commandButton, cmdSetMode, modeDD));
+ commands.append(COMMAND(num++, "Bands", commandButton, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "Band+", commandButton, cmdSetBandUp, (quint8)0x0));
+ commands.append(COMMAND(num++, "Band-", commandButton, cmdSetBandDown, (quint8)0x0));
+ commands.append(COMMAND(num++, "Band 23cm", commandButton, cmdGetBandStackReg, band23cm));
+ commands.append(COMMAND(num++, "Band 70cm", commandButton, cmdGetBandStackReg, band70cm));
+ commands.append(COMMAND(num++, "Band 2m", commandButton, cmdGetBandStackReg, band2m));
+ commands.append(COMMAND(num++, "Band AIR", commandButton, cmdGetBandStackReg, bandAir));
+ commands.append(COMMAND(num++, "Band WFM", commandButton, cmdGetBandStackReg, bandWFM));
+ commands.append(COMMAND(num++, "Band 4m", commandButton, cmdGetBandStackReg, band4m));
+ commands.append(COMMAND(num++, "Band 6m", commandButton, cmdGetBandStackReg, band6m));
+ commands.append(COMMAND(num++, "Band 10m", commandButton, cmdGetBandStackReg, band10m));
+ commands.append(COMMAND(num++, "Band 12m", commandButton, cmdGetBandStackReg, band12m));
+ commands.append(COMMAND(num++, "Band 15m", commandButton, cmdGetBandStackReg, band15m));
+ commands.append(COMMAND(num++, "Band 17m", commandButton, cmdGetBandStackReg, band17m));
+ commands.append(COMMAND(num++, "Band 20m", commandButton, cmdGetBandStackReg, band20m));
+ commands.append(COMMAND(num++, "Band 30m", commandButton, cmdGetBandStackReg, band30m));
+ commands.append(COMMAND(num++, "Band 40m", commandButton, cmdGetBandStackReg, band40m));
+ commands.append(COMMAND(num++, "Band 60m", commandButton, cmdGetBandStackReg, band60m));
+ commands.append(COMMAND(num++, "Band 80m", commandButton, cmdGetBandStackReg, band80m));
+ commands.append(COMMAND(num++, "Band 160m", commandButton, cmdGetBandStackReg, band160m));
+ commands.append(COMMAND(num++, "Band 630m", commandButton, cmdGetBandStackReg, band630m));
+ commands.append(COMMAND(num++, "Band 2200m", commandButton, cmdGetBandStackReg, band2200m));
+ commands.append(COMMAND(num++, "Band GEN", commandButton, cmdGetBandStackReg, bandGen));
+ commands.append(COMMAND(num++, "NB/NR", commandButton, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "NR On", commandButton, cmdSetNR, cmdGetNR, (quint8)0x01));
+ commands.append(COMMAND(num++, "NR Off", commandButton, cmdSetNR, cmdGetNR, (quint8)0x0));
+ commands.append(COMMAND(num++, "NB On", commandButton, cmdSetNB, cmdGetNB, (quint8)0x01));
+ commands.append(COMMAND(num++, "NB Off", commandButton, cmdSetNB, cmdGetNB, (quint8)0x0));
+ commands.append(COMMAND(num++, "Moni On", commandButton, cmdSetMonitor, cmdGetMonitor, (quint8)0x01));
+ commands.append(COMMAND(num++, "Moni Off", commandButton, cmdSetMonitor, cmdGetMonitor, (quint8)0x0));
+ commands.append(COMMAND(num++, "Comp On", commandButton, cmdSetComp, cmdGetComp, (quint8)0x01));
+ commands.append(COMMAND(num++, "Comp Off", commandButton, cmdSetComp, cmdGetComp, (quint8)0x0));
+ commands.append(COMMAND(num++, "Vox On", commandButton, cmdSetVox, cmdGetVox, (quint8)0x01));
+ commands.append(COMMAND(num++, "Vox Off", commandButton, cmdSetVox, cmdGetVox, (quint8)0x0));
+ commands.append(COMMAND(num++, "Split", commandButton, cmdNone, (quint8)0x0));
+ commands.append(COMMAND(num++, "Split On", commandButton, cmdSetQuickSplit, cmdGetDuplexMode, (quint8)0x01));
+ commands.append(COMMAND(num++, "Split Off", commandButton, cmdSetQuickSplit, cmdGetDuplexMode, (quint8)0x0));
+ commands.append(COMMAND(num++, "Swap VFO", commandButton, cmdVFOSwap, (quint8)0x0));
+ commands.append(COMMAND(num++, "Scope", commandButton, cmdNone, (quint8)0x0));
+ commands.append(COMMAND(num++, "Spectrum", commandButton, cmdLCDSpectrum, (quint8)0x0));
+ commands.append(COMMAND(num++, "Waterfall", commandButton, cmdLCDWaterfall, (quint8)0x0));
+ commands.append(COMMAND(num++, "No Display", commandButton, cmdLCDNothing, (quint8)0x0));
+ commands.append(COMMAND(num++, "Pages", commandButton, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "Page Down", commandButton, cmdPageDown, (quint8)0x0));
+ commands.append(COMMAND(num++, "Page Up", commandButton, cmdPageUp, (quint8)0x0));
+
+ commands.append(COMMAND(num++, "AF Gain", commandKnob, cmdSetAfGain, cmdGetAfGain, (quint8)0xff));
+ commands.append(COMMAND(num++, "RF Gain", commandKnob, cmdSetRxRfGain, cmdGetRxGain, (quint8)0xff));
+ commands.append(COMMAND(num++, "TX Power", commandKnob, cmdSetTxPower, cmdGetTxPower, (quint8)0xff));
+ commands.append(COMMAND(num++, "Mic Gain", commandKnob, cmdSetMicGain, cmdGetMicGain, (quint8)0xff));
+ commands.append(COMMAND(num++, "Mod Level", commandKnob, cmdSetModLevel, cmdNone, (quint8)0xff));
+ commands.append(COMMAND(num++, "Squelch", commandKnob, cmdSetSql, cmdGetSql, (quint8)0xff));
+ commands.append(COMMAND(num++, "Monitor", commandKnob, cmdSetMonitorGain, cmdGetMonitorGain, (quint8)0xff));
+ commands.append(COMMAND(num++, "Compressor", commandKnob, cmdSetCompLevel, cmdGetCompLevel, (quint8)0xff));
+ commands.append(COMMAND(num++, "Vox Level", commandKnob, cmdSetVoxGain, cmdGetVoxGain, (quint8)0xff));
+ commands.append(COMMAND(num++, "Anti-Vox", commandKnob, cmdSetAntiVoxGain, cmdGetAntiVoxGain, (quint8)0xff));
+ commands.append(COMMAND(num++, "NB Level", commandKnob, cmdSetNBLevel, cmdGetNBLevel, (quint8)0xff));
+ commands.append(COMMAND(num++, "NR Level", commandKnob, cmdSetNRLevel, cmdGetNRLevel, (quint8)0xff));
+ commands.append(COMMAND(num++, "Span/Step", commandKnob, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "IF Shift", commandKnob, cmdSetIFShift, cmdGetIFShift, (quint8)0xff));
+ commands.append(COMMAND(num++, "In PBT", commandKnob, cmdSetTPBFInner, cmdGetTPBFInner, (quint8)0xff));
+ commands.append(COMMAND(num++, "Out PBT", commandKnob, cmdSetTPBFOuter, cmdGetTPBFOuter, (quint8)0xff));
+ commands.append(COMMAND(num++, "Span/Step", commandKnob, cmdSeparator, (quint8)0x0));
+ commands.append(COMMAND(num++, "CW Pitch", commandKnob, cmdSetCwPitch, cmdGetCwPitch, (quint8)0xff));
+ commands.append(COMMAND(num++, "CW Speed", commandKnob, cmdSetKeySpeed, cmdGetKeySpeed, (quint8)0xff));
+}
+
+
+void usbController::programPages(USBDEVICE* dev, int val)
+{
+ QMutexLocker locker(mutex);
+
+ if (dev->pages > val) {
+ qInfo(logUsbControl()) << "Removing unused pages from " << dev->product;
+ // Remove unneded pages
+
+ // Remove old buttons
+ for (auto b = buttonList->begin();b != buttonList->end();)
+ {
+ if (b->parent == dev && b->page > val)
+ {
+ if (b->text != Q_NULLPTR) {
+ delete b->text;
+ b->text = Q_NULLPTR;
+ }
+ if (b->bgRect != Q_NULLPTR) {
+ delete b->bgRect;
+ b->bgRect = Q_NULLPTR;
+ }
+ b->onCommand = Q_NULLPTR;
+ b->offCommand = Q_NULLPTR;
+ if (b->icon != Q_NULLPTR) {
+ delete b->icon;
+ b->icon=Q_NULLPTR;
+ }
+ b = buttonList->erase(b);
+ } else {
+ ++b;
+ }
}
- qDebug(logUsbControl()) << "write() success";
+ // Remove old knobs
+ for (auto k = knobList->begin();k != knobList->end();)
+ {
+ if (k->parent == dev && k->page > val)
+ {
+ if (k->text != Q_NULLPTR) {
+ delete k->text;
+ k->text = Q_NULLPTR;
+ k->command = Q_NULLPTR;
+ }
+ k = knobList->erase(k);
+ } else {
+ ++k;
+ }
+ }
}
+ else if (dev->pages < val)
+ {
+ for (int page=dev->pages+1; page<=val; page++)
+ {
+ qInfo(logUsbControl()) << QString("Adding new page %0 to %1").arg(page).arg(dev->product);
+ // Add new pages
+
+ for (auto bt = defaultButtons.begin();bt != defaultButtons.end(); bt++)
+ {
+ if (bt->dev == dev->type.model) {
+ BUTTON but = BUTTON(bt->dev, bt->num, bt->pos, bt->textColour, &commands[0], &commands[0],bt->graphics);
+ but.path = dev->path;
+ but.parent = dev;
+ but.page = page;
+ buttonList->append(but);
+ }
+ }
+
+ for (auto kb = defaultKnobs.begin();kb != defaultKnobs.end(); kb++)
+ {
+ if (kb->dev == dev->type.model) {
+ KNOB knob = KNOB(kb->dev, kb->num, kb->pos, kb->textColour, &commands[0]);
+ knob.path = dev->path;
+ knob.parent = dev;
+ knob.page = page;
+ knobList->append(knob);
+ }
+ }
+ }
+ }
+ dev->pages = val;
}
-void usbController::getVersion()
-{
- QByteArray data(64, 0x0);
- data[0] = 63;
- data[1] = 0x02;
- int res = hid_write(handle, (const unsigned char*)data.constData(), data.size());
- if (res < 0) {
- qDebug(logUsbControl()) << "Unable to write(), Error:" << hid_error(handle);
- }
-}
-
-/* End of RC28 functions*/
/* Functions below are for Gamepad controllers */
void usbController::buttonState(QString name, bool val)
{
+ Q_UNUSED(name)
+ Q_UNUSED(val)
+ // Need to fix gamepad support
+ /*
for (BUTTON* but = buttonList->begin(); but != buttonList->end(); but++) {
if (but->dev == usbDevice && but->name == name) {
-
+
if (val && but->onCommand->index > 0) {
qInfo(logUsbControl()) << "On Button" << but->name << "event:" << but->onCommand->text;
emit button(but->onCommand);
@@ -776,11 +1789,12 @@ void usbController::buttonState(QString name, bool val)
}
}
}
+ */
}
void usbController::buttonState(QString name, double val)
{
-
+
if (name == "LEFTX")
{
int value = val * 1000000;
@@ -789,7 +1803,7 @@ void usbController::buttonState(QString name, double val)
/*
for (BUTTON* but = buttonList->begin(); but != buttonList->end(); but++) {
if (but->dev == usbDevice && but->name == name) {
-
+
if (val && but->onCommand->index > 0) {
qInfo(logUsbControl()) << "On Button" << but->name << "event:" << but->onCommand->text;
emit button(but->onCommand);
@@ -805,131 +1819,264 @@ void usbController::buttonState(QString name, double val)
/* End of Gamepad functions*/
-
-/* Functions below are for Xencelabs QuickKeys*/
-void usbController::programButton(quint8 val, QString text)
+void usbController::receiveLevel(cmds cmd, unsigned char level)
{
- if (handle && usbDevice == QuickKeys && val < 8) {
- text = text.mid(0, 10); // Make sure text is no more than 10 characters.
- qDebug(logUsbControl()) << QString("Programming button %0 with %1").arg(val).arg(text);
- QByteArray data(32, 0x0);
- data[0] = (qint8)0x02;
- data[1] = (qint8)0xb1;
- data[3] = val + 1;
- data[5] = text.length() * 2;
- data.replace(10, this->deviceId.size(), this->deviceId.toLocal8Bit());
+ // Update knob if relevant, step through all devices
+ QMutexLocker locker(mutex);
- QByteArray le = qToLittleEndian(QByteArray::fromRawData(reinterpret_cast(text.constData()), text.size() * 2));
- data.replace(16, le.size(), le);
+ for (auto devIt = devices->begin(); devIt != devices->end(); devIt++)
+ {
+ auto dev = &devIt.value();
- int res = hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
-
- if (res < 0) {
- qDebug(logUsbControl()) << "Unable to write(), Error:" << hid_error(this->handle);
- return;
+ auto kb = std::find_if(knobList->begin(), knobList->end(), [dev, cmd](const KNOB& k)
+ { return (k.command && dev->connected && k.path == dev->path && k.page == dev->currentPage && k.command->getCommand == cmd);});
+ if (kb != knobList->end() && kb->num < dev->knobValues.size()) {
+ qInfo(logUsbControl()) << "Received value:" << level << "for knob" << kb->num;
+ // Set both current and previous knobvalue to the received value
+ dev->knobValues[kb->num].value = level/dev->sensitivity;
+ dev->knobValues[kb->num].previous = level/dev->sensitivity;
+ }
+ auto bt = std::find_if(buttonList->begin(), buttonList->end(), [dev, cmd](const BUTTON& b)
+ { return (b.onCommand && dev->connected && b.path == dev->path && b.page == dev->currentPage && b.onCommand->getCommand == cmd && b.led != 0 && b.led <= dev->type.leds);});
+ if (bt != buttonList->end()) {
+ qInfo(logUsbControl()) << "Received value:" << level << "for led" << bt->led;
+ QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,bt->led,QString("%1").arg(level)); });
}
}
}
-void usbController::programBrightness(quint8 val) {
- if (handle && usbDevice == QuickKeys) {
- qDebug(logUsbControl()) << QString("Programming brightness to %0").arg(val);
- QByteArray data(32, 0x0);
- data[0] = (qint8)0x02;
- data[1] = (qint8)0xb1;
- data[2] = (qint8)0x0a;
- data[3] = (qint8)0x01;
- data[4] = val;
- data.replace(10, this->deviceId.size(), this->deviceId.toLocal8Bit());
- hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
- }
-}
-
-void usbController::programOrientation(quint8 val) {
- if (handle && usbDevice == QuickKeys) {
- qDebug(logUsbControl()) << QString("Programming orientation to %0").arg(val);
- QByteArray data(32, 0x0);
- data[0] = (qint8)0x02;
- data[1] = (qint8)0xb1;
- data[2] = (qint8)val;
- data.replace(10, this->deviceId.size(), this->deviceId.toLocal8Bit());
- hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
- }
-}
-
-void usbController::programSpeed(quint8 val) {
- if (handle && usbDevice == QuickKeys) {
- qDebug(logUsbControl()) << QString("Programming speed to %0").arg(val);
- QByteArray data(32, 0x0);
- data[0] = (qint8)0x02;
- data[1] = (qint8)0xb4;
- data[2] = (qint8)0x04;
- data[3] = (qint8)0x01;
- data[4] = (qint8)0x01;
- data[5] = val;
- data.replace(10, this->deviceId.size(), this->deviceId.toLocal8Bit());
- hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
- }
-}
-
-
-void usbController::programWheelColour(quint8 r, quint8 g, quint8 b)
+void usbController::backupController(USBDEVICE* dev, QString file)
{
- if (handle && usbDevice == QuickKeys) {
- QByteArray data(32, 0x0);
- data[0] = (qint8)0x02;
- data[1] = (qint8)0xb4;
- data[2] = (qint8)0x01;
- data[3] = (qint8)0x01;
- data[6] = (qint8)r;
- data[7] = (qint8)g;
- data[8] = (qint8)b;
- data.replace(10, this->deviceId.size(), this->deviceId.toLocal8Bit());
- hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
- currentColour.setRed(r);
- currentColour.setGreen(g);
- currentColour.setBlue(b);
- }
-}
+ QMutexLocker locker(mutex);
-void usbController::programOverlay(quint8 duration, QString text)
-{
- if (handle && usbDevice == QuickKeys) {
- text = text.mid(0, 32);
- QByteArray data(32, 0x0);
- data[0] = (qint8)0x02;
- data[1] = (qint8)0xb1;
- data[3] = (qint8)duration;
- data.replace(10, this->deviceId.size(), this->deviceId.toLocal8Bit());
- for (int i = 0; i < text.length(); i = i + 8)
+ QSettings* settings = new QSettings(file, QSettings::Format::IniFormat);
+
+ qInfo(logUsbControl()) << "Backup of" << dev->path << "to" << file;
+
+ settings->setValue("Version", QString(WFVIEW_VERSION));
+ settings->beginGroup("Controller");
+
+ settings->setValue("Model",dev->product);
+ settings->setValue("Disabled", dev->disabled);
+ settings->setValue("Sensitivity", dev->sensitivity);
+ settings->setValue("Brightness", dev->brightness);
+ settings->setValue("Orientation", dev->orientation);
+ settings->setValue("Speed", dev->speed);
+ settings->setValue("Timeout", dev->timeout);
+ settings->setValue("Pages", dev->pages);
+ settings->setValue("Color", dev->color.name(QColor::HexArgb));
+ settings->setValue("LCD", dev->lcd);
+
+ int n=0;
+ settings->beginWriteArray("Buttons");
+ for (auto b = buttonList->begin(); b != buttonList->end(); b++)
+ {
+ if (b->path == dev->path)
{
- data[2] = (i == 0) ? 0x05 : 0x06;
- QByteArray le = qToLittleEndian(QByteArray::fromRawData(reinterpret_cast(text.mid(i, 8).constData()), text.mid(i, 8).size() * 2));
- data.replace(16, le.size(), le);
- data[5] = text.mid(i, 8).length() * 2;
- data[6] = (i > 0 && text.mid(i).size() > 8) ? 0x01 : 0x00;
- hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
+ settings->setArrayIndex(n);
+ settings->setValue("Page", b->page);
+ settings->setValue("Dev", b->dev);
+ settings->setValue("Num", b->num);
+ settings->setValue("Name", b->name);
+ settings->setValue("Left", b->pos.left());
+ settings->setValue("Top", b->pos.top());
+ settings->setValue("Width", b->pos.width());
+ settings->setValue("Height", b->pos.height());
+ settings->setValue("Colour", b->textColour.name(QColor::HexArgb));
+ settings->setValue("BackgroundOn", b->backgroundOn.name(QColor::HexArgb));
+ settings->setValue("BackgroundOff", b->backgroundOff.name(QColor::HexArgb));
+ if (b->icon != Q_NULLPTR) {
+ settings->setValue("Icon", *b->icon);
+ settings->setValue("IconName", b->iconName);
+ }
+ settings->setValue("Toggle", b->toggle);
+
+ if (b->onCommand != Q_NULLPTR)
+ settings->setValue("OnCommand", b->onCommand->text);
+ if (b->offCommand != Q_NULLPTR)
+ settings->setValue("OffCommand", b->offCommand->text);
+ settings->setValue("Graphics",b->graphics);
+ if (b->led > -1) {
+ settings->setValue("Led", b->led);
+ }
+ ++n;
}
- //qInfo(logUsbControl()) << "Sent overlay" << text;
}
+ settings->endArray();
+
+ n = 0;
+ settings->beginWriteArray("Knobs");
+ for (auto k = knobList->begin(); k != knobList->end(); k++)
+ {
+ if (k->path == dev->path)
+ {
+ settings->setArrayIndex(n);
+ settings->setValue("Page", k->page);
+ settings->setValue("Dev", k->dev);
+ settings->setValue("Num", k->num);
+ settings->setValue("Left", k->pos.left());
+ settings->setValue("Top", k->pos.top());
+ settings->setValue("Width", k->pos.width());
+ settings->setValue("Height", k->pos.height());
+ settings->setValue("Colour", k->textColour.name());
+ if (k->command != Q_NULLPTR)
+ settings->setValue("Command", k->command->text);
+ ++n;
+ }
+ }
+
+ settings->endArray();
+ settings->endGroup();
+ settings->sync();
+ delete settings;
}
-void usbController::programTimeout(quint8 val)
+void usbController::restoreController(USBDEVICE* dev, QString file)
{
- if (handle && usbDevice == QuickKeys) {
- qInfo(logUsbControl()) << QString("Programming timeout to %0 minutes").arg(val);
- QByteArray data(32, 0x0);
- data[0] = (qint8)0x02;
- data[1] = (qint8)0xb4;
- data[2] = (qint8)0x08;
- data[3] = (qint8)0x01;
- data[4] = val;
- data.replace(10, this->deviceId.size(), this->deviceId.toLocal8Bit());
- hid_write(this->handle, (const unsigned char*)data.constData(), data.size());
+
+ // Signal UI to remove existing device.
+ emit removeDevice(dev);
+
+ QMutexLocker locker(mutex);
+
+ QSettings* settings = new QSettings(file, QSettings::Format::IniFormat);
+
+ settings->beginGroup("Controller");
+
+ dev->disabled = settings->value("Disabled", false).toBool();
+ dev->sensitivity = settings->value("Sensitivity", 1).toInt();
+ dev->pages = settings->value("Pages", 1).toInt();
+ dev->brightness = (quint8)settings->value("Brightness", 2).toInt();
+ dev->orientation = (quint8)settings->value("Orientation", 2).toInt();
+ dev->speed = (quint8)settings->value("Speed", 2).toInt();
+ dev->timeout = (quint8)settings->value("Timeout", 30).toInt();
+ dev->color.setNamedColor(settings->value("Color", QColor(Qt::white).name(QColor::HexArgb)).toString());
+ dev->lcd = (cmds)settings->value("LCD",0).toInt();
+
+ qInfo(logUsbControl()) << "Restore of" << dev->product << "path" << dev->path << "from" << file;
+
+ // Remove old buttons
+
+ for (auto b = buttonList->begin();b != buttonList->end();)
+ {
+ if (b->parent == dev)
+ {
+ if (b->text != Q_NULLPTR) {
+ delete b->text;
+ b->text = Q_NULLPTR;
+ }
+ if (b->bgRect != Q_NULLPTR) {
+ delete b->bgRect;
+ b->bgRect = Q_NULLPTR;
+ }
+ b->onCommand = Q_NULLPTR;
+ b->offCommand = Q_NULLPTR;
+ if (b->icon != Q_NULLPTR) {
+ delete b->icon;
+ b->icon=Q_NULLPTR;
+ }
+ b = buttonList->erase(b);
+ } else {
+ ++b;
+ }
}
+
+ int numButtons = settings->beginReadArray("Buttons");
+ if (numButtons == 0) {
+ qInfo(logUsbControl()) << "No Buttons Found!";
+ settings->endArray();
+ }
+ else {
+ for (int b = 0; b < numButtons; b++)
+ {
+ settings->setArrayIndex(b);
+ BUTTON but;
+ but.page = settings->value("Page", 1).toInt();
+ but.dev = (usbDeviceType)settings->value("Dev", 0).toInt();
+ but.num = settings->value("Num", 0).toInt();
+ but.name = settings->value("Name", "").toString();
+ but.pos = QRect(settings->value("Left", 0).toInt(),
+ settings->value("Top", 0).toInt(),
+ settings->value("Width", 0).toInt(),
+ settings->value("Height", 0).toInt());
+ but.textColour.setNamedColor(settings->value("Colour", QColor(Qt::white).name(QColor::HexArgb)).toString());
+ but.backgroundOn.setNamedColor(settings->value("BackgroundOn", QColor(Qt::lightGray).name(QColor::HexArgb)).toString());
+ but.backgroundOff.setNamedColor(settings->value("BackgroundOff", QColor(Qt::blue).name(QColor::HexArgb)).toString());
+ but.toggle = settings->value("Toggle", false).toBool();
+#if (QT_VERSION > QT_VERSION_CHECK(6,0,0))
+ if (settings->value("Icon",NULL) != NULL) {
+ but.icon = new QImage(settings->value("Icon",NULL).value());
+ but.iconName = settings->value("IconName", "").toString();
+ }
+#endif
+ but.on = settings->value("OnCommand", "None").toString();
+ but.off = settings->value("OffCommand", "None").toString();
+ but.graphics = settings->value("Graphics",false).toBool();
+ but.led = settings->value("Led", -1).toInt();
+ but.path = dev->path;
+ qInfo(logUsbControl()) << "Restoring button" << but.num << "On" << but.on << "Off" << but.off;
+ buttonList->append(BUTTON(but));
+ }
+ settings->endArray();
+ }
+
+
+ // Remove old knobs
+
+ for (auto k = knobList->begin();k != knobList->end();)
+ {
+ if (k->parent == dev)
+ {
+ if (k->text != Q_NULLPTR) {
+ delete k->text;
+ k->text = Q_NULLPTR;
+ k->command = Q_NULLPTR;
+ }
+ k = knobList->erase(k);
+ } else {
+ ++k;
+ }
+ }
+
+ int numKnobs = settings->beginReadArray("Knobs");
+ if (numKnobs == 0) {
+ qInfo(logUsbControl()) << "No Knobs Found!";
+ settings->endArray();
+ }
+ else {
+ for (int k = 0; k < numKnobs; k++)
+ {
+ settings->setArrayIndex(k);
+ KNOB kb;
+ kb.page = settings->value("Page", 1).toInt();
+ kb.dev = (usbDeviceType)settings->value("Dev", 0).toInt();
+ kb.num = settings->value("Num", 0).toInt();
+ kb.name = settings->value("Name", "").toString();
+ kb.pos = QRect(settings->value("Left", 0).toInt(),
+ settings->value("Top", 0).toInt(),
+ settings->value("Width", 0).toInt(),
+ settings->value("Height", 0).toInt());
+ kb.textColour = QColor((settings->value("Colour", "Green").toString()));
+
+ kb.cmd = settings->value("Command", "None").toString();
+ kb.path = dev->path;
+ qInfo(logUsbControl()) << "Restoring knob" << kb.num << "Cmd" << kb.cmd;
+ knobList->append(KNOB(kb));
+ }
+ settings->endArray();
+ }
+
+ settings->endGroup();
+ settings->sync();
+ delete settings;
+
+ qInfo(logUsbControl()) << "Disconnecting device" << dev->product;
+ hid_close(dev->handle);
+ dev->handle = NULL;
+ dev->connected = false;
+ dev->uiCreated = false;
+ devicesConnected--;
+ QTimer::singleShot(250, this, SLOT(run())); // Call run to cleanup connectons after 250ms
}
-/* End of functions for Xencelabs QuickKeys*/
-
-
#endif
diff --git a/usbcontroller.h b/usbcontroller.h
index 4f732cf..44465f0 100644
--- a/usbcontroller.h
+++ b/usbcontroller.h
@@ -8,12 +8,24 @@
#include
#include
#include
+#include
#include
#include
#include
+#include
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
#if defined(USB_CONTROLLER) && QT_VERSION < QT_VERSION_CHECK(6,0,0)
#include
@@ -23,7 +35,7 @@
#ifndef Q_OS_WIN
#include "hidapi/hidapi.h"
#else
- #include "hidapi.h"
+ #include "hidapi.h"
#endif
#ifdef HID_API_VERSION_MAJOR
@@ -53,15 +65,87 @@
using namespace std;
-
#define HIDDATALENGTH 64
#define MAX_STR 255
+struct USBTYPE {
+ USBTYPE() {}
+ USBTYPE(usbDeviceType model,quint32 manufacturerId, quint32 productId , quint32 usage, quint32 usagePage, int buttons, int knobs, int leds, int maxPayload, int iconSize) :
+ model(model), manufacturerId(manufacturerId), productId(productId), usage(usage), usagePage(usagePage), buttons(buttons), knobs(knobs), leds(leds), maxPayload(maxPayload), iconSize(iconSize) {}
+
+ usbDeviceType model = usbNone;
+ quint32 manufacturerId=0;
+ quint32 productId=0;
+ quint32 usage=0;
+ quint32 usagePage=0;
+ int buttons=0;
+ int knobs=0;
+ int leds=0;
+ int maxPayload=0;
+ int iconSize=0;
+};
+
+
+struct KNOBVALUE {
+ int value=0;
+ int previous=0;
+ quint8 send=0;
+ qint64 lastChanged=0;
+ QString name="";
+};
+
+struct USBDEVICE {
+ USBDEVICE() {}
+ USBDEVICE(USBTYPE type) : type(type) {}
+ USBTYPE type;
+ bool detected = false;
+ bool remove = false;
+ bool connected = false;
+ bool uiCreated = false;
+ bool disabled = false;
+ quint8 speed=2;
+ quint8 timeout=30;
+ quint8 brightness=2;
+ quint8 orientation=0;
+ QColor color=Qt::darkGray;
+ cmds lcd=cmdNone;
+
+ hid_device* handle = NULL;
+ QString product = "";
+ QString manufacturer = "";
+ QString serial = "";
+ QString deviceId = "";
+ QString path = "";
+ int sensitivity = 1;
+ unsigned char jogpos=0;
+ unsigned char shutpos=0;
+ unsigned char shutMult = 0;
+ int jogCounter = 0;
+ quint32 buttons = 0;
+ quint32 knobs = 0;
+ QList knobValues;
+
+ QTime lastusbController = QTime::currentTime();
+ QByteArray lastData = QByteArray(8,0x0);
+ unsigned char lastDialPos=0;
+ QUuid uuid;
+ QLabel *message;
+ int pages=1;
+ int currentPage=0;
+ QGraphicsScene* scene = Q_NULLPTR;
+ QSpinBox* pageSpin = Q_NULLPTR;
+ QImage image;
+ quint8 ledStatus=0x07;
+};
+
struct COMMAND {
COMMAND() {}
-
+ COMMAND(int index, QString text, usbCommandType cmdType, int command, int value) :
+ index(index), text(text), cmdType(cmdType), command(command), value(value) {}
COMMAND(int index, QString text, usbCommandType cmdType, int command, unsigned char suffix) :
index(index), text(text), cmdType(cmdType), command(command), suffix(suffix) {}
+ COMMAND(int index, QString text, usbCommandType cmdType, int command, int getCommand, unsigned char suffix) :
+ index(index), text(text), cmdType(cmdType), command(command), getCommand(getCommand), suffix(suffix) {}
COMMAND(int index, QString text, usbCommandType cmdType, int command, availableBands band) :
index(index), text(text), cmdType(cmdType), command(command), band(band) {}
COMMAND(int index, QString text, usbCommandType cmdType, int command, mode_kind mode) :
@@ -71,7 +155,9 @@ struct COMMAND {
QString text;
usbCommandType cmdType = commandButton;
int command=0;
+ int getCommand=0;
unsigned char suffix=0x0;
+ int value=0;
availableBands band=bandGen;
mode_kind mode=modeLSB;
};
@@ -79,21 +165,33 @@ struct COMMAND {
struct BUTTON {
BUTTON() {}
- BUTTON(usbDeviceType dev, int num, QRect pos, const QColor textColour, COMMAND* on, COMMAND* off) :
- dev(dev), num(num), name(""), pos(pos), textColour(textColour), onCommand(on), offCommand(off) {}
+ BUTTON(usbDeviceType dev, int num, QRect pos, const QColor textColour, COMMAND* on, COMMAND* off, bool graphics=false, int led=0) :
+ dev(dev), num(num), name(""), pos(pos), textColour(textColour), onCommand(on), offCommand(off), on(onCommand->text), off(offCommand->text), graphics(graphics), led(led){}
BUTTON(usbDeviceType dev, QString name, QRect pos, const QColor textColour, COMMAND* on, COMMAND* off) :
- dev(dev), num(-1), name(name), pos(pos), textColour(textColour), onCommand(on), offCommand(off) {}
+ dev(dev), num(-1), name(name), pos(pos), textColour(textColour), onCommand(on), offCommand(off), on(onCommand->text), off(offCommand->text) {}
usbDeviceType dev;
+ USBDEVICE* parent = Q_NULLPTR;
+ int page=1;
int num;
QString name;
QRect pos;
QColor textColour;
const COMMAND* onCommand = Q_NULLPTR;
const COMMAND* offCommand = Q_NULLPTR;
- QGraphicsTextItem* onText;
- QGraphicsTextItem* offText;
-
+ QGraphicsRectItem* bgRect = Q_NULLPTR;
+ QGraphicsTextItem* text = Q_NULLPTR;
+ QString on;
+ QString off;
+ QString path;
+ QColor backgroundOn = Qt::lightGray;
+ QColor backgroundOff = Qt::blue;
+ QString iconName = "";
+ QImage* icon = Q_NULLPTR;
+ bool toggle = false;
+ bool isOn = false;
+ bool graphics = false;
+ int led = 0;
};
@@ -101,18 +199,25 @@ struct KNOB {
KNOB() {}
KNOB(usbDeviceType dev, int num, QRect pos, const QColor textColour, COMMAND* command) :
- dev(dev), num(num), name(""), pos(pos), textColour(textColour), command(command) {}
+ dev(dev), num(num), name(""), pos(pos), textColour(textColour), command(command), cmd(command->text) {}
usbDeviceType dev;
+ USBDEVICE* parent = Q_NULLPTR;
+ int page=1;
int num;
QString name;
QRect pos;
QColor textColour;
const COMMAND* command = Q_NULLPTR;
- QGraphicsTextItem* text;
-
+ QGraphicsTextItem* text = Q_NULLPTR;
+ QString cmd;
+ QString path;
};
+
+typedef QMap usbDevMap;
+
+
#if defined(USB_CONTROLLER)
class usbController : public QObject
{
@@ -121,25 +226,21 @@ class usbController : public QObject
public:
usbController();
~usbController();
+ bool hotPlugEvent(const QByteArray & eventType, void * message, long * result);
public slots:
- void init(int sens, QMutex *mut);
+ void init(QMutex* mut,usbDevMap* prefs ,QVector* buts,QVector* knobs);
void run();
void runTimer();
- void ledControl(bool on, unsigned char num);
- void receiveCommands(QVector*);
- void receiveButtons(QVector*);
- void receiveKnobs(QVector*);
void receivePTTStatus(bool on);
- void getVersion();
- void receiveSensitivity(int val);
- void programButton(quint8 val, QString text);
- void programBrightness(quint8 val);
- void programOrientation(quint8 val);
- void programSpeed(quint8 val);
- void programWheelColour(quint8 r, quint8 g, quint8 b);
- void programOverlay(quint8 duration, QString text);
- void programTimeout(quint8 val);
+ void receiveLevel(cmds cmd, unsigned char level);
+ void programPages(USBDEVICE* dev, int pages);
+ void programDisable(USBDEVICE* dev, bool disabled);
+
+ void sendRequest(USBDEVICE *dev, usbFeatureType feature, int val=0, QString text="", QImage* img=Q_NULLPTR, QColor* color=Q_NULLPTR);
+ void sendToLCD(QImage *img);
+ void backupController(USBDEVICE* dev, QString file);
+ void restoreController(USBDEVICE* dev, QString file);
signals:
void jogPlus();
@@ -148,56 +249,53 @@ signals:
void doShuttle(bool plus, quint8 level);
void setBand(int band);
void button(const COMMAND* cmd);
- void newDevice(unsigned char devType, QVector* but, QVector* kb, QVector* cmd, QMutex* mut);
- void sendSensitivity(int val);
+ void initUI(usbDevMap* devs, QVector* but, QVector* kb, QVector* cmd, QMutex* mut);
+ void newDevice(USBDEVICE* dev);
+ void removeDevice(USBDEVICE* dev);
+ void setConnected(USBDEVICE* dev);
+ void changePage(USBDEVICE* dev, int page);
private:
- hid_device* handle=NULL;
+ void loadButtons();
+ void loadKnobs();
+ void loadCommands();
+
+
int hidStatus = 1;
bool isOpen=false;
- quint32 buttons = 0;
- quint32 knobs = 0;
- unsigned char jogpos=0;
- unsigned char shutpos=0;
- unsigned char shutMult = 0;
- int jogCounter = 0;
- QTime lastusbController = QTime::currentTime();
- QByteArray lastData = QByteArray(8,0x0);
- unsigned char lastDialPos=0;
+ int devicesConnected=0;
QVector* buttonList;
QVector* knobList;
- QVector* commands = Q_NULLPTR;
- QString product="";
- QString manufacturer="";
- QString serial="";
- QString deviceId = "";
- QString path = "";
- quint16 vendorId = 0;
- quint16 productId = 0;
- int sensitivity = 1;
- QList knobValues;
- QList knobSend;
- QMutex* mutex=Q_NULLPTR;
- QColor currentColour;
+
+ QVector defaultButtons;
+ QVector defaultKnobs;
+ QVector knownDevices;
+ QVector commands;
+ usbDevMap* devices;
+
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
QGamepad* gamepad=Q_NULLPTR;
#endif
void buttonState(QString but, bool val);
void buttonState(QString but, double val);
- usbDeviceType usbDevice = usbNone;
+ QColor currentColour;
- unsigned short knownUsbDevices[6][5] = {
- {shuttleXpress,0x0b33,0x0020,0x0000,0x0000},
- {shuttlePro2,0x0b33,0x0030,0x0000,0x0000},
- {RC28,0x0c26,0x001e,0x0004,0x0004},
- {eCoderPlus, 0x1fc9, 0x0003,0x0000,0x0000},
- {QuickKeys, 0x28bd, 0x5202,0x0001,0xff0a},
- {QuickKeys, 0x28bd, 0x5203,0x0001,0xff0a}
- };
+ QMutex* mutex=Q_NULLPTR;
+ COMMAND sendCommand;
+ QTimer* dataTimer = Q_NULLPTR;
protected:
};
+
+class usbControllerDev : public QObject
+{
+ Q_OBJECT
+
+};
+
+
+
#endif
#endif
diff --git a/wfmain.cpp b/wfmain.cpp
index 21e07d9..75289a7 100644
--- a/wfmain.cpp
+++ b/wfmain.cpp
@@ -49,7 +49,6 @@ wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode
sat = new satelliteSetup();
trxadj = new transceiverAdjustments();
cw = new cwSender();
- shut = new controllerSetup();
abtBox = new aboutbox();
selRad = new selectRadio();
@@ -77,12 +76,15 @@ wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode
qRegisterMetaType*>();
qRegisterMetaType*>();
qRegisterMetaType();
+ qRegisterMetaType();
qRegisterMetaType>();
qRegisterMetaType>();
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
+ qRegisterMetaType();
+ qRegisterMetaType();
haveRigCaps = false;
@@ -168,19 +170,39 @@ wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode
amTransmitting = false;
-#if !defined(USB_CONTROLLER)
- ui->enableUsbChk->setVisible(false);
- ui->usbControllerBtn->setVisible(false);
- ui->usbButtonsResetBtn->setVisible(false);
- ui->usbCommandsResetBtn->setVisible(false);
- ui->usbResetLbl->setVisible(false);
-#endif
-
connect(ui->txPowerSlider, &QSlider::sliderMoved,
[&](int value) {
QToolTip::showText(QCursor::pos(), QString("%1").arg(value*100/255), nullptr);
});
+#if !defined(USB_CONTROLLER)
+ ui->enableUsbChk->setVisible(false);
+ ui->usbControllerBtn->setVisible(false);
+ ui->usbControllersResetBtn->setVisible(false);
+ ui->usbResetLbl->setVisible(false);
+#else
+ #if defined(USB_HOTPLUG) && defined(Q_OS_LINUX)
+ uDev = udev_new();
+ if (!uDev)
+ {
+ qInfo(logUsbControl()) << "Cannot register udev, hotplug of USB devices is not available";
+ return;
+ }
+ uDevMonitor = udev_monitor_new_from_netlink(uDev, "udev");
+ if (!uDevMonitor)
+ {
+ qInfo(logUsbControl()) << "Cannot register udev_monitor, hotplug of USB devices is not available";
+ return;
+ }
+ int fd = udev_monitor_get_fd(uDevMonitor);
+ uDevNotifier = new QSocketNotifier(fd, QSocketNotifier::Read,this);
+ connect(uDevNotifier, SIGNAL(activated(int)), this, SLOT(uDevEvent()));
+ udev_monitor_enable_receiving(uDevMonitor);
+ #endif
+#endif
+
+
+
}
wfmain::~wfmain()
@@ -214,6 +236,14 @@ wfmain::~wfmain()
usbControllerThread->quit();
usbControllerThread->wait();
}
+ #if defined(Q_OS_LINUX)
+ if (uDevMonitor)
+ {
+ udev_monitor_unref(uDevMonitor);
+ udev_unref(uDev);
+ delete uDevNotifier;
+ }
+ #endif
#endif
}
@@ -338,6 +368,7 @@ void wfmain::rigConnections()
connect(rig, SIGNAL(haveFrequency(freqt)), this, SLOT(receiveFreq(freqt)));
connect(this, SIGNAL(getFrequency()), rig, SLOT(getFrequency()));
+ connect(this, SIGNAL(getFrequency(unsigned char)), rig, SLOT(getFrequency(unsigned char)));
connect(this, SIGNAL(getMode()), rig, SLOT(getMode()));
connect(this, SIGNAL(getDataMode()), rig, SLOT(getDataMode()));
connect(this, SIGNAL(setDataMode(bool, unsigned char)), rig, SLOT(setDataMode(bool, unsigned char)));
@@ -346,6 +377,12 @@ void wfmain::rigConnections()
connect(this, SIGNAL(setPTT(bool)), rig, SLOT(setPTT(bool)));
connect(this, SIGNAL(getPTT()), rig, SLOT(getPTT()));
+ connect(this, SIGNAL(getVox()), rig, SLOT(getVox()));
+ connect(this, SIGNAL(getMonitor()), rig, SLOT(getMonitor()));
+ connect(this, SIGNAL(getCompressor()), rig, SLOT(getCompressor()));
+ connect(this, SIGNAL(getNB()), rig, SLOT(getNB()));
+ connect(this, SIGNAL(getNR()), rig, SLOT(getNR()));
+
connect(this, SIGNAL(selectVFO(vfo_t)), rig, SLOT(selectVFO(vfo_t)));
connect(this, SIGNAL(sendVFOSwap()), rig, SLOT(exchangeVFOs()));
connect(this, SIGNAL(sendVFOEqualAB()), rig, SLOT(equalizeVFOsAB()));
@@ -386,6 +423,16 @@ void wfmain::rigConnections()
connect(rig, SIGNAL(haveDataMode(bool)), this, SLOT(receiveDataModeStatus(bool)));
connect(rig, SIGNAL(havePassband(quint16)), this, SLOT(receivePassband(quint16)));
connect(rig, SIGNAL(haveCwPitch(unsigned char)), this, SLOT(receiveCwPitch(unsigned char)));
+ connect(rig, SIGNAL(haveMonitorGain(unsigned char)), this, SLOT(receiveMonitorGain(unsigned char)));
+ connect(rig, SIGNAL(haveVoxGain(unsigned char)), this, SLOT(receiveVoxGain(unsigned char)));
+ connect(rig, SIGNAL(haveAntiVoxGain(unsigned char)), this, SLOT(receiveAntiVoxGain(unsigned char)));
+ connect(rig, SIGNAL(haveNBLevel(unsigned char)), this, SLOT(receiveNBLevel(unsigned char)));
+ connect(rig, SIGNAL(haveNRLevel(unsigned char)), this, SLOT(receiveNRLevel(unsigned char)));
+ connect(rig, SIGNAL(haveNB(bool)), this, SLOT(receiveNB(bool)));
+ connect(rig, SIGNAL(haveNR(bool)), this, SLOT(receiveNR(bool)));
+ connect(rig, SIGNAL(haveComp(bool)), this, SLOT(receiveComp(bool)));
+ connect(rig, SIGNAL(haveVox(bool)), this, SLOT(receiveVox(bool)));
+ connect(rig, SIGNAL(haveMonitor(bool)), this, SLOT(receiveMonitor(bool)));
// Repeater, duplex, and split:
connect(rpt, SIGNAL(getDuplexMode()), rig, SLOT(getDuplexMode()));
@@ -470,16 +517,6 @@ void wfmain::rigConnections()
connect(this, SIGNAL(setRptDuplexOffset(freqt)), rig, SLOT(setRptDuplexOffset(freqt)));
connect(this, SIGNAL(getDuplexMode()), rig, SLOT(getDuplexMode()));
- connect(this, SIGNAL(getPassband()), rig, SLOT(getPassband()));
- connect(this, SIGNAL(setPassband(quint16)), rig, SLOT(setPassband(quint16)));
- connect(this, SIGNAL(getCwPitch()), rig, SLOT(getCwPitch()));
- connect(this, SIGNAL(getDashRatio()), rig, SLOT(getDashRatio()));
- connect(this, SIGNAL(getPskTone()), rig, SLOT(getPskTone()));
- connect(this, SIGNAL(getRttyMark()), rig, SLOT(getRttyMark()));
- connect(this, SIGNAL(getTone()), rig, SLOT(getTone()));
- connect(this, SIGNAL(getTSQL()), rig, SLOT(getTSQL()));
- connect(this, SIGNAL(getRptAccessMode()), rig, SLOT(getRptAccessMode()));
-
connect(this, SIGNAL(getModInput(bool)), rig, SLOT(getModInput(bool)));
connect(rig, SIGNAL(haveModInput(rigInput,bool)), this, SLOT(receiveModInput(rigInput, bool)));
connect(this, SIGNAL(setModInput(rigInput, bool)), rig, SLOT(setModInput(rigInput,bool)));
@@ -502,6 +539,14 @@ void wfmain::rigConnections()
connect(this, SIGNAL(setMode(unsigned char, unsigned char)), rig, SLOT(setMode(unsigned char, unsigned char)));
connect(this, SIGNAL(setMode(mode_info)), rig, SLOT(setMode(mode_info)));
+ connect(this, SIGNAL(setVox(bool)), rig, SLOT(setVox(bool)));
+ connect(this, SIGNAL(setMonitor(bool)), rig, SLOT(setMonitor(bool)));
+ connect(this, SIGNAL(setCompressor(bool)), rig, SLOT(setCompressor(bool)));
+ connect(this, SIGNAL(setNB(bool)), rig, SLOT(setNB(bool)));
+ connect(this, SIGNAL(setNR(bool)), rig, SLOT(setNR(bool)));
+
+ connect(this, SIGNAL(setPassband(quint16)), rig, SLOT(setPassband(quint16)));
+
// Levels (read and write)
// Levels: Query:
connect(this, SIGNAL(getLevels()), rig, SLOT(getLevels()));
@@ -515,7 +560,20 @@ void wfmain::rigConnections()
connect(this, SIGNAL(getMicGain()), rig, SLOT(getMicGain()));
connect(this, SIGNAL(getSpectrumRefLevel()), rig, SLOT(getSpectrumRefLevel()));
connect(this, SIGNAL(getModInputLevel(rigInput)), rig, SLOT(getModInputLevel(rigInput)));
-
+ connect(this, SIGNAL(getPassband()), rig, SLOT(getPassband()));
+ connect(this, SIGNAL(getMonitorGain()), rig, SLOT(getMonitorGain()));
+ connect(this, SIGNAL(getVoxGain()), rig, SLOT(getVoxGain()));
+ connect(this, SIGNAL(getAntiVoxGain()), rig, SLOT(getAntiVoxGain()));
+ connect(this, SIGNAL(getNBLevel()), rig, SLOT(getNBLevel()));
+ connect(this, SIGNAL(getNRLevel()), rig, SLOT(getNRLevel()));
+ connect(this, SIGNAL(getCompLevel()), rig, SLOT(getCompLevel()));
+ connect(this, SIGNAL(getCwPitch()), rig, SLOT(getCwPitch()));
+ connect(this, SIGNAL(getDashRatio()), rig, SLOT(getDashRatio()));
+ connect(this, SIGNAL(getPskTone()), rig, SLOT(getPskTone()));
+ connect(this, SIGNAL(getRttyMark()), rig, SLOT(getRttyMark()));
+ connect(this, SIGNAL(getTone()), rig, SLOT(getTone()));
+ connect(this, SIGNAL(getTSQL()), rig, SLOT(getTSQL()));
+ connect(this, SIGNAL(getRptAccessMode()), rig, SLOT(getRptAccessMode()));
// Levels: Set:
connect(this, SIGNAL(setRfGain(unsigned char)), rig, SLOT(setRfGain(unsigned char)));
@@ -526,11 +584,13 @@ void wfmain::rigConnections()
connect(this, SIGNAL(setTPBFOuter(unsigned char)), rig, SLOT(setTPBFOuter(unsigned char)));
connect(this, SIGNAL(setTxPower(unsigned char)), rig, SLOT(setTxPower(unsigned char)));
connect(this, SIGNAL(setMicGain(unsigned char)), rig, SLOT(setMicGain(unsigned char)));
- connect(this, SIGNAL(setMonitorLevel(unsigned char)), rig, SLOT(setMonitorLevel(unsigned char)));
+ connect(this, SIGNAL(setMonitorGain(unsigned char)), rig, SLOT(setMonitorGain(unsigned char)));
connect(this, SIGNAL(setVoxGain(unsigned char)), rig, SLOT(setVoxGain(unsigned char)));
connect(this, SIGNAL(setAntiVoxGain(unsigned char)), rig, SLOT(setAntiVoxGain(unsigned char)));
connect(this, SIGNAL(setSpectrumRefLevel(int)), rig, SLOT(setSpectrumRefLevel(int)));
connect(this, SIGNAL(setModLevel(rigInput, unsigned char)), rig, SLOT(setModInputLevel(rigInput, unsigned char)));
+ connect(this, SIGNAL(setNBLevel(unsigned char)), rig, SLOT(setNBLevel(unsigned char)));
+ connect(this, SIGNAL(setNBLevel(unsigned char)), rig, SLOT(setNBLevel(unsigned char)));
// Levels: handle return on query:
connect(rig, SIGNAL(haveRfGain(unsigned char)), this, SLOT(receiveRfGain(unsigned char)));
@@ -1505,19 +1565,19 @@ void wfmain::setupKeyShortcuts()
connect(keyF12, SIGNAL(activated()), this, SLOT(shortcutF12()));
keyControlT = new QShortcut(this);
- keyControlT->setKey(Qt::CTRL + Qt::Key_T);
+ keyControlT->setKey(Qt::CTRL | Qt::Key_T);
connect(keyControlT, SIGNAL(activated()), this, SLOT(shortcutControlT()));
keyControlR = new QShortcut(this);
- keyControlR->setKey(Qt::CTRL + Qt::Key_R);
+ keyControlR->setKey(Qt::CTRL | Qt::Key_R);
connect(keyControlR, SIGNAL(activated()), this, SLOT(shortcutControlR()));
keyControlI = new QShortcut(this);
- keyControlI->setKey(Qt::CTRL + Qt::Key_I);
+ keyControlI->setKey(Qt::CTRL | Qt::Key_I);
connect(keyControlI, SIGNAL(activated()), this, SLOT(shortcutControlI()));
keyControlU = new QShortcut(this);
- keyControlU->setKey(Qt::CTRL + Qt::Key_U);
+ keyControlU->setKey(Qt::CTRL | Qt::Key_U);
connect(keyControlU, SIGNAL(activated()), this, SLOT(shortcutControlU()));
keyStar = new QShortcut(this);
@@ -1537,23 +1597,23 @@ void wfmain::setupKeyShortcuts()
connect(keyPlus, SIGNAL(activated()), this, SLOT(shortcutPlus()));
keyShiftMinus = new QShortcut(this);
- keyShiftMinus->setKey(Qt::SHIFT + Qt::Key_Minus);
+ keyShiftMinus->setKey(Qt::SHIFT | Qt::Key_Minus);
connect(keyShiftMinus, SIGNAL(activated()), this, SLOT(shortcutShiftMinus()));
keyShiftPlus = new QShortcut(this);
- keyShiftPlus->setKey(Qt::SHIFT + Qt::Key_Plus);
+ keyShiftPlus->setKey(Qt::SHIFT | Qt::Key_Plus);
connect(keyShiftPlus, SIGNAL(activated()), this, SLOT(shortcutShiftPlus()));
keyControlMinus = new QShortcut(this);
- keyControlMinus->setKey(Qt::CTRL + Qt::Key_Minus);
+ keyControlMinus->setKey(Qt::CTRL | Qt::Key_Minus);
connect(keyControlMinus, SIGNAL(activated()), this, SLOT(shortcutControlMinus()));
keyControlPlus = new QShortcut(this);
- keyControlPlus->setKey(Qt::CTRL + Qt::Key_Plus);
+ keyControlPlus->setKey(Qt::CTRL | Qt::Key_Plus);
connect(keyControlPlus, SIGNAL(activated()), this, SLOT(shortcutControlPlus()));
keyQuit = new QShortcut(this);
- keyQuit->setKey(Qt::CTRL + Qt::Key_Q);
+ keyQuit->setKey(Qt::CTRL | Qt::Key_Q);
connect(keyQuit, SIGNAL(activated()), this, SLOT(on_exitBtn_clicked()));
keyPageUp = new QShortcut(this);
@@ -1591,7 +1651,7 @@ void wfmain::setupKeyShortcuts()
});
keyShiftK = new QShortcut(this);
- keyShiftK->setKey(Qt::SHIFT + Qt::Key_K);
+ keyShiftK->setKey(Qt::SHIFT | Qt::Key_K);
connect(keyShiftK, &QShortcut::activated,
[=]() {
if (freqLock) return;
@@ -1600,7 +1660,7 @@ void wfmain::setupKeyShortcuts()
keyShiftJ = new QShortcut(this);
- keyShiftJ->setKey(Qt::SHIFT + Qt::Key_J);
+ keyShiftJ->setKey(Qt::SHIFT | Qt::Key_J);
connect(keyShiftJ, &QShortcut::activated,
[=]() {
if (freqLock) return;
@@ -1608,7 +1668,7 @@ void wfmain::setupKeyShortcuts()
});
keyControlK = new QShortcut(this);
- keyControlK->setKey(Qt::CTRL + Qt::Key_K);
+ keyControlK->setKey(Qt::CTRL | Qt::Key_K);
connect(keyControlK, &QShortcut::activated,
[=]() {
if (freqLock) return;
@@ -1617,7 +1677,7 @@ void wfmain::setupKeyShortcuts()
keyControlJ = new QShortcut(this);
- keyControlJ->setKey(Qt::CTRL + Qt::Key_J);
+ keyControlJ->setKey(Qt::CTRL | Qt::Key_J);
connect(keyControlJ, &QShortcut::activated,
[=]() {
if (freqLock) return;
@@ -1659,9 +1719,9 @@ void wfmain::setupKeyShortcuts()
keyDebug = new QShortcut(this);
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
- keyDebug->setKey(Qt::CTRL + Qt::SHIFT + Qt::Key_D);
+ keyDebug->setKey(Qt::CTRL | Qt::SHIFT | Qt::Key_D);
#else
- keyDebug->setKey(Qt::CTRL + Qt::Key_D);
+ keyDebug->setKey(Qt::CTRL | Qt::Key_D);
#endif
connect(keyDebug, SIGNAL(activated()), this, SLOT(on_debugBtn_clicked()));
}
@@ -1669,35 +1729,38 @@ void wfmain::setupKeyShortcuts()
void wfmain::setupUsbControllerDevice()
{
#if defined (USB_CONTROLLER)
+
+ if (usbWindow == Q_NULLPTR) {
+ usbWindow = new controllerSetup();
+ }
+
usbControllerDev = new usbController();
usbControllerThread = new QThread(this);
+ usbControllerThread->setObjectName("usb()");
usbControllerDev->moveToThread(usbControllerThread);
connect(usbControllerThread, SIGNAL(started()), usbControllerDev, SLOT(run()));
connect(usbControllerThread, SIGNAL(finished()), usbControllerDev, SLOT(deleteLater()));
+ connect(usbControllerThread, SIGNAL(finished()), usbWindow, SLOT(deleteLater())); // Delete window when controller is deleted
connect(usbControllerDev, SIGNAL(sendJog(int)), this, SLOT(changeFrequency(int)));
- connect(usbControllerDev, SIGNAL(doShuttle(bool, unsigned char)), this, SLOT(doShuttle(bool, unsigned char)));
+ connect(usbControllerDev, SIGNAL(doShuttle(bool,unsigned char)), this, SLOT(doShuttle(bool,unsigned char)));
connect(usbControllerDev, SIGNAL(button(const COMMAND*)), this, SLOT(buttonControl(const COMMAND*)));
connect(usbControllerDev, SIGNAL(setBand(int)), this, SLOT(setBand(int)));
- connect(usbControllerDev, SIGNAL(newDevice(unsigned char, QVector*, QVector*, QVector*, QMutex*)), shut, SLOT(newDevice(unsigned char, QVector*, QVector*, QVector*,QMutex*)));
+ connect(usbControllerDev, SIGNAL(removeDevice(USBDEVICE*)), usbWindow, SLOT(removeDevice(USBDEVICE*)));
+ connect(usbControllerDev, SIGNAL(initUI(usbDevMap*, QVector*, QVector*, QVector*, QMutex*)), usbWindow, SLOT(init(usbDevMap*, QVector*, QVector*, QVector*, QMutex*)));
+ connect(usbControllerDev, SIGNAL(changePage(USBDEVICE*,int)), usbWindow, SLOT(pageChanged(USBDEVICE*,int)));
+ connect(usbControllerDev, SIGNAL(setConnected(USBDEVICE*)), usbWindow, SLOT(setConnected(USBDEVICE*)));
+ connect(usbControllerDev, SIGNAL(newDevice(USBDEVICE*)), usbWindow, SLOT(newDevice(USBDEVICE*)));
usbControllerThread->start(QThread::LowestPriority);
- connect(this, SIGNAL(sendUsbControllerCommands(QVector*)), usbControllerDev, SLOT(receiveCommands(QVector*)));
- connect(this, SIGNAL(sendUsbControllerButtons(QVector*)), usbControllerDev, SLOT(receiveButtons(QVector*)));
- connect(this, SIGNAL(sendUsbControllerKnobs(QVector*)), usbControllerDev, SLOT(receiveKnobs(QVector*)));
- connect(shut, SIGNAL(sendSensitivity(int)), usbControllerDev, SLOT(receiveSensitivity(int)));
- connect(shut, SIGNAL(sendSensitivity(int)), this, SLOT(receiveUsbSensitivity(int)));
- connect(usbControllerDev, SIGNAL(sendSensitivity(int)), shut, SLOT(receiveSensitivity(int)));
- connect(shut, SIGNAL(programButton(quint8, QString)), usbControllerDev, SLOT(programButton(quint8, QString)));
- connect(shut, SIGNAL(programBrightness(quint8)), usbControllerDev, SLOT(programBrightness(quint8)));
- connect(shut, SIGNAL(programOrientation(quint8)), usbControllerDev, SLOT(programOrientation(quint8)));
- connect(shut, SIGNAL(programSpeed(quint8)), usbControllerDev, SLOT(programSpeed(quint8)));
- connect(shut, SIGNAL(programWheelColour(quint8, quint8, quint8)), usbControllerDev, SLOT(programWheelColour(quint8, quint8, quint8)));
- connect(shut, SIGNAL(programOverlay(quint8, QString)), usbControllerDev, SLOT(programOverlay(quint8, QString)));
- connect(shut, SIGNAL(programTimeout(quint8)), usbControllerDev, SLOT(programTimeout(quint8)));
- connect(shut, SIGNAL(updateSettings(quint8, quint8, quint8, quint8, QColor)), this, SLOT(receiveUsbSettings(quint8, quint8, quint8, quint8, QColor)));
- connect(this, SIGNAL(setPTT(bool)), usbControllerDev, SLOT(receivePTTStatus(bool)));
- connect(this, SIGNAL(initUsbController(int, QMutex*)), usbControllerDev, SLOT(init(int, QMutex*)));
- connect(this, SIGNAL(initUsbDefaults(quint8, quint8, quint8, quint8, QColor)), shut, SLOT(setDefaults(quint8, quint8, quint8, quint8, QColor)));
+ connect(usbWindow, SIGNAL(sendRequest(USBDEVICE*, usbFeatureType, int, QString, QImage*, QColor *)), usbControllerDev, SLOT(sendRequest(USBDEVICE*, usbFeatureType, int, QString, QImage*, QColor *)));
+ connect(this, SIGNAL(sendControllerRequest(USBDEVICE*, usbFeatureType, int, QString, QImage*, QColor *)), usbControllerDev, SLOT(sendRequest(USBDEVICE*, usbFeatureType, int, QString, QImage*, QColor *)));
+ connect(usbWindow, SIGNAL(programPages(USBDEVICE*,int)), usbControllerDev, SLOT(programPages(USBDEVICE*,int)));
+ connect(usbWindow, SIGNAL(programDisable(USBDEVICE*,bool)), usbControllerDev, SLOT(programDisable(USBDEVICE*,bool)));
+ connect(this, SIGNAL(sendLevel(cmds,unsigned char)), usbControllerDev, SLOT(receiveLevel(cmds,unsigned char)));
+ connect(this, SIGNAL(initUsbController(QMutex*,usbDevMap*,QVector*,QVector*)), usbControllerDev, SLOT(init(QMutex*,usbDevMap*,QVector*,QVector*)));
+ connect(this, SIGNAL(usbHotplug()), usbControllerDev, SLOT(run()));
+ connect(usbWindow, SIGNAL(backup(USBDEVICE*,QString)), usbControllerDev, SLOT(backupController(USBDEVICE*,QString)));
+ connect(usbWindow, SIGNAL(restore(USBDEVICE*,QString)), usbControllerDev, SLOT(restoreController(USBDEVICE*,QString)));
#endif
}
@@ -1705,7 +1768,6 @@ void wfmain::setupUsbControllerDevice()
void wfmain::pttToggle(bool status)
{
// is it enabled?
-
if (!ui->pttEnableChk->isChecked())
{
showStatusBarText("PTT is disabled, not sending command. Change under Settings tab.");
@@ -1742,6 +1804,7 @@ void wfmain::doShuttle(bool up, unsigned char level)
void wfmain::buttonControl(const COMMAND* cmd)
{
+ qDebug(logUsbControl()) << QString("executing command: %0 (%1) suffix:%2 value:%3" ).arg(cmd->text).arg(cmd->command).arg(cmd->suffix).arg(cmd->value);
switch (cmd->command) {
case cmdGetBandStackReg:
issueCmd((cmds)cmd->command, cmd->band);
@@ -1841,10 +1904,36 @@ void wfmain::buttonControl(const COMMAND* cmd)
ui->scopeBWCombo->setCurrentIndex(ui->scopeBWCombo->count() - 1);
}
break;
+ case cmdSetFreq:
+ {
+ if (freqLock) break;
+ freqt f;
+ if (cmd->suffix) {
+ f.Hz = roundFrequencyWithStep(freqb.Hz, cmd->value, tsWfScrollHz);
+ } else {
+ f.Hz = roundFrequencyWithStep(freq.Hz, cmd->value, tsWfScrollHz);
+ }
+ f.MHzDouble = f.Hz / (double)1E6;
+ f.VFO=(selVFO_t)cmd->suffix;
+ issueCmdUniquePriority((cmds)cmd->command, f);
+ if (!cmd->suffix) {
+ freq = f;
+ ui->freqLabel->setText(QString("%1").arg(f.MHzDouble, 0, 'f'));
+ } else {
+ freqb = f;
+ }
+ break;
+ }
default:
+ qInfo(logUsbControl()) << "Command" << cmd->command << "Suffix" << cmd->suffix;
issueCmdUniquePriority((cmds)cmd->command, cmd->suffix);
break;
}
+
+ // Make sure we get status quickly
+ if (cmd->getCommand != cmdNone) {
+ issueDelayedCommand((cmds)cmd->getCommand);
+ }
}
void wfmain::stepUp()
@@ -1878,6 +1967,7 @@ void wfmain::setDefPrefs()
defPrefs.currentColorPresetNumber = 0;
defPrefs.underlayMode = underlayNone;
defPrefs.underlayBufferSize = 64;
+ defPrefs.wfEnable = 2;
defPrefs.wfAntiAlias = false;
defPrefs.wfInterpolate = true;
defPrefs.stylesheetPath = QString("qdarkstyle/style.qss");
@@ -1904,12 +1994,6 @@ void wfmain::setDefPrefs()
defPrefs.waterfallFormat = 0;
defPrefs.audioSystem = qtAudio;
defPrefs.enableUSBControllers = false;
- defPrefs.usbSensitivity = 1;
- defPrefs.usbSpeed = 3;
- defPrefs.usbTimeout = 30;
- defPrefs.usbBrightness = 3;
- defPrefs.usbOrientation = 3;
- defPrefs.usbColor = Qt::white;
udpDefPrefs.ipAddress = QString("");
udpDefPrefs.controlLANPort = 50001;
@@ -1947,6 +2031,8 @@ void wfmain::loadSettings()
settings->beginGroup("Interface");
prefs.useFullScreen = settings->value("UseFullScreen", defPrefs.useFullScreen).toBool();
prefs.useSystemTheme = settings->value("UseSystemTheme", defPrefs.useSystemTheme).toBool();
+ prefs.wfEnable = settings->value("WFEnable", defPrefs.wfEnable).toInt();
+ ui->scopeEnableWFBtn->setCheckState(Qt::CheckState(prefs.wfEnable));
prefs.wftheme = settings->value("WFTheme", defPrefs.wftheme).toInt();
prefs.plotFloor = settings->value("plotFloor", defPrefs.plotFloor).toInt();
prefs.plotCeiling = settings->value("plotCeiling", defPrefs.plotCeiling).toInt();
@@ -2459,64 +2545,47 @@ void wfmain::loadSettings()
settings->beginGroup("USB");
/* Load USB buttons*/
prefs.enableUSBControllers = settings->value("EnableUSBControllers", defPrefs.enableUSBControllers).toBool();
- prefs.usbSensitivity = settings->value("USBSensitivity", defPrefs.usbSensitivity).toInt();
ui->enableUsbChk->blockSignals(true);
ui->enableUsbChk->setChecked(prefs.enableUSBControllers);
ui->enableUsbChk->blockSignals(false);
ui->usbControllerBtn->setEnabled(prefs.enableUSBControllers);
- ui->usbButtonsResetBtn->setEnabled(prefs.enableUSBControllers);
- ui->usbCommandsResetBtn->setEnabled(prefs.enableUSBControllers);
+ ui->usbControllersResetBtn->setEnabled(prefs.enableUSBControllers);
ui->usbResetLbl->setVisible(prefs.enableUSBControllers);
-
- prefs.usbBrightness = (quint8)settings->value("USBBrightness", defPrefs.usbBrightness).toInt();
- prefs.usbOrientation = (quint8)settings->value("USBOrientation", defPrefs.usbOrientation).toInt();
- prefs.usbSpeed = (quint8)settings->value("USBSpeed", defPrefs.usbSpeed).toInt();
- prefs.usbTimeout = (quint8)settings->value("USBBTimeout", defPrefs.usbTimeout).toInt();
- prefs.usbColor.setNamedColor(settings->value("USBColor", defPrefs.usbColor.name(QColor::HexArgb)).toString());
/*Ensure that no operations on the usb commands/buttons/knobs take place*/
QMutexLocker locker(&usbMutex);
- if (prefs.enableUSBControllers) {
- // Setup USB Controller
- setupUsbControllerDevice();
- emit initUsbController(prefs.usbSensitivity, &usbMutex);
- emit sendUsbControllerCommands(&usbCommands);
- emit sendUsbControllerButtons(&usbButtons);
- emit sendUsbControllerKnobs(&usbKnobs);
- emit initUsbDefaults(prefs.usbBrightness, prefs.usbOrientation, prefs.usbSpeed, prefs.usbTimeout, prefs.usbColor);
- }
-
- int numCommands = settings->beginReadArray("Commands");
- // This is the last time the commands were changed (v1.58)
- if (numCommands == 0 || priorVersionFloat < 1.58) {
+ int numControllers = settings->beginReadArray("Controllers");
+ if (numControllers == 0) {
settings->endArray();
- // We have no buttons so create defaults
- resetUsbCommands();
}
else {
- for (int nc = 0; nc < numCommands; nc++)
+ usbDevices.clear();
+ for (int nc = 0; nc < numControllers; nc++)
{
settings->setArrayIndex(nc);
- COMMAND comm;
- comm.index = settings->value("Num", 0).toInt();
- comm.text = settings->value("Text", "").toString();
- comm.command = settings->value("Command", 0).toInt();
- comm.band = (availableBands)settings->value("Band", 0).toInt();
- comm.mode = (mode_kind)settings->value("Mode", 0).toInt();
- comm.suffix = (unsigned char)settings->value("Suffix", 0).toInt();
- comm.cmdType = (usbCommandType)settings->value("CommandType", 0).toInt();
- usbCommands.append(comm);
+ USBDEVICE tempPrefs;
+ tempPrefs.path = settings->value("Path", "").toString();
+ tempPrefs.disabled = settings->value("Disabled", false).toBool();
+ tempPrefs.sensitivity = settings->value("Sensitivity", 1).toInt();
+ tempPrefs.pages = settings->value("Pages", 1).toInt();
+ tempPrefs.brightness = (quint8)settings->value("Brightness", 2).toInt();
+ tempPrefs.orientation = (quint8)settings->value("Orientation", 2).toInt();
+ tempPrefs.speed = (quint8)settings->value("Speed", 2).toInt();
+ tempPrefs.timeout = (quint8)settings->value("Timeout", 30).toInt();
+ tempPrefs.color.setNamedColor(settings->value("Color", QColor(Qt::white).name(QColor::HexArgb)).toString());
+ tempPrefs.lcd = (cmds)settings->value("LCD",0).toInt();
+
+ if (!tempPrefs.path.isEmpty()) {
+ usbDevices.insert(tempPrefs.path,tempPrefs);
+ }
}
settings->endArray();
}
int numButtons = settings->beginReadArray("Buttons");
- // This is the last time the buttons were changed, (v1.58)
- if (numButtons == 0 || priorVersionFloat < 1.58) {
+ if (numButtons == 0) {
settings->endArray();
- // We have no buttons so create defaults
- resetUsbButtons();
}
else {
usbButtons.clear();
@@ -2524,6 +2593,15 @@ void wfmain::loadSettings()
{
settings->setArrayIndex(nb);
BUTTON butt;
+ butt.path = settings->value("Path", "").toString();
+ butt.page = settings->value("Page", 1).toInt();
+ auto it = usbDevices.find(butt.path);
+ if (it==usbDevices.end())
+ {
+ qWarning(logUsbControl) << "Cannot find existing device while creating button, aborting!";
+ continue;
+ }
+ butt.parent = &it.value();
butt.dev = (usbDeviceType)settings->value("Dev", 0).toInt();
butt.num = settings->value("Num", 0).toInt();
butt.name = settings->value("Name", "").toString();
@@ -2531,33 +2609,29 @@ void wfmain::loadSettings()
settings->value("Top", 0).toInt(),
settings->value("Width", 0).toInt(),
settings->value("Height", 0).toInt());
- butt.textColour = QColor((settings->value("Colour", "Green").toString()));
-
- QString on = settings->value("OnCommand", "None").toString();
- QString off = settings->value("OffCommand", "None").toString();
-
- QVector::iterator usbc = usbCommands.begin();
-
- while (usbc != usbCommands.end())
- {
- if (on == usbc->text)
- butt.onCommand = usbc;
- if (off == usbc->text)
- butt.offCommand = usbc;
- ++usbc;
+ butt.textColour.setNamedColor(settings->value("Colour", QColor(Qt::white).name(QColor::HexArgb)).toString());
+ butt.backgroundOn.setNamedColor(settings->value("BackgroundOn", QColor(Qt::lightGray).name(QColor::HexArgb)).toString());
+ butt.backgroundOff.setNamedColor(settings->value("BackgroundOff", QColor(Qt::blue).name(QColor::HexArgb)).toString());
+ butt.toggle = settings->value("Toggle", false).toBool();
+#if (QT_VERSION > QT_VERSION_CHECK(6,0,0))
+ if (settings->value("Icon",NULL) != NULL) {
+ butt.icon = new QImage(settings->value("Icon",NULL).value());
+ butt.iconName = settings->value("IconName", "").toString();
}
- usbButtons.append(butt);
-
+#endif
+ butt.on = settings->value("OnCommand", "None").toString();
+ butt.off = settings->value("OffCommand", "None").toString();
+ butt.graphics = settings->value("Graphics", false).toBool();
+ butt.led = settings->value("Led", 0).toInt();
+ if (!butt.path.isEmpty())
+ usbButtons.append(butt);
}
settings->endArray();
}
int numKnobs = settings->beginReadArray("Knobs");
- // This is the last time the knobs were changed, (v1.58)
- if (numKnobs == 0 || priorVersionFloat < 1.58) {
+ if (numKnobs == 0) {
settings->endArray();
- // We have no knobs so create defaults
- resetUsbKnobs();
}
else {
usbKnobs.clear();
@@ -2565,6 +2639,15 @@ void wfmain::loadSettings()
{
settings->setArrayIndex(nk);
KNOB kb;
+ kb.path = settings->value("Path", "").toString();
+ auto it = usbDevices.find(kb.path);
+ if (it==usbDevices.end())
+ {
+ qWarning(logUsbControl) << "Cannot find existing device while creating knob, aborting!";
+ continue;
+ }
+ kb.parent = &it.value();
+ kb.page = settings->value("Page", 1).toInt();
kb.dev = (usbDeviceType)settings->value("Dev", 0).toInt();
kb.num = settings->value("Num", 0).toInt();
kb.name = settings->value("Name", "").toString();
@@ -2574,23 +2657,22 @@ void wfmain::loadSettings()
settings->value("Height", 0).toInt());
kb.textColour = QColor((settings->value("Colour", "Green").toString()));
- QString cmd = settings->value("Command", "None").toString();
-
- QVector::iterator usbc = usbCommands.begin();
-
- while (usbc != usbCommands.end())
- {
- if (cmd == usbc->text) {
- kb.command = usbc;
- }
- ++usbc;
- }
- usbKnobs.append(kb);
+ kb.cmd = settings->value("Command", "None").toString();
+ if (!kb.path.isEmpty())
+ usbKnobs.append(kb);
}
settings->endArray();
}
settings->endGroup();
+
+ if (prefs.enableUSBControllers) {
+ // Setup USB Controller
+ setupUsbControllerDevice();
+ emit initUsbController(&usbMutex,&usbDevices,&usbButtons,&usbKnobs);
+ }
+
+
#endif
}
@@ -2790,6 +2872,7 @@ void wfmain::saveSettings()
settings->beginGroup("Interface");
settings->setValue("UseFullScreen", prefs.useFullScreen);
settings->setValue("UseSystemTheme", prefs.useSystemTheme);
+ settings->setValue("WFEnable", prefs.wfEnable);
settings->setValue("DrawPeaks", prefs.drawPeaks);
settings->setValue("underlayMode", prefs.underlayMode);
settings->setValue("underlayBufferSize", prefs.underlayBufferSize);
@@ -2990,43 +3073,85 @@ void wfmain::saveSettings()
#if defined(USB_CONTROLLER)
settings->beginGroup("USB");
- // Store USB Controller
+
settings->setValue("EnableUSBControllers", prefs.enableUSBControllers);
- settings->setValue("USBSensitivity", prefs.usbSensitivity);
-
- settings->setValue("USBBrightness", prefs.usbBrightness);
- settings->setValue("USBOrientation", prefs.usbOrientation);
- settings->setValue("USBSpeed", prefs.usbSpeed);
- settings->setValue("USBTimeout", prefs.usbTimeout);
- settings->setValue("USBColor", prefs.usbColor.name(QColor::HexArgb));
QMutexLocker locker(&usbMutex);
+
+ // Store USB Controller
+
+ settings->remove("Controllers");
+ settings->beginWriteArray("Controllers");
+ int nc=0;
+
+ auto it = usbDevices.begin();
+ while (it != usbDevices.end())
+ {
+ auto dev = &it.value();
+ settings->setArrayIndex(nc);
+
+ settings->setValue("Model", dev->product);
+ settings->setValue("Path", dev->path);
+ settings->setValue("Disabled", dev->disabled);
+ settings->setValue("Sensitivity", dev->sensitivity);
+ settings->setValue("Brightness", dev->brightness);
+ settings->setValue("Orientation", dev->orientation);
+ settings->setValue("Speed", dev->speed);
+ settings->setValue("Timeout", dev->timeout);
+ settings->setValue("Pages", dev->pages);
+ settings->setValue("Color", dev->color.name(QColor::HexArgb));
+ settings->setValue("LCD", dev->lcd);
+
+ ++it;
+ ++nc;
+ }
+ settings->endArray();
+
+
+ settings->remove("Buttons");
settings->beginWriteArray("Buttons");
for (int nb = 0; nb < usbButtons.count(); nb++)
{
settings->setArrayIndex(nb);
+ settings->setValue("Page", usbButtons[nb].page);
settings->setValue("Dev", usbButtons[nb].dev);
settings->setValue("Num", usbButtons[nb].num);
+ settings->setValue("Path", usbButtons[nb].path);
settings->setValue("Name", usbButtons[nb].name);
settings->setValue("Left", usbButtons[nb].pos.left());
settings->setValue("Top", usbButtons[nb].pos.top());
settings->setValue("Width", usbButtons[nb].pos.width());
settings->setValue("Height", usbButtons[nb].pos.height());
- settings->setValue("Colour", usbButtons[nb].textColour.name());
+ settings->setValue("Colour", usbButtons[nb].textColour.name(QColor::HexArgb));
+ settings->setValue("BackgroundOn", usbButtons[nb].backgroundOn.name(QColor::HexArgb));
+ settings->setValue("BackgroundOff", usbButtons[nb].backgroundOff.name(QColor::HexArgb));
+ if (usbButtons[nb].icon != Q_NULLPTR) {
+ settings->setValue("Icon", *usbButtons[nb].icon);
+ settings->setValue("IconName", usbButtons[nb].iconName);
+ }
+ settings->setValue("Toggle", usbButtons[nb].toggle);
+
if (usbButtons[nb].onCommand != Q_NULLPTR)
settings->setValue("OnCommand", usbButtons[nb].onCommand->text);
if (usbButtons[nb].offCommand != Q_NULLPTR)
settings->setValue("OffCommand", usbButtons[nb].offCommand->text);
+ settings->setValue("Graphics",usbButtons[nb].graphics);
+ if (usbButtons[nb].led) {
+ settings->setValue("Led", usbButtons[nb].led);
+ }
}
settings->endArray();
+ settings->remove("Knobs");
settings->beginWriteArray("Knobs");
for (int nk = 0; nk < usbKnobs.count(); nk++)
{
settings->setArrayIndex(nk);
+ settings->setValue("Page", usbKnobs[nk].page);
settings->setValue("Dev", usbKnobs[nk].dev);
settings->setValue("Num", usbKnobs[nk].num);
+ settings->setValue("Path", usbKnobs[nk].path);
settings->setValue("Left", usbKnobs[nk].pos.left());
settings->setValue("Top", usbKnobs[nk].pos.top());
settings->setValue("Width", usbKnobs[nk].pos.width());
@@ -3038,22 +3163,6 @@ void wfmain::saveSettings()
settings->endArray();
- settings->beginWriteArray("Commands");
- for (int nc = 0; nc < usbCommands.count(); nc++)
- {
- settings->setArrayIndex(nc);
-
- settings->setValue("Num", usbCommands[nc].index);
- settings->setValue("Text", usbCommands[nc].text);
- settings->setValue("Command", usbCommands[nc].command);
- settings->setValue("Band", usbCommands[nc].band);
- settings->setValue("Mode", usbCommands[nc].mode);
- settings->setValue("Suffix", usbCommands[nc].suffix);
- settings->setValue("CommandType", usbCommands[nc].cmdType);
- }
-
- settings->endArray();
-
settings->endGroup();
#endif
@@ -3079,6 +3188,7 @@ void wfmain::showHideSpectrum(bool show)
ui->scopeBWCombo->setVisible(show);
ui->scopeEdgeCombo->setVisible(show);
ui->scopeEnableWFBtn->setVisible(show);
+ ui->scopeEnableWFBtn->setTristate(true);
ui->scopeRefLevelSlider->setEnabled(show);
ui->wfLengthSlider->setEnabled(show);
ui->wfthemeCombo->setVisible(show);
@@ -3621,6 +3731,13 @@ void wfmain:: getInitialRigState()
issueDelayedCommand(cmdGetSpectrumMode);
issueDelayedCommand(cmdGetSpectrumSpan);
issueDelayedCommand(cmdGetPassband);
+ if(ui->scopeEnableWFBtn->checkState() != Qt::Unchecked)
+ {
+ issueDelayedCommand(cmdSpecOn);
+ } else {
+ issueDelayedCommand(cmdSpecOff);
+ }
+
}
issueDelayedCommand(cmdNone);
@@ -3798,7 +3915,7 @@ void wfmain::doCmd(commandtype cmddata)
{
case cmdSetFreq:
{
- lastFreqCmdTime_ms = QDateTime::currentMSecsSinceEpoch();
+ lastFreqCmdTime_ms = QDateTime::currentMSecsSinceEpoch();
freqt f = (*std::static_pointer_cast(data));
emit setFrequency(f.VFO,f);
break;
@@ -4040,6 +4157,67 @@ void wfmain::doCmd(commandtype cmddata)
emit setPassband(pass);
break;
}
+ case cmdSetMonitorGain:
+ {
+ quint16 gain = (*std::static_pointer_cast(data));
+ emit setMonitorGain(gain);
+ break;
+ }
+ case cmdSetVoxGain:
+ {
+ quint16 gain = (*std::static_pointer_cast(data));
+ emit setVoxGain(gain);
+ break;
+ }
+ case cmdSetAntiVoxGain:
+ {
+ quint16 gain = (*std::static_pointer_cast(data));
+ emit setAntiVoxGain(gain);
+ break;
+ }
+ case cmdSetNBLevel:
+ {
+ quint16 level = (*std::static_pointer_cast(data));
+ emit setNBLevel(level);
+ break;
+ }
+ case cmdSetNRLevel:
+ {
+ quint16 level = (*std::static_pointer_cast(data));
+ emit setNRLevel(level);
+ break;
+ }
+ case cmdSetMonitor:
+ {
+ bool en = (*std::static_pointer_cast(data));
+ emit setMonitor(en);
+ break;
+ }
+ case cmdSetVox:
+ {
+ bool en = (*std::static_pointer_cast(data));
+ emit setVox(en);
+ break;
+ }
+ case cmdSetComp:
+ {
+ bool en = (*std::static_pointer_cast(data));
+ emit setCompressor(en);
+ break;
+ }
+ case cmdSetNB:
+ {
+ bool en = (*std::static_pointer_cast(data));
+ emit setNB(en);
+ break;
+ }
+ case cmdSetNR:
+ {
+ bool en = (*std::static_pointer_cast(data));
+ emit setNR(en);
+ break;
+ }
+
default:
doCmd(cmd);
break;
@@ -4072,6 +4250,9 @@ void wfmain::doCmd(cmds cmd)
case cmdGetFreq:
emit getFrequency();
break;
+ case cmdGetFreqB:
+ emit getFrequency((unsigned char)1);
+ break;
case cmdGetMode:
emit getMode();
break;
@@ -4123,6 +4304,39 @@ void wfmain::doCmd(cmds cmd)
case cmdGetPassband:
emit getPassband();
break;
+ case cmdGetMonitor:
+ emit getMonitor();
+ break;
+ case cmdGetMonitorGain:
+ emit getMonitorGain();
+ break;
+ case cmdGetComp:
+ emit getCompressor();
+ break;
+ case cmdGetVox:
+ emit getVox();
+ break;
+ case cmdGetVoxGain:
+ emit getVoxGain();
+ break;
+ case cmdGetAntiVoxGain:
+ emit getAntiVoxGain();
+ break;
+ case cmdGetNB:
+ emit getNB();
+ break;
+ case cmdGetNBLevel:
+ emit getNBLevel();
+ break;
+ case cmdGetNR:
+ emit getNR();
+ break;
+ case cmdGetNRLevel:
+ emit getNRLevel();
+ break;
+ case cmdGetCompLevel:
+ emit getCompLevel();
+ break;
case cmdGetCwPitch:
emit getCwPitch();
break;
@@ -4802,6 +5016,7 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
if(usingLAN)
{
ui->afGainSlider->setValue(prefs.localAFgain);
+ emit sendLevel(cmdGetAfGain,prefs.localAFgain);
}
// Adding these here because clearly at this point we have valid
// rig comms. In the future, we should establish comms and then
@@ -4841,6 +5056,11 @@ void wfmain::initPeriodicCommands()
insertPeriodicCommand(cmdGetTxRxMeter, 128);
insertSlowPeriodicCommand(cmdGetFreq, 128);
+
+ if (rigCaps.hasVFOAB || rigCaps.hasVFOMS) {
+ insertSlowPeriodicCommand(cmdGetFreqB, 128);
+ }
+
insertSlowPeriodicCommand(cmdGetMode, 128);
if(rigCaps.hasTransmit)
insertSlowPeriodicCommand(cmdGetPTT, 128);
@@ -4870,7 +5090,6 @@ void wfmain::initPeriodicCommands()
insertPeriodicRapidCmdUnique(cmdGetTPBFOuter);
insertPeriodicRapidCmdUnique(cmdGetPassband);
}
-
}
void wfmain::insertPeriodicRapidCmd(cmds cmd)
@@ -4977,9 +5196,14 @@ void wfmain::receiveFreq(freqt freqStruct)
qint64 tnow_ms = QDateTime::currentMSecsSinceEpoch();
if(tnow_ms - lastFreqCmdTime_ms > delayedCommand->interval() * 2)
{
- ui->freqLabel->setText(QString("%1").arg(freqStruct.MHzDouble, 0, 'f'));
- freq = freqStruct;
- rpt->handleUpdateCurrentMainFrequency(freqStruct);
+ if (freqStruct.VFO == selVFO_t::activeVFO) {
+ ui->freqLabel->setText(QString("%1").arg(freqStruct.MHzDouble, 0, 'f'));
+ freq = freqStruct;
+ rpt->handleUpdateCurrentMainFrequency(freqStruct);
+ } else {
+ freqb = freqStruct;
+ }
+
} else {
qDebug(logSystem()) << "Rejecting stale frequency: " << freqStruct.Hz << " Hz, delta time ms = " << tnow_ms - lastFreqCmdTime_ms\
<< ", tnow_ms " << tnow_ms << ", last: " << lastFreqCmdTime_ms;
@@ -4988,6 +5212,8 @@ void wfmain::receiveFreq(freqt freqStruct)
void wfmain::receivePTTstatus(bool pttOn)
{
+ emit sendLevel(cmdGetPTT,pttOn);
+
// This is the only place where amTransmitting and the transmit button text should be changed:
if (pttOn && !amTransmitting)
{
@@ -5026,13 +5252,19 @@ void wfmain::changeTxBtn()
void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double endFreq)
{
+ if (ui->scopeEnableWFBtn->checkState()== Qt::PartiallyChecked)
+ {
+ return;
+ }
+
+
if(!haveRigCaps)
{
qDebug(logSystem()) << "Spectrum received, but RigID incomplete.";
return;
}
- QElapsedTimer performanceTimer;
+ //QElapsedTimer performanceTimer;
bool updateRange = false;
if((startFreq != oldLowerFreq) || (endFreq != oldUpperFreq))
@@ -5243,9 +5475,32 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e
wf->yAxis->setRange(0,wfLength - 1);
wf->xAxis->setRange(0, spectWidth-1);
wf->replot();
+
+#if defined (USB_CONTROLLER)
+ // Send to USB Controllers if requested
+ auto i = usbDevices.begin();
+ while (i != usbDevices.end())
+ {
+ if (i.value().connected && i.value().type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDWaterfall )
+ {
+ lcdImage = wf->toPixmap().toImage();
+ emit sendControllerRequest(&i.value(), usbFeatureType::featureLCD, 0, "", &lcdImage);
+ }
+ else if (i.value().connected && i.value().type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDSpectrum)
+ {
+ lcdImage = plot->toPixmap().toImage();
+ emit sendControllerRequest(&i.value(), usbFeatureType::featureLCD, 0, "", &lcdImage);
+ }
+ ++i;
+ }
+#endif
+
}
oldPlotFloor = plotFloor;
oldPlotCeiling = plotCeiling;
+
+
+
}
}
@@ -5681,14 +5936,17 @@ void wfmain::handlePlotScroll(QWheelEvent *we)
handleWFScroll(we);
}
-void wfmain::on_scopeEnableWFBtn_clicked(bool checked)
+void wfmain::on_scopeEnableWFBtn_stateChanged(int state)
{
- if(checked)
+ if (state == Qt::Unchecked)
{
- emit spectOutputEnable();
- } else {
- emit spectOutputDisable();
+ issueDelayedCommand(cmdSpecOff);
}
+ else
+ {
+ issueDelayedCommand(cmdSpecOn);
+ }
+ prefs.wfEnable = state;
}
@@ -6410,6 +6668,7 @@ void wfmain::on_afGainSlider_valueChanged(int value)
{
rxSetup.localAFgain = (unsigned char)(value);
prefs.localAFgain = (unsigned char)(value);
+ emit sendLevel(cmdGetAfGain,value);
}
}
@@ -6419,6 +6678,7 @@ void wfmain::receiveRfGain(unsigned char level)
ui->rfGainSlider->blockSignals(true);
ui->rfGainSlider->setValue(level);
ui->rfGainSlider->blockSignals(false);
+ emit sendLevel(cmdGetRxGain,level);
}
void wfmain::receiveAfGain(unsigned char level)
@@ -6427,26 +6687,31 @@ void wfmain::receiveAfGain(unsigned char level)
ui->afGainSlider->blockSignals(true);
ui->afGainSlider->setValue(level);
ui->afGainSlider->blockSignals(false);
+ emit sendLevel(cmdGetAfGain,level);
}
void wfmain::receiveSql(unsigned char level)
{
ui->sqlSlider->setValue(level);
+ emit sendLevel(cmdGetSql,level);
}
void wfmain::receiveIFShift(unsigned char level)
{
trxadj->updateIFShift(level);
+ emit sendLevel(cmdGetIFShift,level);
}
void wfmain::receiveTBPFInner(unsigned char level)
{
trxadj->updateTPBFInner(level);
+ emit sendLevel(cmdGetTPBFInner,level);
}
void wfmain::receiveTBPFOuter(unsigned char level)
{
trxadj->updateTPBFOuter(level);
+ emit sendLevel(cmdGetTPBFOuter,level);
}
void wfmain::on_tuneNowBtn_clicked()
@@ -6920,11 +7185,14 @@ void wfmain::statusFromSliderPercent(QString name, int rawValue)
void wfmain::receiveTxPower(unsigned char power)
{
changeSliderQuietly(ui->txPowerSlider, power);
+ emit sendLevel(cmdGetTxPower,power);
+
}
void wfmain::receiveMicGain(unsigned char gain)
{
processModLevel(inputMic, gain);
+ emit sendLevel(cmdGetMicGain,gain);
}
void wfmain::processModLevel(rigInput source, unsigned char level)
@@ -6968,6 +7236,7 @@ void wfmain::processModLevel(rigInput source, unsigned char level)
if(currentIn == source)
{
changeSliderQuietly(ui->micGainSlider, level);
+ emit sendLevel(cmdGetModLevel,level);
}
}
@@ -7050,6 +7319,7 @@ void wfmain::receiveCwPitch(unsigned char pitch) {
if (currentModeInfo.mk == modeCW || currentModeInfo.mk == modeCW_R) {
cwPitch = round((((600.0 / 255.0) * pitch) + 300) / 5.0) * 5.0;
passbandCenterFrequency = cwPitch / 2000000.0;
+ emit sendLevel(cmdGetCwPitch,pitch);
}
//qDebug() << "CW" << pitch << "Pitch" << cwPitch;
}
@@ -7069,6 +7339,7 @@ void wfmain::receiveTPBFInner(unsigned char level) {
pitch = (600.0 - cwPitch) / 1000000.0;
}
TPBFInner = round((tempVar + pitch) * 200000.0) / 200000.0; // Nearest 5Hz.
+ emit sendLevel(cmdGetTPBFInner,level);
//qDebug() << "Inner" << level << "TPBFInner" << TPBFInner;
}
@@ -7087,6 +7358,7 @@ void wfmain::receiveTPBFOuter(unsigned char level) {
pitch = (600.0 - cwPitch) / 1000000.0;
}
TPBFOuter = round((tempVar + pitch) * 200000.0) / 200000.0; // Nearest 5Hz.
+ emit sendLevel(cmdGetTPBFOuter,level);
//qDebug() << "Outer" << level << "TPBFOuter" << TPBFOuter;
}
@@ -7123,22 +7395,57 @@ void wfmain::receiveMeter(meterKind inMeter, unsigned char level)
void wfmain::receiveCompLevel(unsigned char compLevel)
{
- (void)compLevel;
+ emit sendLevel(cmdGetCompLevel,compLevel);
}
void wfmain::receiveMonitorGain(unsigned char monitorGain)
{
- (void)monitorGain;
+ emit sendLevel(cmdGetMonitorGain,monitorGain);
}
void wfmain::receiveVoxGain(unsigned char voxGain)
{
- (void)voxGain;
+ emit sendLevel(cmdGetVoxGain,voxGain);
}
void wfmain::receiveAntiVoxGain(unsigned char antiVoxGain)
{
- (void)antiVoxGain;
+ emit sendLevel(cmdGetAntiVoxGain,antiVoxGain);
+}
+
+void wfmain::receiveNBLevel(unsigned char level)
+{
+ emit sendLevel(cmdGetNBLevel,level);
+}
+
+void wfmain::receiveNRLevel(unsigned char level)
+{
+ emit sendLevel(cmdGetNRLevel,level);
+}
+
+void wfmain::receiveComp(bool en)
+{
+ emit sendLevel(cmdGetComp,en);
+}
+
+void wfmain::receiveMonitor(bool en)
+{
+ emit sendLevel(cmdGetMonitor,en);
+}
+
+void wfmain::receiveVox(bool en)
+{
+ emit sendLevel(cmdGetVox,en);
+}
+
+void wfmain::receiveNB(bool en)
+{
+ emit sendLevel(cmdGetNB,en);
+}
+
+void wfmain::receiveNR(bool en)
+{
+ emit sendLevel(cmdGetNR,en);
}
void wfmain::on_txPowerSlider_valueChanged(int value)
@@ -7490,7 +7797,7 @@ void wfmain::powerRigOn()
emit sendPowerOn();
delayedCommand->setInterval(3000); // 3 seconds
- if(ui->scopeEnableWFBtn->isChecked())
+ if(ui->scopeEnableWFBtn->checkState() != Qt::Unchecked)
{
issueDelayedCommand(cmdDispEnable);
issueDelayedCommand(cmdQueNormalSpeed);
@@ -7498,6 +7805,7 @@ void wfmain::powerRigOn()
issueDelayedCommand(cmdStartRegularPolling); // s-meter, etc
} else {
issueDelayedCommand(cmdQueNormalSpeed);
+ issueDelayedCommand(cmdSpecOff);
issueDelayedCommand(cmdStartRegularPolling); // s-meter, etc
}
delayedCommand->start();
@@ -9176,8 +9484,7 @@ void wfmain::on_enableUsbChk_clicked(bool checked)
{
prefs.enableUSBControllers = checked;
ui->usbControllerBtn->setEnabled(checked);
- ui->usbButtonsResetBtn->setEnabled(checked);
- ui->usbCommandsResetBtn->setEnabled(checked);
+ ui->usbControllersResetBtn->setEnabled(checked);
ui->usbResetLbl->setVisible(checked);
#if defined (USB_CONTROLLER)
@@ -9185,67 +9492,51 @@ void wfmain::on_enableUsbChk_clicked(bool checked)
usbControllerThread->quit();
usbControllerThread->wait();
usbControllerThread = Q_NULLPTR;
+ usbWindow = Q_NULLPTR;
}
+
if (checked) {
// Setup USB Controller
setupUsbControllerDevice();
- emit initUsbController(prefs.usbSensitivity, &usbMutex);
- emit sendUsbControllerCommands(&usbCommands);
- emit sendUsbControllerButtons(&usbButtons);
- emit sendUsbControllerKnobs(&usbKnobs);
- emit initUsbDefaults(prefs.usbBrightness, prefs.usbOrientation, prefs.usbSpeed, prefs.usbTimeout, prefs.usbColor);
- }
- else {
- if (shut != Q_NULLPTR) {
- if (shut->isVisible()) {
- shut->hide();
- }
- }
+ emit initUsbController(&usbMutex,&usbDevices,&usbButtons,&usbKnobs);
}
#endif
}
void wfmain::on_usbControllerBtn_clicked()
{
- if (shut != Q_NULLPTR) {
- if (shut->isVisible()) {
- shut->hide();
+ if (usbWindow != Q_NULLPTR) {
+ if (usbWindow->isVisible()) {
+ usbWindow->hide();
}
else {
- shut->show();
- shut->raise();
+ qInfo(logUsbControl()) << "Showing USB Controller window";
+ usbWindow->show();
+ usbWindow->raise();
}
}
}
-void wfmain::on_usbButtonsResetBtn_clicked()
+void wfmain::on_usbControllersResetBtn_clicked()
{
int ret = QMessageBox::warning(this, tr("wfview"),
- tr("Are you sure you wish to reset the USB buttons?"),
+ tr("Are you sure you wish to reset the USB controllers?"),
QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Cancel);
if (ret == QMessageBox::Ok) {
- qInfo(logUsbControl()) << "Resetting USB buttons to default values";
- resetUsbButtons();
- resetUsbKnobs();
- on_enableUsbChk_clicked(true); // Force disconnect/reconnect of USB controller.
+ qInfo(logUsbControl()) << "Resetting USB controllers to default values";
+ bool enabled = ui->enableUsbChk->isChecked();
+ if (enabled) on_enableUsbChk_clicked(false); // Force disconnect of USB controllers
+
+ usbButtons.clear();
+ usbKnobs.clear();
+ usbDevices.clear();
+
+ if (enabled) on_enableUsbChk_clicked(true); // Force connect of USB controllers
}
}
-void wfmain::on_usbCommandsResetBtn_clicked()
-{
- int ret = QMessageBox::warning(this, tr("wfview"),
- tr("Are you sure you wish to reset the USB commands?"),
- QMessageBox::Ok | QMessageBox::Cancel,
- QMessageBox::Cancel);
- if (ret == QMessageBox::Ok) {
- qInfo(logUsbControl()) << "Resetting USB commands to default values";
- resetUsbCommands();
- on_enableUsbChk_clicked(true); // Force disconnect/reconnect of USB controller.
- }
-
-}
void wfmain::on_autoPollBtn_clicked(bool checked)
{
@@ -9333,197 +9624,77 @@ void wfmain::on_cwButton_clicked()
cw->activateWindow();
}
-void wfmain::resetUsbButtons()
+#ifdef USB_HOTPLUG
+
+
+#ifdef Q_OS_WINDOWS
+bool wfmain::nativeEvent(const QByteArray& eventType, void* message, qintptr* result)
{
-#ifdef USB_CONTROLLER
- qInfo(logUsbControl) << "Resetting USB Buttons to defaults";
- usbButtons.clear();
+ Q_UNUSED(eventType);
+ Q_UNUSED(result);
- // ShuttleXpress
- usbButtons.append(BUTTON(shuttleXpress, 4, QRect(25, 199, 89, 169), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttleXpress, 5, QRect(101, 72, 83, 88), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttleXpress, 6, QRect(238, 26, 134, 69), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttleXpress, 7, QRect(452, 72, 77, 86), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttleXpress, 8, QRect(504, 199, 89, 169), Qt::red, &usbCommands[0], &usbCommands[0]));
+ if (QDateTime::currentMSecsSinceEpoch() > lastUsbNotify + 10)
+ {
+ static bool created = false;
- // ShuttlePro2
- usbButtons.append(BUTTON(shuttlePro2, 0, QRect(60, 66, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 1, QRect(114, 50, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 2, QRect(169, 47, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 3, QRect(225, 59, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 4, QRect(41, 132, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 5, QRect(91, 105, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 6, QRect(144, 93, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 7, QRect(204, 99, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 8, QRect(253, 124, 40, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 9, QRect(50, 270, 70, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 10, QRect(210, 270, 70, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 11, QRect(50, 335, 70, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 12, QRect(210, 335, 70, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 13, QRect(30, 195, 25, 80), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(shuttlePro2, 14, QRect(280, 195, 25, 80), Qt::red, &usbCommands[0], &usbCommands[0]));
+ MSG * msg = static_cast< MSG * > (message);
+ switch (msg->message)
+ {
+ case WM_PAINT:
+ {
+ if (!created) {
+ GUID InterfaceClassGuid = {0x745a17a0, 0x74d3, 0x11d0,{ 0xb6, 0xfe, 0x00, 0xa0, 0xc9, 0x0f, 0x57, 0xda}};
+ DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
+ ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
+ NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
+ NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+ NotificationFilter.dbcc_classguid = InterfaceClassGuid;
+ HWND hw = (HWND) this->effectiveWinId(); //Main window handle
+ RegisterDeviceNotification(hw,&NotificationFilter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES );
+ created = true;
+ }
+ break;
+ }
+ case WM_DEVICECHANGE:
+ {
+ switch (msg->wParam) {
+ case DBT_DEVICEARRIVAL:
+ case DBT_DEVICEREMOVECOMPLETE:
+ emit usbHotplug();
+ lastUsbNotify = QDateTime::currentMSecsSinceEpoch();
+ break;
+ case DBT_DEVNODES_CHANGED:
+ break;
+ default:
+ break;
+ }
- // RC28
- usbButtons.append(BUTTON(RC28, 0, QRect(52, 445, 238, 64), Qt::red, &usbCommands[1], &usbCommands[2])); // PTT On/OFF
- usbButtons.append(BUTTON(RC28, 1, QRect(52, 373, 98, 46), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(RC28, 2, QRect(193, 373, 98, 46), Qt::red, &usbCommands[0], &usbCommands[0]));
+ return true;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return false; // Process native events as normal
+}
- // Xbox Gamepad
- usbButtons.append(BUTTON(xBoxGamepad, "UP", QRect(256, 229, 50, 50), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "DOWN", QRect(256, 316, 50, 50), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "LEFT", QRect(203, 273, 50, 50), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "RIGHT", QRect(303, 273, 50, 50), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "SELECT", QRect(302, 160, 40, 40), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "START", QRect(412, 163, 40, 40), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "Y", QRect(534, 104, 53, 53), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "X", QRect(485, 152, 53, 53), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "B", QRect(590, 152, 53, 53), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "A", QRect(534, 202, 53, 53), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "L1", QRect(123, 40, 70, 45), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "R1", QRect(562, 40, 70, 45), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "LEFTX", QRect(143, 119, 83, 35), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "LEFTY", QRect(162, 132, 50, 57), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "RIGHTX", QRect(430, 298, 83, 35), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(xBoxGamepad, "RIGHTY", QRect(453, 233, 50, 57), Qt::red, &usbCommands[0], &usbCommands[0]));
-
- // eCoder
- usbButtons.append(BUTTON(eCoderPlus, 1, QRect(87, 190, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 2, QRect(168, 190, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 3, QRect(249, 190, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 4, QRect(329, 190, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 5, QRect(410, 190, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 6, QRect(87, 270, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 7, QRect(168, 270, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 8, QRect(249, 270, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 9, QRect(329, 270, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 10, QRect(410, 270, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 11, QRect(87, 351, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 12, QRect(410, 351, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 13, QRect(87, 512, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 14, QRect(410, 512, 55, 55), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 16, QRect(128, 104, 45, 47), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 17, QRect(256, 104, 45, 47), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 18, QRect(380, 104, 45, 47), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 19, QRect(124, 2, 55, 30), Qt::red, &usbCommands[1], &usbCommands[2]));
- usbButtons.append(BUTTON(eCoderPlus, 20, QRect(290, 2, 55, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(eCoderPlus, 21, QRect(404, 2, 55, 30), Qt::red, &usbCommands[0], &usbCommands[0]));
-
- // QuickKeys
- usbButtons.append(BUTTON(QuickKeys, 0, QRect(77, 204, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 1, QRect(77, 276, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 2, QRect(77, 348, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 3, QRect(77, 422, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 4, QRect(230, 204, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 5, QRect(230, 276, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 6, QRect(230, 348, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 7, QRect(230, 422, 39, 63), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 8, QRect(143, 515, 55, 40), Qt::white, &usbCommands[0], &usbCommands[0]));
- usbButtons.append(BUTTON(QuickKeys, 9, QRect(139, 68, 65, 65), Qt::white, &usbCommands[0], &usbCommands[0]));
-
- emit sendUsbControllerButtons(&usbButtons);
+#elif defined(Q_OS_LINUX)
+void wfmain::uDevEvent()
+{
+ udev_device *dev = udev_monitor_receive_device(uDevMonitor);
+ if (dev)
+ {
+ const char* action = udev_device_get_action(dev);
+ if (action && strcmp(action, "add") == 0 && QDateTime::currentMSecsSinceEpoch() > lastUsbNotify + 10)
+ {
+ emit usbHotplug();
+ lastUsbNotify = QDateTime::currentMSecsSinceEpoch();
+ }
+ udev_device_unref(dev);
+ }
+}
#endif
-}
-
-void wfmain::resetUsbKnobs()
-{
-#ifdef USB_CONTROLLER
- qInfo(logUsbControl) << "Resetting USB Knobs to defaults";
- usbKnobs.clear();
- // eCoder
- usbKnobs.append(KNOB(eCoderPlus, 1, QRect(120, 153, 72, 27), Qt::green, &usbCommands[0]));
- usbKnobs.append(KNOB(eCoderPlus, 2, QRect(242, 153, 72, 27), Qt::green, &usbCommands[0]));
- usbKnobs.append(KNOB(eCoderPlus, 3, QRect(362, 153, 72, 27), Qt::green, &usbCommands[0]));
- emit sendUsbControllerKnobs(&usbKnobs);
-
#endif
-}
-void wfmain::resetUsbCommands()
-{
-#ifdef USB_CONTROLLER
- qInfo(logUsbControl) << "Resetting USB Commands to defaults";
- usbCommands.clear();
- int num = 0;
- usbCommands.append(COMMAND(num++, "None", commandButton, cmdNone, 0x0));
- usbCommands.append(COMMAND(num++, "PTT On", commandButton, cmdSetPTT, 0x1));
- usbCommands.append(COMMAND(num++, "PTT Off", commandButton, cmdSetPTT, 0x0));
- usbCommands.append(COMMAND(num++, "PTT Toggle", commandButton, cmdPTTToggle, 0x0));
- usbCommands.append(COMMAND(num++, "Tune", commandButton, cmdStartATU, 0x0));
- usbCommands.append(COMMAND(num++, "Step+", commandButton, cmdSetStepUp, 0x0));
- usbCommands.append(COMMAND(num++, "Step-", commandButton, cmdSetStepDown, 0x0));
- usbCommands.append(COMMAND(num++, "Span+", commandButton, cmdSetSpanUp, 0x0));
- usbCommands.append(COMMAND(num++, "Span-", commandButton, cmdSetSpanDown, 0x0));
- usbCommands.append(COMMAND(num++, "Mode+", commandButton, cmdSetModeUp, 0x0));
- usbCommands.append(COMMAND(num++, "Mode-", commandButton, cmdSetModeDown, 0x0));
- usbCommands.append(COMMAND(num++, "Mode LSB", commandButton, cmdSetMode, modeLSB));
- usbCommands.append(COMMAND(num++, "Mode USB", commandButton, cmdSetMode, modeUSB));
- usbCommands.append(COMMAND(num++, "Mode LSBD", commandButton, cmdSetMode, modeLSB_D));
- usbCommands.append(COMMAND(num++, "Mode USBD", commandButton, cmdSetMode, modeUSB_D));
- usbCommands.append(COMMAND(num++, "Mode CW", commandButton, cmdSetMode, modeCW));
- usbCommands.append(COMMAND(num++, "Mode CWR", commandButton, cmdSetMode, modeCW_R));
- usbCommands.append(COMMAND(num++, "Mode FM", commandButton, cmdSetMode, modeFM));
- usbCommands.append(COMMAND(num++, "Mode AM", commandButton, cmdSetMode, modeAM));
- usbCommands.append(COMMAND(num++, "Mode RTTY", commandButton, cmdSetMode, modeRTTY));
- usbCommands.append(COMMAND(num++, "Mode RTTYR", commandButton, cmdSetMode, modeRTTY_R));
- usbCommands.append(COMMAND(num++, "Mode PSK", commandButton, cmdSetMode, modePSK));
- usbCommands.append(COMMAND(num++, "Mode PSKR", commandButton, cmdSetMode, modePSK_R));
- usbCommands.append(COMMAND(num++, "Mode DV", commandButton, cmdSetMode, modeDV));
- usbCommands.append(COMMAND(num++, "Mode DD", commandButton, cmdSetMode, modeDD));
- usbCommands.append(COMMAND(num++, "Band+", commandButton, cmdSetBandUp, 0x0));
- usbCommands.append(COMMAND(num++, "Band-", commandButton, cmdSetBandDown, 0x0));
- usbCommands.append(COMMAND(num++, "Band 23cm", commandButton, cmdGetBandStackReg, band23cm));
- usbCommands.append(COMMAND(num++, "Band 70cm", commandButton, cmdGetBandStackReg, band70cm));
- usbCommands.append(COMMAND(num++, "Band 2m", commandButton, cmdGetBandStackReg, band2m));
- usbCommands.append(COMMAND(num++, "Band AIR", commandButton, cmdGetBandStackReg, bandAir));
- usbCommands.append(COMMAND(num++, "Band WFM", commandButton, cmdGetBandStackReg, bandWFM));
- usbCommands.append(COMMAND(num++, "Band 4m", commandButton, cmdGetBandStackReg, band4m));
- usbCommands.append(COMMAND(num++, "Band 6m", commandButton, cmdGetBandStackReg, band6m));
- usbCommands.append(COMMAND(num++, "Band 10m", commandButton, cmdGetBandStackReg, band10m));
- usbCommands.append(COMMAND(num++, "Band 12m", commandButton, cmdGetBandStackReg, band12m));
- usbCommands.append(COMMAND(num++, "Band 15m", commandButton, cmdGetBandStackReg, band15m));
- usbCommands.append(COMMAND(num++, "Band 17m", commandButton, cmdGetBandStackReg, band17m));
- usbCommands.append(COMMAND(num++, "Band 20m", commandButton, cmdGetBandStackReg, band20m));
- usbCommands.append(COMMAND(num++, "Band 30m", commandButton, cmdGetBandStackReg, band30m));
- usbCommands.append(COMMAND(num++, "Band 40m", commandButton, cmdGetBandStackReg, band40m));
- usbCommands.append(COMMAND(num++, "Band 60m", commandButton, cmdGetBandStackReg, band60m));
- usbCommands.append(COMMAND(num++, "Band 80m", commandButton, cmdGetBandStackReg, band80m));
- usbCommands.append(COMMAND(num++, "Band 160m", commandButton, cmdGetBandStackReg, band160m));
- usbCommands.append(COMMAND(num++, "Band 630m", commandButton, cmdGetBandStackReg, band630m));
- usbCommands.append(COMMAND(num++, "Band 2200m", commandButton, cmdGetBandStackReg, band2200m));
- usbCommands.append(COMMAND(num++, "Band GEN", commandButton, cmdGetBandStackReg, bandGen));
- usbCommands.append(COMMAND(num++, "NR On", commandButton, cmdNone, 0x0));
- usbCommands.append(COMMAND(num++, "NR Off", commandButton, cmdNone, 0x0));
- usbCommands.append(COMMAND(num++, "NB On", commandButton, cmdNone, 0x0));
- usbCommands.append(COMMAND(num++, "NB Off", commandButton, cmdNone, 0x0));
- usbCommands.append(COMMAND(num++, "Split On", commandButton, cmdNone, 0x01));
- usbCommands.append(COMMAND(num++, "Split Off", commandButton, cmdNone, 0x0));
- usbCommands.append(COMMAND(num++, "Swap VFO", commandButton, cmdVFOSwap, 0x0));
- usbCommands.append(COMMAND(num++, "AF Gain", commandKnob, cmdSetAfGain, 0xff));
- usbCommands.append(COMMAND(num++, "RF Gain", commandKnob, cmdSetRxRfGain, 0xff));
- usbCommands.append(COMMAND(num++, "TX Power", commandKnob, cmdSetTxPower, 0xff));
- usbCommands.append(COMMAND(num++, "Mic Gain", commandKnob, cmdSetMicGain, 0xff));
- usbCommands.append(COMMAND(num++, "Mod Level", commandKnob, cmdSetModLevel, 0xff));
- usbCommands.append(COMMAND(num++, "Squelch", commandKnob, cmdSetSql, 0xff));
- usbCommands.append(COMMAND(num++, "IF Shift", commandKnob, cmdSetIFShift, 0xff));
- usbCommands.append(COMMAND(num++, "In PBT", commandKnob, cmdSetTPBFInner, 0xff));
- usbCommands.append(COMMAND(num++, "Out PBT", commandKnob, cmdSetTPBFOuter, 0xff));
- usbCommands.append(COMMAND(num++, "CW Pitch", commandKnob, cmdSetCwPitch, 0xff));
- usbCommands.append(COMMAND(num++, "CW Speed", commandKnob, cmdSetKeySpeed, 0xff));
- emit sendUsbControllerCommands(&usbCommands);
-#endif
-}
-
-void wfmain::receiveUsbSensitivity(int val) {
- prefs.usbSensitivity = val;
-}
-
-void wfmain::receiveUsbSettings(quint8 bright, quint8 orient, quint8 speed, quint8 timeout, QColor color)
-{
- qInfo(logUsbControl()) << QString("USB brightness: %0 orentation: %1 speed: %2 timeout: %3 color: %4").arg(bright).arg(orient).arg(speed).arg(timeout).arg(color.name());
- prefs.usbBrightness = bright;
- prefs.usbOrientation = orient;
- prefs.usbSpeed = speed;
- prefs.usbTimeout = timeout;
- prefs.usbColor = color;
-}
diff --git a/wfmain.h b/wfmain.h
index de38c8c..caaf765 100644
--- a/wfmain.h
+++ b/wfmain.h
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include "logcategories.h"
#include "wfviewtypes.h"
@@ -62,6 +63,18 @@
#include "rtaudio/RtAudio.h"
#endif
+#ifdef USB_CONTROLLER
+ #ifdef Q_OS_WIN
+ #include
+ #include
+ #define USB_HOTPLUG
+ #elif defined(Q_OS_LINUX)
+ #include
+ #include
+ #define USB_HOTPLUG
+ #endif
+#endif
+
#define numColorPresetsTotal (5)
namespace Ui {
@@ -78,7 +91,20 @@ public:
static void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
void handleLogText(QString text);
+#ifdef USB_HOTPLUG
+ #if defined(Q_OS_WIN)
+ protected:
+ virtual bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result);
+ #elif defined(Q_OS_LINUX)
+ private slots:
+ void uDevEvent();
+ #endif
+#endif
+
signals:
+ // Signal levels received to other parts of wfview
+ void sendLevel(cmds cmd, unsigned char level);
+ void usbHotplug();
// Basic to rig:
void setCIVAddr(unsigned char newRigCIVAddr);
void setRigID(unsigned char rigID);
@@ -90,6 +116,7 @@ signals:
// Frequency, mode, band:
void getFrequency();
+ void getFrequency(unsigned char);
void setFrequency(unsigned char vfo, freqt freq);
void getMode();
void setMode(unsigned char modeIndex, unsigned char modeFilter);
@@ -140,7 +167,20 @@ signals:
void getModInputLevel(rigInput input);
void getMeters(meterKind meter);
void getPassband();
+ void getVoxGain();
+ void getAntiVoxGain();
+ void getMonitorGain();
+ void getNBLevel();
+ void getNRLevel();
+ void getCompLevel();
void getCwPitch();
+
+ void getVox();
+ void getMonitor();
+ void getCompressor();
+ void getNB();
+ void getNR();
+
void getDashRatio();
void getPskTone();
void getRttyMark();
@@ -159,9 +199,18 @@ signals:
void setMicGain(unsigned char);
void setCompLevel(unsigned char);
void setTxPower(unsigned char);
- void setMonitorLevel(unsigned char);
+ void setMonitorGain(unsigned char);
void setVoxGain(unsigned char);
void setAntiVoxGain(unsigned char);
+ void setNBLevel(unsigned char level);
+ void setNRLevel(unsigned char level);
+
+ void setVox(bool en);
+ void setMonitor(bool en);
+ void setCompressor(bool en);
+ void setNB(bool en);
+ void setNR(bool en);
+
void setSpectrumRefLevel(int);
void setModLevel(rigInput input, unsigned char level);
@@ -170,6 +219,7 @@ signals:
void setACCBGain(unsigned char level);
void setUSBGain(unsigned char level);
void setLANGain(unsigned char level);
+
void setPassband(quint16 pass);
// PTT, ATU, ATT, Antenna, Preamp:
@@ -225,11 +275,7 @@ signals:
void openShuttle();
void requestRigState();
void stateUpdated();
- void initUsbController(int sens, QMutex* mutex);
- void sendUsbControllerCommands(QVector* cmds);
- void sendUsbControllerButtons(QVector* buts);
- void sendUsbControllerKnobs(QVector* kbs);
- void initUsbDefaults(quint8 bright, quint8 orient, quint8 speed, quint8 timeout, QColor color);
+ void initUsbController(QMutex* mutex,usbDevMap* devs ,QVector* buts,QVector* knobs);
void setClusterUdpPort(int port);
void setClusterEnableUdp(bool udp);
void setClusterEnableTcp(bool tcp);
@@ -240,6 +286,7 @@ signals:
void setClusterTimeout(int timeout);
void setClusterSkimmerSpots(bool enable);
void setFrequencyRange(double low, double high);
+ void sendControllerRequest(USBDEVICE* dev, usbFeatureType request, int val=0, QString text="", QImage* img=Q_NULLPTR, QColor* color=Q_NULLPTR);
private slots:
void setAudioDevicesUI();
@@ -299,9 +346,17 @@ private slots:
void receiveModInput(rigInput input, bool dataOn);
//void receiveDuplexMode(duplexMode dm);
void receivePassband(quint16 pass);
+ void receiveMonitorGain(unsigned char pass);
+ void receiveNBLevel(unsigned char pass);
+ void receiveNRLevel(unsigned char pass);
void receiveCwPitch(unsigned char pitch);
void receiveTPBFInner(unsigned char level);
void receiveTPBFOuter(unsigned char level);
+ void receiveVox(bool en);
+ void receiveMonitor(bool en);
+ void receiveComp(bool en);
+ void receiveNB(bool en);
+ void receiveNR(bool en);
// Levels:
void receiveRfGain(unsigned char level);
@@ -317,7 +372,6 @@ private slots:
void receiveTxPower(unsigned char power);
void receiveMicGain(unsigned char gain);
void receiveCompLevel(unsigned char compLevel);
- void receiveMonitorGain(unsigned char monitorGain);
void receiveVoxGain(unsigned char voxGain);
void receiveAntiVoxGain(unsigned char antiVoxGain);
void receiveSpectrumRefLevel(int level);
@@ -354,8 +408,6 @@ private slots:
void showStatusBarText(QString text);
void receiveBaudRate(quint32 baudrate);
void radioSelection(QList radios);
- void receiveUsbSensitivity(int val);
- void receiveUsbSettings(quint8 bright, quint8 orient, quint8 speed, quint8 timeout, QColor color);
// Added for RC28/Shuttle support
@@ -405,8 +457,7 @@ private slots:
void on_fEnterBtn_clicked();
void on_usbControllerBtn_clicked();
- void on_usbButtonsResetBtn_clicked();
- void on_usbCommandsResetBtn_clicked();
+ void on_usbControllersResetBtn_clicked();
void on_enableUsbChk_clicked(bool checked);
@@ -500,7 +551,7 @@ private slots:
void on_vspCombo_currentIndexChanged(int value);
- void on_scopeEnableWFBtn_clicked(bool checked);
+ void on_scopeEnableWFBtn_stateChanged(int state);
void on_sqlSlider_valueChanged(int value);
@@ -926,6 +977,7 @@ private:
double oldLowerFreq;
double oldUpperFreq;
freqt freq;
+ freqt freqb;
float tsKnobMHz;
unsigned char setModeVal=0;
@@ -1073,9 +1125,6 @@ private:
void updateUsbButtons();
- void resetUsbButtons();
- void resetUsbKnobs();
- void resetUsbCommands();
int oldFreqDialVal;
rigCapabilities rigCaps;
@@ -1102,7 +1151,7 @@ private:
satelliteSetup *sat;
transceiverAdjustments *trxadj;
cwSender *cw;
- controllerSetup* shut;
+ controllerSetup* usbWindow = Q_NULLPTR;
aboutbox *abtBox;
selectRadio *selRad;
loggingWindow *logWindow;
@@ -1150,11 +1199,18 @@ private:
#if defined (USB_CONTROLLER)
usbController *usbControllerDev = Q_NULLPTR;
QThread *usbControllerThread = Q_NULLPTR;
- QString usbDeviceName;
- QVector usbCommands;
+ QString typeName;
QVector usbButtons;
QVector usbKnobs;
+ usbDevMap usbDevices;
QMutex usbMutex;
+ qint64 lastUsbNotify=0;
+
+ #if defined (Q_OS_LINUX)
+ struct udev* uDev = nullptr;
+ struct udev_monitor* uDevMonitor = nullptr;
+ QSocketNotifier* uDevNotifier = nullptr;
+ #endif
#endif
dxClusterClient* cluster = Q_NULLPTR;
@@ -1166,6 +1222,7 @@ private:
QMutex clusterMutex;
QColor clusterColor;
audioDevices* audioDev = Q_NULLPTR;
+ QImage lcdImage;
};
Q_DECLARE_METATYPE(struct rigCapabilities)
@@ -1192,12 +1249,15 @@ Q_DECLARE_METATYPE(QVector *)
Q_DECLARE_METATYPE(QVector *)
Q_DECLARE_METATYPE(QVector *)
Q_DECLARE_METATYPE(const COMMAND*)
+Q_DECLARE_METATYPE(const USBDEVICE*)
Q_DECLARE_METATYPE(codecType)
Q_DECLARE_METATYPE(errorType)
Q_DECLARE_METATYPE(enum duplexMode)
Q_DECLARE_METATYPE(enum rptAccessTxRx)
Q_DECLARE_METATYPE(struct rptrTone_t)
Q_DECLARE_METATYPE(struct rptrAccessData_t)
+Q_DECLARE_METATYPE(enum usbFeatureType)
+Q_DECLARE_METATYPE(enum cmds)
//void (*wfmain::logthistext)(QString text) = NULL;
diff --git a/wfmain.ui b/wfmain.ui
index 1228901..f625ea7 100644
--- a/wfmain.ui
+++ b/wfmain.ui
@@ -18,7 +18,7 @@
-
- 3
+ 0
@@ -159,12 +159,18 @@
-
+
+ Checked=WF enable, Unchecked=WF disable, Partial=Enable WF but no local display
+
Enable WF
true
+
+ true
+
-
@@ -3443,8 +3449,8 @@
0
0
- 820
- 302
+ 579
+ 254
@@ -5015,7 +5021,7 @@
- Setup USB Controller
+ Setup USB Controllers
@@ -5033,23 +5039,16 @@
-
-
+
- Reset Buttons
-
-
-
- -
-
-
- Reset Commands
+ Reset Controllers
-
- Only reset buttons/commands if you have issues.
+ Reset all USB controllers to defaults (delete all knobs/buttons)
@@ -5537,8 +5536,8 @@
-
+
diff --git a/wfview.pro b/wfview.pro
index 3fcc6e8..a401d92 100644
--- a/wfview.pro
+++ b/wfview.pro
@@ -51,7 +51,7 @@ macx:DEFINES += __MACOSX_CORE__
!linux:HEADERS += ../rtaudio/RTAUdio.h
!linux:INCLUDEPATH += ../rtaudio
-linux:LIBS += -lpulse -lpulse-simple -lrtaudio -lpthread
+linux:LIBS += -lpulse -lpulse-simple -lrtaudio -lpthread -ludev
win32:INCLUDEPATH += ../portaudio/include
!win32:LIBS += -lportaudio
@@ -202,7 +202,7 @@ contains(DEFINES,USB_CONTROLLER){
}
!win32:LIBS += -L./ -l$$QCPLIB -lopus
-win32:LIBS += -l$$QCPLIB -lopus -lole32
+win32:LIBS += -l$$QCPLIB -lopus -lole32 -luser32
#macx:SOURCES += ../qcustomplot/qcustomplot.cpp
diff --git a/wfviewtypes.h b/wfviewtypes.h
index 2921c30..a84ff7c 100644
--- a/wfviewtypes.h
+++ b/wfviewtypes.h
@@ -148,16 +148,19 @@ struct timekind {
};
enum cmds {
- cmdNone, cmdGetRigID, cmdGetRigCIV, cmdGetFreq, cmdSetFreq, cmdGetMode, cmdSetMode,
+ cmdNone, cmdGetRigID, cmdGetRigCIV, cmdGetFreq, cmdGetFreqB, cmdSetFreq, cmdGetMode, cmdSetMode,
cmdGetDataMode, cmdSetModeFilter, cmdSetDataModeOn, cmdSetDataModeOff, cmdGetRitEnabled, cmdGetRitValue,
cmdSpecOn, cmdSpecOff, cmdDispEnable, cmdDispDisable, cmdGetRxGain, cmdSetRxRfGain, cmdGetAfGain, cmdSetAfGain,
- cmdGetSql, cmdSetSql, cmdGetIFShift, cmdSetIFShift, cmdGetTPBFInner, cmdSetTPBFInner,
- cmdGetTPBFOuter, cmdSetTPBFOuter, cmdGetPassband, cmdSetPassband,
+ cmdGetSql, cmdSetSql, cmdGetIFShift, cmdSetIFShift, cmdGetNRLevel, cmdSetNRLevel, cmdGetTPBFInner, cmdSetTPBFInner,
+ cmdGetTPBFOuter, cmdSetTPBFOuter, cmdGetPassband, cmdSetPassband, cmdGetNBLevel, cmdSetNBLevel,
+ cmdGetCompLevel, cmdSetCompLevel,
+ cmdGetMonitorGain, cmdSetMonitorGain, cmdGetVoxGain, cmdSetVoxGain, cmdGetAntiVoxGain, cmdSetAntiVoxGain,
cmdGetCwPitch, cmdGetPskTone, cmdGetRttyMark, cmdSetCwPitch, cmdSetPskTone, cmdSetRttyMark,
+ cmdGetVox,cmdSetVox, cmdGetMonitor,cmdSetMonitor, cmdGetComp, cmdSetComp, cmdGetNB, cmdSetNB, cmdGetNR, cmdSetNR,
cmdSetATU, cmdStartATU, cmdGetATUStatus,
cmdGetSpectrumMode, cmdGetSpectrumSpan, cmdScopeCenterMode, cmdScopeFixedMode,
cmdGetPTT, cmdSetPTT,cmdPTTToggle,
- cmdGetTxPower, cmdSetTxPower, cmdGetMicGain, cmdSetMicGain, cmdSetModLevel,
+ cmdGetTxPower, cmdSetTxPower, cmdGetMicGain, cmdSetMicGain, cmdGetModLevel, cmdSetModLevel,
cmdGetSpectrumRefLevel, cmdGetDuplexMode, cmdGetModInput, cmdGetModDataInput,
cmdGetCurrentModLevel, cmdStartRegularPolling, cmdStopRegularPolling, cmdQueNormalSpeed,
cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetCenterMeter, cmdGetPowerMeter,
@@ -170,7 +173,9 @@ enum cmds {
cmdGetBandStackReg, cmdGetKeySpeed, cmdSetKeySpeed, cmdGetBreakMode, cmdSetBreakMode, cmdSendCW, cmdStopCW, cmdGetDashRatio, cmdSetDashRatio,
cmdSetTime, cmdSetDate, cmdSetUTCOffset,
// Below Only used for USB Controller at the moment.
- cmdSetBandUp, cmdSetBandDown, cmdSetModeUp, cmdSetModeDown, cmdSetStepUp, cmdSetStepDown, cmdSetSpanUp, cmdSetSpanDown, cmdIFFilterUp, cmdIFFilterDown
+ cmdSetBandUp, cmdSetBandDown, cmdSetModeUp, cmdSetModeDown, cmdSetStepUp, cmdSetStepDown,
+ cmdSetSpanUp, cmdSetSpanDown, cmdIFFilterUp, cmdIFFilterDown, cmdPageDown, cmdPageUp,
+ cmdLCDWaterfall, cmdLCDSpectrum, cmdLCDNothing, cmdSeparator
};
struct commandtype {
@@ -195,7 +200,14 @@ enum codecType { LPCM, PCMU, OPUS };
enum passbandActions {passbandStatic, pbtInnerMove, pbtOuterMove, pbtMoving, passbandResizing};
-enum usbDeviceType { usbNone = 0, shuttleXpress, shuttlePro2, RC28, xBoxGamepad, unknownGamepad, eCoderPlus, QuickKeys};
-enum usbCommandType{ commandButton, commandKnob };
+enum usbDeviceType { usbNone = 0, shuttleXpress, shuttlePro2,
+ RC28, xBoxGamepad, unknownGamepad, eCoderPlus, QuickKeys,
+ StreamDeckMini,StreamDeckMiniV2,StreamDeckOriginal,StreamDeckOriginalV2,
+ StreamDeckOriginalMK2,StreamDeckXL,StreamDeckXLV2,StreamDeckPedal, StreamDeckPlus
+ };
+
+enum usbCommandType{ commandButton, commandKnob, commandAny };
+enum usbFeatureType { featureReset,featureResetKeys, featureEventsA, featureEventsB, featureFirmware, featureSerial, featureButton, featureSensitivity, featureBrightness,
+ featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featureLCD, featureGraph, featureLEDControl };
#endif // WFVIEWTYPES_H