kopia lustrzana https://gitlab.com/eliggett/wfview
More work, tidying and improving stablity
rodzic
0304ac67f6
commit
a0f3f7de07
|
@ -17,6 +17,9 @@ controllerSetup::controllerSetup(QWidget* parent) :
|
||||||
|
|
||||||
controllerSetup::~controllerSetup()
|
controllerSetup::~controllerSetup()
|
||||||
{
|
{
|
||||||
|
qInfo(logUsbControl()) << "Deleting controllerSetup() window";
|
||||||
|
delete noControllersText;
|
||||||
|
delete updateDialog;
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,17 +35,20 @@ void controllerSetup::on_tabWidget_currentChanged(int index)
|
||||||
updateDialog->hide();
|
updateDialog->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void controllerSetup::init(usbDevMap* dev, QVector<BUTTON>* but, QVector<KNOB>* kb, QVector<COMMAND>* cmd, QMutex* mut)
|
||||||
void controllerSetup::init()
|
|
||||||
{
|
{
|
||||||
|
// Store pointers to all current settings
|
||||||
|
devices = dev;
|
||||||
|
buttons = but;
|
||||||
|
knobs = kb;
|
||||||
|
commands = cmd;
|
||||||
|
mutex = mut;
|
||||||
|
|
||||||
updateDialog = new QDialog(this);
|
updateDialog = new QDialog(this);
|
||||||
// Not sure if I like it Frameless or not?
|
// Not sure if I like it Frameless or not?
|
||||||
updateDialog->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
|
updateDialog->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
|
||||||
|
|
||||||
QGridLayout* udLayout = new QGridLayout;
|
QGridLayout* udLayout = new QGridLayout(updateDialog);
|
||||||
updateDialog->setLayout(udLayout);
|
|
||||||
updateDialog->setBaseSize(1, 1);
|
|
||||||
|
|
||||||
onLabel = new QLabel("On");
|
onLabel = new QLabel("On");
|
||||||
udLayout->addWidget(onLabel,0,0);
|
udLayout->addWidget(onLabel,0,0);
|
||||||
|
@ -85,6 +91,30 @@ void controllerSetup::init()
|
||||||
|
|
||||||
updateDialog->hide();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c.cmdType == commandKnob || c.cmdType == commandAny) {
|
||||||
|
if (c.command == cmdSeparator) {
|
||||||
|
knobEvent->insertSeparator(knobEvent->count());
|
||||||
|
} else {
|
||||||
|
knobEvent->addItem(c.text, c.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
connect(offEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(offEventIndexChanged(int)));
|
connect(offEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(offEventIndexChanged(int)));
|
||||||
connect(onEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(onEventIndexChanged(int)));
|
connect(onEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(onEventIndexChanged(int)));
|
||||||
connect(knobEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(knobEventIndexChanged(int)));
|
connect(knobEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(knobEventIndexChanged(int)));
|
||||||
|
@ -103,17 +133,18 @@ void controllerSetup::mousePressed(controllerScene* scene, QPoint p)
|
||||||
|
|
||||||
QPoint gp = this->mapToGlobal(p);
|
QPoint gp = this->mapToGlobal(p);
|
||||||
|
|
||||||
|
|
||||||
// Did the user click on a button?
|
// Did the user click on a button?
|
||||||
auto b = std::find_if(buttons->begin(), buttons->end(), [p, this](BUTTON& b)
|
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 ); });
|
{ return (b.parent != Q_NULLPTR && b.pos.contains(p) && b.page == b.parent->currentPage && ui->tabWidget->currentWidget()->objectName() == b.path ); });
|
||||||
|
|
||||||
if (b != buttons->end())
|
if (but != buttons->end())
|
||||||
{
|
{
|
||||||
currentButton = b;
|
currentButton = but;
|
||||||
currentKnob = Q_NULLPTR;
|
currentKnob = Q_NULLPTR;
|
||||||
qDebug() << "Button" << currentButton->num << "On Event" << currentButton->onCommand->text << "Off Event" << currentButton->offCommand->text;
|
qDebug() << "Button" << currentButton->num << "On Event" << currentButton->onCommand->text << "Off Event" << currentButton->offCommand->text;
|
||||||
|
|
||||||
updateDialog->setWindowTitle(QString("Update button %0").arg(b->num));
|
updateDialog->setWindowTitle(QString("Update button %0").arg(but->num));
|
||||||
|
|
||||||
onEvent->blockSignals(true);
|
onEvent->blockSignals(true);
|
||||||
onEvent->setCurrentIndex(onEvent->findData(currentButton->onCommand->index));
|
onEvent->setCurrentIndex(onEvent->findData(currentButton->onCommand->index));
|
||||||
|
@ -166,16 +197,16 @@ void controllerSetup::mousePressed(controllerScene* scene, QPoint p)
|
||||||
updateDialog->raise();
|
updateDialog->raise();
|
||||||
} else {
|
} else {
|
||||||
// It wasn't a button so was it a knob?
|
// It wasn't a button so was it a knob?
|
||||||
auto k = std::find_if(knobs->begin(), knobs->end(), [p, this](KNOB& k)
|
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 ); });
|
{ return (k.parent != Q_NULLPTR && k.pos.contains(p) && k.page == k.parent->currentPage && ui->tabWidget->currentWidget()->objectName() == k.path ); });
|
||||||
|
|
||||||
if (k != knobs->end())
|
if (kb != knobs->end())
|
||||||
{
|
{
|
||||||
currentKnob = k;
|
currentKnob = kb;
|
||||||
currentButton = Q_NULLPTR;
|
currentButton = Q_NULLPTR;
|
||||||
qDebug() << "Knob" << currentKnob->num << "Event" << currentKnob->command->text;
|
qDebug() << "Knob" << currentKnob->num << "Event" << currentKnob->command->text;
|
||||||
|
|
||||||
updateDialog->setWindowTitle(QString("Update knob %0").arg(k->num));
|
updateDialog->setWindowTitle(QString("Update knob %0").arg(kb->num));
|
||||||
|
|
||||||
knobEvent->blockSignals(true);
|
knobEvent->blockSignals(true);
|
||||||
knobEvent->setCurrentIndex(knobEvent->findData(currentKnob->command->index));
|
knobEvent->setCurrentIndex(knobEvent->findData(currentKnob->command->index));
|
||||||
|
@ -213,9 +244,7 @@ void controllerSetup::onEventIndexChanged(int index) {
|
||||||
// If command is changed, delete current command and deep copy the new command
|
// If command is changed, delete current command and deep copy the new command
|
||||||
if (currentButton != Q_NULLPTR && onEvent->currentData().toInt() < commands->size()) {
|
if (currentButton != Q_NULLPTR && onEvent->currentData().toInt() < commands->size()) {
|
||||||
QMutexLocker locker(mutex);
|
QMutexLocker locker(mutex);
|
||||||
if (currentButton->onCommand)
|
currentButton->onCommand = &commands->at(onEvent->currentData().toInt());
|
||||||
delete currentButton->onCommand;
|
|
||||||
currentButton->onCommand = new COMMAND(commands->at(onEvent->currentData().toInt()));
|
|
||||||
currentButton->onText->setPlainText(currentButton->onCommand->text);
|
currentButton->onText->setPlainText(currentButton->onCommand->text);
|
||||||
currentButton->onText->setPos(currentButton->pos.center().x() - currentButton->onText->boundingRect().width() / 2,
|
currentButton->onText->setPos(currentButton->pos.center().x() - currentButton->onText->boundingRect().width() / 2,
|
||||||
(currentButton->pos.center().y() - currentButton->onText->boundingRect().height() / 2)-6);
|
(currentButton->pos.center().y() - currentButton->onText->boundingRect().height() / 2)-6);
|
||||||
|
@ -230,9 +259,7 @@ void controllerSetup::offEventIndexChanged(int index) {
|
||||||
// If command is changed, delete current command and deep copy the new command
|
// If command is changed, delete current command and deep copy the new command
|
||||||
if (currentButton != Q_NULLPTR && offEvent->currentData().toInt() < commands->size()) {
|
if (currentButton != Q_NULLPTR && offEvent->currentData().toInt() < commands->size()) {
|
||||||
QMutexLocker locker(mutex);
|
QMutexLocker locker(mutex);
|
||||||
if (currentButton->offCommand)
|
currentButton->offCommand = &commands->at(offEvent->currentData().toInt());
|
||||||
delete currentButton->offCommand;
|
|
||||||
currentButton->offCommand = new COMMAND(commands->at(offEvent->currentData().toInt()));
|
|
||||||
currentButton->offText->setPlainText(currentButton->offCommand->text);
|
currentButton->offText->setPlainText(currentButton->offCommand->text);
|
||||||
currentButton->offText->setPos(currentButton->pos.center().x() - currentButton->offText->boundingRect().width() / 2,
|
currentButton->offText->setPos(currentButton->pos.center().x() - currentButton->offText->boundingRect().width() / 2,
|
||||||
(currentButton->pos.center().y() - currentButton->offText->boundingRect().height() / 2)+6);
|
(currentButton->pos.center().y() - currentButton->offText->boundingRect().height() / 2)+6);
|
||||||
|
@ -248,7 +275,7 @@ void controllerSetup::knobEventIndexChanged(int index) {
|
||||||
QMutexLocker locker(mutex);
|
QMutexLocker locker(mutex);
|
||||||
if (currentKnob->command)
|
if (currentKnob->command)
|
||||||
delete currentKnob->command;
|
delete currentKnob->command;
|
||||||
currentKnob->command = new COMMAND(commands->at(knobEvent->currentData().toInt()));
|
currentKnob->command = &commands->at(knobEvent->currentData().toInt());
|
||||||
currentKnob->text->setPlainText(currentKnob->command->text);
|
currentKnob->text->setPlainText(currentKnob->command->text);
|
||||||
currentKnob->text->setPos(currentKnob->pos.center().x() - currentKnob->text->boundingRect().width() / 2,
|
currentKnob->text->setPos(currentKnob->pos.center().x() - currentKnob->text->boundingRect().width() / 2,
|
||||||
(currentKnob->pos.center().y() - currentKnob->text->boundingRect().height() / 2));
|
(currentKnob->pos.center().y() - currentKnob->text->boundingRect().height() / 2));
|
||||||
|
@ -312,28 +339,108 @@ void controllerSetup::latchStateChanged(int state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void controllerSetup::deleteMyWidget(QWidget* widget) {
|
||||||
|
QLayout *layout = widget->layout();
|
||||||
|
if (widget->layout())
|
||||||
|
{
|
||||||
|
QLayoutItem* child;
|
||||||
|
while (nullptr != (child = layout->takeAt(0)))
|
||||||
|
{
|
||||||
|
if (child->layout())
|
||||||
|
{
|
||||||
|
QLayoutItem* child2;
|
||||||
|
|
||||||
|
while (nullptr != (child2 = child->layout()->takeAt(0)))
|
||||||
|
{
|
||||||
|
if (child2->widget())
|
||||||
|
{
|
||||||
|
deleteMyWidget(child2->widget());
|
||||||
|
}
|
||||||
|
delete child2;
|
||||||
|
child2 = Q_NULLPTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (child->widget())
|
||||||
|
{
|
||||||
|
deleteMyWidget(child->widget());
|
||||||
|
}
|
||||||
|
delete child;
|
||||||
|
child = Q_NULLPTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete widget;
|
||||||
|
}
|
||||||
|
|
||||||
void controllerSetup::removeDevice(USBDEVICE* dev)
|
void controllerSetup::removeDevice(USBDEVICE* dev)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(mutex);
|
QMutexLocker locker(mutex);
|
||||||
|
|
||||||
int remove = -1;
|
/* 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 (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (auto b = buttons->begin();b != buttons->end(); b++)
|
||||||
auto widget = ui->tabWidget->widget(i);
|
{
|
||||||
if (widget->objectName() == dev->path) {
|
if (b->parent == dev && b->page == dev->currentPage)
|
||||||
qInfo(logUsbControl()) << "Removing child widgets for" << dev->product;
|
{
|
||||||
qDeleteAll(widget->findChildren<QWidget *>("", Qt::FindDirectChildrenOnly));
|
if (b->onText != Q_NULLPTR) {
|
||||||
remove = i;
|
tab.value()->scene->removeItem(b->onText);
|
||||||
//break;
|
delete b->onText;
|
||||||
|
b->onText = Q_NULLPTR;
|
||||||
|
b->onCommand = Q_NULLPTR;
|
||||||
|
}
|
||||||
|
if (b->offText != Q_NULLPTR) {
|
||||||
|
tab.value()->scene->removeItem(b->offText);
|
||||||
|
delete b->offText;
|
||||||
|
b->offText = Q_NULLPTR;
|
||||||
|
b->offCommand = Q_NULLPTR;
|
||||||
|
}
|
||||||
|
if (b->icon != Q_NULLPTR) {
|
||||||
|
delete b->icon;
|
||||||
|
b->icon=Q_NULLPTR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remove != -1) {
|
for (auto k = knobs->begin();k != knobs->end(); k++)
|
||||||
qInfo(logUsbControl()) << "Removing tab" << dev->product;
|
{
|
||||||
//auto widget = ui->tabWidget->widget(remove);
|
if (k->parent == dev && k->page == dev->currentPage)
|
||||||
ui->tabWidget->removeTab(remove);
|
{
|
||||||
//widget->deleteLater();
|
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)
|
if (ui->tabWidget->count() == 0)
|
||||||
{
|
{
|
||||||
ui->tabWidget->hide();
|
ui->tabWidget->hide();
|
||||||
|
@ -342,13 +449,8 @@ void controllerSetup::removeDevice(USBDEVICE* dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void controllerSetup::newDevice(USBDEVICE* dev, CONTROLLER* cntrl, QVector<BUTTON>* but, QVector<KNOB>* kb, QVector<COMMAND>* cmd, QMutex* mut)
|
void controllerSetup::newDevice(USBDEVICE* dev)
|
||||||
{
|
{
|
||||||
buttons = but;
|
|
||||||
knobs = kb;
|
|
||||||
commands = cmd;
|
|
||||||
mutex = mut;
|
|
||||||
|
|
||||||
QMutexLocker locker(mutex);
|
QMutexLocker locker(mutex);
|
||||||
|
|
||||||
for (int i=0; i<ui->tabWidget->count();i++) {
|
for (int i=0; i<ui->tabWidget->count();i++) {
|
||||||
|
@ -359,262 +461,215 @@ void controllerSetup::newDevice(USBDEVICE* dev, CONTROLLER* cntrl, QVector<BUTTO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
qDebug(logUsbControl()) << "Adding new tab for" << dev->product;
|
||||||
noControllersText->hide();
|
noControllersText->hide();
|
||||||
|
|
||||||
QWidget* tab = new QWidget();
|
tabContent* c = new tabContent();
|
||||||
tab->setObjectName(dev->path);
|
|
||||||
|
|
||||||
ui->tabWidget->addTab(tab,dev->product);
|
c->tab.setObjectName(dev->path);
|
||||||
ui->tabWidget->show();
|
ui->tabWidget->addTab(&c->tab,dev->product);
|
||||||
|
c->tab.setLayout(&c->mainLayout);
|
||||||
|
c->mainLayout.addLayout(&c->topLayout);
|
||||||
|
c->mainLayout.addWidget(&c->widget);
|
||||||
|
|
||||||
QVBoxLayout* mainlayout = new QVBoxLayout();
|
c->widget.setLayout(&c->layout);
|
||||||
mainlayout->setContentsMargins(0,0,0,0);
|
c->layout.addLayout(&c->sensLayout);
|
||||||
tab->setLayout(mainlayout);
|
|
||||||
|
|
||||||
|
|
||||||
QHBoxLayout* toplayout = new QHBoxLayout();
|
c->topLayout.addWidget(&c->disabled);
|
||||||
mainlayout->addLayout(toplayout);
|
c->disabled.setText("Disable");
|
||||||
toplayout->setContentsMargins(0,0,0,0);
|
connect(&c->disabled, qOverload<bool>(&QCheckBox::clicked),
|
||||||
|
[dev,this,c](bool checked) { this->disableClicked(dev,checked,&c->widget); });
|
||||||
|
c->disabled.setChecked(dev->disabled);
|
||||||
|
|
||||||
QWidget* widget = new QWidget();
|
|
||||||
mainlayout->addWidget(widget);
|
|
||||||
QVBoxLayout* layout = new QVBoxLayout(widget);
|
|
||||||
layout->setContentsMargins(0,0,0,0);
|
|
||||||
|
|
||||||
QCheckBox* disabled = new QCheckBox();
|
|
||||||
disabled->setText("Disable");
|
|
||||||
toplayout->addWidget(disabled);
|
|
||||||
dev->message = new QLabel();
|
|
||||||
if (dev->connected) {
|
if (dev->connected) {
|
||||||
dev->message->setStyleSheet("QLabel { color : green; }");
|
c->message.setStyleSheet("QLabel { color : green; }");
|
||||||
dev->message->setText("Connected");
|
c->message.setText("Connected");
|
||||||
} else {
|
} else {
|
||||||
dev->message->setStyleSheet("QLabel { color : red; }");
|
c->message.setStyleSheet("QLabel { color : red; }");
|
||||||
dev->message->setText("Not Connected");
|
c->message.setText("Not Connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
toplayout->addWidget(dev->message);
|
c->topLayout.addWidget(&c->message);
|
||||||
dev->message->setAlignment(Qt::AlignRight);
|
c->message.setAlignment(Qt::AlignRight);
|
||||||
|
|
||||||
connect(disabled, qOverload<bool>(&QCheckBox::clicked),
|
c->layout.addWidget(&c->view);
|
||||||
[dev,this,widget](bool checked) { this->disableClicked(dev,checked,widget); });
|
|
||||||
|
|
||||||
disabled->setChecked(dev->disabled);
|
c->page.setObjectName("Page SpinBox");
|
||||||
|
c->page.setValue(1);
|
||||||
|
c->page.setMinimum(1);
|
||||||
|
c->page.setMaximum(dev->pages);
|
||||||
|
c->page.setToolTip("Select current page to edit");
|
||||||
|
c->layout.addWidget(&c->page,0,Qt::AlignBottom | Qt::AlignRight);
|
||||||
|
dev->pageSpin = &c->page;
|
||||||
|
|
||||||
QGraphicsView *view = new QGraphicsView();
|
c->sensLayout.addWidget(&c->sensLabel);
|
||||||
layout->addWidget(view);
|
c->sens.setMinimum(1);
|
||||||
|
c->sens.setMaximum(21);
|
||||||
QSpinBox *page = new QSpinBox();
|
c->sens.setOrientation(Qt::Horizontal);
|
||||||
page->setValue(1);
|
c->sens.setInvertedAppearance(true);
|
||||||
page->setMinimum(1);
|
c->sensLayout.addWidget(&c->sens);
|
||||||
page->setMaximum(dev->pages);
|
c->sens.setValue(dev->sensitivity);
|
||||||
page->setToolTip("Select current page to edit");
|
connect(&c->sens, &QSlider::valueChanged,
|
||||||
layout->addWidget(page,0,Qt::AlignBottom | Qt::AlignRight);
|
|
||||||
dev->pageSpin = page;
|
|
||||||
|
|
||||||
|
|
||||||
QHBoxLayout* senslayout = new QHBoxLayout();
|
|
||||||
layout->addLayout(senslayout);
|
|
||||||
QLabel* senslabel = new QLabel("Sensitivity");
|
|
||||||
senslayout->addWidget(senslabel);
|
|
||||||
QSlider *sens = new QSlider();
|
|
||||||
sens->setMinimum(1);
|
|
||||||
sens->setMaximum(21);
|
|
||||||
sens->setOrientation(Qt::Horizontal);
|
|
||||||
sens->setInvertedAppearance(true);
|
|
||||||
senslayout->addWidget(sens);
|
|
||||||
sens->setValue(cntrl->sensitivity);
|
|
||||||
connect(sens, &QSlider::valueChanged,
|
|
||||||
[dev,this](int val) { this->sensitivityMoved(dev,val); });
|
[dev,this](int val) { this->sensitivityMoved(dev,val); });
|
||||||
|
|
||||||
QImage image;
|
|
||||||
|
|
||||||
switch (dev->type.model) {
|
switch (dev->type.model) {
|
||||||
case shuttleXpress:
|
case shuttleXpress:
|
||||||
image.load(":/resources/shuttlexpress.png");
|
c->image.load(":/resources/shuttlexpress.png");
|
||||||
break;
|
break;
|
||||||
case shuttlePro2:
|
case shuttlePro2:
|
||||||
image.load(":/resources/shuttlepro.png");
|
c->image.load(":/resources/shuttlepro.png");
|
||||||
break;
|
break;
|
||||||
case RC28:
|
case RC28:
|
||||||
image.load(":/resources/rc28.png");
|
c->image.load(":/resources/rc28.png");
|
||||||
break;
|
break;
|
||||||
case xBoxGamepad:
|
case xBoxGamepad:
|
||||||
image.load(":/resources/xbox.png");
|
c->image.load(":/resources/xbox.png");
|
||||||
break;
|
break;
|
||||||
case eCoderPlus:
|
case eCoderPlus:
|
||||||
image.load(":/resources/ecoder.png");
|
c->image.load(":/resources/ecoder.png");
|
||||||
break;
|
break;
|
||||||
case QuickKeys:
|
case QuickKeys:
|
||||||
image.load(":/resources/quickkeys.png");
|
c->image.load(":/resources/quickkeys.png");
|
||||||
break;
|
break;
|
||||||
case StreamDeckOriginal:
|
case StreamDeckOriginal:
|
||||||
case StreamDeckOriginalV2:
|
case StreamDeckOriginalV2:
|
||||||
case StreamDeckOriginalMK2:
|
case StreamDeckOriginalMK2:
|
||||||
image.load(":/resources/streamdeck.png");
|
c->image.load(":/resources/streamdeck.png");
|
||||||
break;
|
break;
|
||||||
case StreamDeckMini:
|
case StreamDeckMini:
|
||||||
case StreamDeckMiniV2:
|
case StreamDeckMiniV2:
|
||||||
image.load(":/resources/streamdeckmini.png");
|
c->image.load(":/resources/streamdeckmini.png");
|
||||||
break;
|
break;
|
||||||
case StreamDeckXL:
|
case StreamDeckXL:
|
||||||
case StreamDeckXLV2:
|
case StreamDeckXLV2:
|
||||||
image.load(":/resources/streamdeckxl.png");
|
c->image.load(":/resources/streamdeckxl.png");
|
||||||
break;
|
break;
|
||||||
case StreamDeckPlus:
|
case StreamDeckPlus:
|
||||||
image.load(":/resources/streamdeckplus.png");
|
c->image.load(":/resources/streamdeckplus.png");
|
||||||
break;
|
break;
|
||||||
default:
|
case StreamDeckPedal:
|
||||||
//ui->graphicsView->setSceneRect(scene->itemsBoundingRect());
|
c->image.load(":/resources/streamdeckpedal.png");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
this->adjustSize();
|
this->adjustSize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
QGraphicsItem* bgImage = new QGraphicsPixmapItem(QPixmap::fromImage(image));
|
c->bgImage = new QGraphicsPixmapItem(QPixmap::fromImage(c->image));
|
||||||
view->setMinimumSize(bgImage->boundingRect().width() + 2, bgImage->boundingRect().height() + 2);
|
c->view.setMinimumSize(c->bgImage->boundingRect().width() + 2, c->bgImage->boundingRect().height() + 2);
|
||||||
|
|
||||||
|
ui->tabWidget->show();
|
||||||
|
|
||||||
|
|
||||||
// This command causes the window to disappear in Linux?
|
// This command causes the window to disappear in Linux?
|
||||||
#if !defined(Q_OS_LINUX)
|
#if !defined(Q_OS_LINUX)
|
||||||
this->setMinimumSize(bgImage->boundingRect().width() + 2, bgImage->boundingRect().height() + 250);
|
this->setMinimumSize(c->bgImage->boundingRect().width() + 2, c->bgImage->boundingRect().height() + 250);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
controllerScene * scene = new controllerScene();
|
c->scene = new controllerScene();
|
||||||
dev->scene = scene;
|
c->view.setScene(c->scene);
|
||||||
view->setScene(scene);
|
connect(c->scene, SIGNAL(mousePressed(controllerScene*,QPoint)), this, SLOT(mousePressed(controllerScene*,QPoint)));
|
||||||
connect(scene, SIGNAL(mousePressed(controllerScene*,QPoint)), this, SLOT(mousePressed(controllerScene*,QPoint)));
|
c->scene->addItem(c->bgImage);
|
||||||
scene->addItem(bgImage);
|
|
||||||
|
|
||||||
|
c->layout.addLayout(&c->grid);
|
||||||
|
|
||||||
QGridLayout* grid = new QGridLayout();
|
c->grid.addWidget(&c->brightLabel,0,0);
|
||||||
layout->addLayout(grid);
|
c->brightness.addItem("Off");
|
||||||
|
c->brightness.addItem("Low");
|
||||||
QLabel* brightlabel = new QLabel("Brightness");
|
c->brightness.addItem("Medium");
|
||||||
grid->addWidget(brightlabel,0,0);
|
c->brightness.addItem("High");
|
||||||
QComboBox *brightness = new QComboBox();
|
c->brightness.setCurrentIndex(dev->brightness);
|
||||||
brightness->addItem("Off");
|
c->grid.addWidget(&c->brightness,1,0);
|
||||||
brightness->addItem("Low");
|
connect(&c->brightness, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||||
brightness->addItem("Medium");
|
|
||||||
brightness->addItem("High");
|
|
||||||
brightness->setCurrentIndex(cntrl->brightness);
|
|
||||||
grid->addWidget(brightness,1,0);
|
|
||||||
connect(brightness, qOverload<int>(&QComboBox::currentIndexChanged),
|
|
||||||
[dev,this](int index) { this->brightnessChanged(dev,index); });
|
[dev,this](int index) { this->brightnessChanged(dev,index); });
|
||||||
|
|
||||||
QLabel* speedlabel = new QLabel("Speed");
|
c->grid.addWidget(&c->speedLabel,0,1);
|
||||||
grid->addWidget(speedlabel,0,1);
|
c->speed.setObjectName("Speed");
|
||||||
QComboBox *speed = new QComboBox();
|
c->speed.addItem("Fastest");
|
||||||
speed->addItem("Fastest");
|
c->speed.addItem("Faster");
|
||||||
speed->addItem("Faster");
|
c->speed.addItem("Normal");
|
||||||
speed->addItem("Normal");
|
c->speed.addItem("Slower");
|
||||||
speed->addItem("Slower");
|
c->speed.addItem("Slowest");
|
||||||
speed->addItem("Slowest");
|
c->speed.setCurrentIndex(dev->speed);
|
||||||
speed->setCurrentIndex(cntrl->speed);
|
c->grid.addWidget(&c->speed,1,1);
|
||||||
grid->addWidget(speed,1,1);
|
connect(&c->speed, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||||
connect(speed, qOverload<int>(&QComboBox::currentIndexChanged),
|
|
||||||
[dev,this](int index) { this->speedChanged(dev,index); });
|
[dev,this](int index) { this->speedChanged(dev,index); });
|
||||||
|
|
||||||
QLabel* orientlabel = new QLabel("Orientation");
|
c->grid.addWidget(&c->orientLabel,0,2);
|
||||||
grid->addWidget(orientlabel,0,2);
|
c->orientation.addItem("Rotate 0");
|
||||||
QComboBox *orientation = new QComboBox();
|
c->orientation.addItem("Rotate 90");
|
||||||
orientation->addItem("Rotate 0");
|
c->orientation.addItem("Rotate 180");
|
||||||
orientation->addItem("Rotate 90");
|
c->orientation.addItem("Rotate 270");
|
||||||
orientation->addItem("Rotate 180");
|
c->orientation.setCurrentIndex(dev->orientation);
|
||||||
orientation->addItem("Rotate 270");
|
c->grid.addWidget(&c->orientation,1,2);
|
||||||
orientation->setCurrentIndex(cntrl->orientation);
|
connect(&c->orientation, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||||
grid->addWidget(orientation,1,2);
|
|
||||||
connect(orientation, qOverload<int>(&QComboBox::currentIndexChanged),
|
|
||||||
[dev,this](int index) { this->orientationChanged(dev,index); });
|
[dev,this](int index) { this->orientationChanged(dev,index); });
|
||||||
|
|
||||||
QLabel* colorlabel = new QLabel("Color");
|
c->color.setText("Color");
|
||||||
grid->addWidget(colorlabel,0,3);
|
c->grid.addWidget(&c->colorLabel,0,3);
|
||||||
QPushButton* color = new QPushButton("Select");
|
c->color.setStyleSheet(QString("background-color: %1").arg(dev->color.name(QColor::HexArgb)));
|
||||||
grid->addWidget(color,1,3);
|
c->grid.addWidget(&c->color,1,3);
|
||||||
connect(color, &QPushButton::clicked,
|
connect(&c->color, &QPushButton::clicked,
|
||||||
[dev,this]() { this->colorPicker(dev); });
|
[dev,c,this]() { this->colorPicker(dev,&c->color,dev->color); });
|
||||||
|
|
||||||
QLabel* timeoutlabel = new QLabel("Timeout");
|
c->timeoutLabel.setText("Timeout");
|
||||||
grid->addWidget(timeoutlabel,0,4);
|
c->grid.addWidget(&c->timeoutLabel,0,4);
|
||||||
QSpinBox *timeout = new QSpinBox();
|
c->timeout.setValue(dev->timeout);
|
||||||
timeout->setValue(cntrl->timeout);
|
c->grid.addWidget(&c->timeout,1,4);
|
||||||
grid->addWidget(timeout,1,4);
|
connect(&c->timeout, qOverload<int>(&QSpinBox::valueChanged),
|
||||||
connect(timeout, qOverload<int>(&QSpinBox::valueChanged),
|
|
||||||
[dev,this](int index) { this->timeoutChanged(dev,index); });
|
[dev,this](int index) { this->timeoutChanged(dev,index); });
|
||||||
|
|
||||||
QLabel* pageslabel = new QLabel("Pages");
|
c->pagesLabel.setText("Pages");
|
||||||
grid->addWidget(pageslabel,0,5);
|
c->grid.addWidget(&c->pagesLabel,0,5);
|
||||||
QSpinBox *pages = new QSpinBox();
|
c->pages.setValue(dev->pages);
|
||||||
pages->setValue(dev->pages);
|
c->pages.setMinimum(1);
|
||||||
pages->setMinimum(1);
|
c->grid.addWidget(&c->pages,1,5);
|
||||||
grid->addWidget(pages,1,5);
|
connect(&c->pages, qOverload<int>(&QSpinBox::valueChanged),
|
||||||
connect(pages, qOverload<int>(&QSpinBox::valueChanged),
|
|
||||||
[dev,this](int index) { this->pagesChanged(dev,index); });
|
[dev,this](int index) { this->pagesChanged(dev,index); });
|
||||||
|
|
||||||
for (int i=0;i<6;i++)
|
for (int i=0;i<6;i++)
|
||||||
grid->setColumnStretch(i,1);
|
c->grid.setColumnStretch(i,1);
|
||||||
|
|
||||||
QLabel *helpText = new QLabel();
|
c->helpText.setText("<p><b>Button configuration:</b> Right-click on each button to configure it.</p>");
|
||||||
helpText->setText("<p><b>Button configuration:</b> Right-click on each button to configure it.</p>");
|
c->helpText.setAlignment(Qt::AlignCenter);
|
||||||
helpText->setAlignment(Qt::AlignCenter);
|
c->layout.addWidget(&c->helpText);
|
||||||
layout->addWidget(helpText);
|
|
||||||
|
|
||||||
onEvent->blockSignals(true);
|
|
||||||
offEvent->blockSignals(true);
|
|
||||||
knobEvent->blockSignals(true);
|
|
||||||
|
|
||||||
onEvent->clear();
|
c->view.setSceneRect(c->scene->itemsBoundingRect());
|
||||||
offEvent->clear();
|
|
||||||
knobEvent->clear();
|
|
||||||
|
|
||||||
for (COMMAND& c : *commands) {
|
|
||||||
if (c.cmdType == commandButton || c.text == "None") {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (c.cmdType == commandKnob || c.text == "None") {
|
|
||||||
if (c.command == cmdSeparator) {
|
|
||||||
knobEvent->insertSeparator(knobEvent->count());
|
|
||||||
} else {
|
|
||||||
knobEvent->addItem(c.text, c.index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onEvent->blockSignals(false);
|
|
||||||
offEvent->blockSignals(false);
|
|
||||||
knobEvent->blockSignals(false);
|
|
||||||
|
|
||||||
locker.unlock();
|
|
||||||
pageChanged(dev,1);
|
|
||||||
locker.relock();
|
|
||||||
|
|
||||||
view->setSceneRect(scene->itemsBoundingRect());
|
|
||||||
|
|
||||||
// Add comboboxes to scene after everything else.
|
|
||||||
|
|
||||||
// Attach pageChanged() here so we have access to all necessary vars
|
// Attach pageChanged() here so we have access to all necessary vars
|
||||||
connect(page, qOverload<int>(&QSpinBox::valueChanged),
|
connect(&c->page, qOverload<int>(&QSpinBox::valueChanged),
|
||||||
[dev, this](int index) { this->pageChanged(dev, index); });
|
[dev, this](int index) { this->pageChanged(dev, index); });
|
||||||
|
|
||||||
|
|
||||||
this->adjustSize();
|
this->adjustSize();
|
||||||
|
|
||||||
numTabs++;
|
numTabs++;
|
||||||
|
tabs.insert(dev->path,c);
|
||||||
|
|
||||||
dev->uiCreated = true;
|
dev->uiCreated = true;
|
||||||
|
|
||||||
// Finally update the device with the default values
|
// Finally update the device with the default values
|
||||||
emit sendRequest(dev,usbFeatureType::featureSensitivity,cntrl->sensitivity);
|
emit sendRequest(dev,usbFeatureType::featureSensitivity,dev->sensitivity);
|
||||||
emit sendRequest(dev,usbFeatureType::featureBrightness,cntrl->brightness);
|
emit sendRequest(dev,usbFeatureType::featureBrightness,dev->brightness);
|
||||||
emit sendRequest(dev,usbFeatureType::featureOrientation,cntrl->orientation);
|
emit sendRequest(dev,usbFeatureType::featureOrientation,dev->orientation);
|
||||||
emit sendRequest(dev,usbFeatureType::featureSpeed,cntrl->speed);
|
emit sendRequest(dev,usbFeatureType::featureSpeed,dev->speed);
|
||||||
emit sendRequest(dev,usbFeatureType::featureTimeout,cntrl->timeout);
|
emit sendRequest(dev,usbFeatureType::featureTimeout,dev->timeout);
|
||||||
emit sendRequest(dev,usbFeatureType::featureColor,1,cntrl->color.name(QColor::HexArgb));
|
emit sendRequest(dev,usbFeatureType::featureColor,0,dev->color.name(QColor::HexArgb));
|
||||||
|
|
||||||
|
locker.unlock();
|
||||||
|
|
||||||
|
// pageChanged will update the buttons/knobs for the tab
|
||||||
|
pageChanged(dev,1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,19 +694,18 @@ void controllerSetup::speedChanged(USBDEVICE* dev, int index)
|
||||||
emit sendRequest(dev,usbFeatureType::featureSpeed,index);
|
emit sendRequest(dev,usbFeatureType::featureSpeed,index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void controllerSetup::colorPicker(USBDEVICE* dev)
|
void controllerSetup::colorPicker(USBDEVICE* dev, QPushButton* btn, QColor current)
|
||||||
{
|
{
|
||||||
QColorDialog::ColorDialogOptions options;
|
QColorDialog::ColorDialogOptions options;
|
||||||
options.setFlag(QColorDialog::ShowAlphaChannel, false);
|
options.setFlag(QColorDialog::ShowAlphaChannel, false);
|
||||||
options.setFlag(QColorDialog::DontUseNativeDialog, false);
|
options.setFlag(QColorDialog::DontUseNativeDialog, false);
|
||||||
QColor selColor = QColorDialog::getColor(initialColor, this, "Select Color", options);
|
QColor selColor = QColorDialog::getColor(current, this, "Select Color", options);
|
||||||
|
|
||||||
if(!selColor.isValid())
|
if(selColor.isValid())
|
||||||
{
|
{
|
||||||
selColor = initialColor;
|
btn->setStyleSheet(QString("background-color: %1").arg(selColor.name(QColor::HexArgb)));
|
||||||
|
emit sendRequest(dev,usbFeatureType::featureColor,0,selColor.name(QColor::HexArgb));
|
||||||
}
|
}
|
||||||
initialColor = selColor;
|
|
||||||
emit sendRequest(dev,usbFeatureType::featureColor,1,selColor.name(QColor::HexArgb));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void controllerSetup::timeoutChanged(USBDEVICE* dev, int val)
|
void controllerSetup::timeoutChanged(USBDEVICE* dev, int val)
|
||||||
|
@ -668,8 +722,14 @@ void controllerSetup::pagesChanged(USBDEVICE* dev, int val)
|
||||||
|
|
||||||
void controllerSetup::pageChanged(USBDEVICE* dev, int val)
|
void controllerSetup::pageChanged(USBDEVICE* dev, int val)
|
||||||
{
|
{
|
||||||
if (dev->currentPage == val) // We haven't changed page!
|
|
||||||
|
auto tab = tabs.find(dev->path);
|
||||||
|
if (tab == tabs.end())
|
||||||
|
{
|
||||||
|
qWarning(logUsbControl()) << "Cannot find tabContent while changing page" << dev->path;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (val > dev->pages)
|
if (val > dev->pages)
|
||||||
val=1;
|
val=1;
|
||||||
|
@ -692,12 +752,12 @@ void controllerSetup::pageChanged(USBDEVICE* dev, int val)
|
||||||
if (b->page == lastPage)
|
if (b->page == lastPage)
|
||||||
{
|
{
|
||||||
if (b->onText != Q_NULLPTR) {
|
if (b->onText != Q_NULLPTR) {
|
||||||
dev->scene->removeItem(b->onText);
|
tab.value()->scene->removeItem(b->onText);
|
||||||
delete b->onText;
|
delete b->onText;
|
||||||
b->onText = Q_NULLPTR;
|
b->onText = Q_NULLPTR;
|
||||||
}
|
}
|
||||||
if (b->offText != Q_NULLPTR) {
|
if (b->offText != Q_NULLPTR) {
|
||||||
dev->scene->removeItem(b->offText);
|
tab.value()->scene->removeItem(b->offText);
|
||||||
delete b->offText;
|
delete b->offText;
|
||||||
b->offText = Q_NULLPTR;
|
b->offText = Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
@ -706,14 +766,14 @@ void controllerSetup::pageChanged(USBDEVICE* dev, int val)
|
||||||
{
|
{
|
||||||
b->onText = new QGraphicsTextItem(b->onCommand->text);
|
b->onText = new QGraphicsTextItem(b->onCommand->text);
|
||||||
b->onText->setDefaultTextColor(b->textColour);
|
b->onText->setDefaultTextColor(b->textColour);
|
||||||
dev->scene->addItem(b->onText);
|
tab.value()->scene->addItem(b->onText);
|
||||||
b->onText->setPos(b->pos.center().x() - b->onText->boundingRect().width() / 2,
|
b->onText->setPos(b->pos.center().x() - b->onText->boundingRect().width() / 2,
|
||||||
(b->pos.center().y() - b->onText->boundingRect().height() / 2) - 6);
|
(b->pos.center().y() - b->onText->boundingRect().height() / 2) - 6);
|
||||||
emit sendRequest(dev,usbFeatureType::featureButton,b->num,b->onCommand->text,b->icon,&b->backgroundOn);
|
emit sendRequest(dev,usbFeatureType::featureButton,b->num,b->onCommand->text,b->icon,&b->backgroundOn);
|
||||||
|
|
||||||
b->offText = new QGraphicsTextItem(b->offCommand->text);
|
b->offText = new QGraphicsTextItem(b->offCommand->text);
|
||||||
b->offText->setDefaultTextColor(b->textColour);
|
b->offText->setDefaultTextColor(b->textColour);
|
||||||
dev->scene->addItem(b->offText);
|
tab.value()->scene->addItem(b->offText);
|
||||||
b->offText->setPos(b->pos.center().x() - b->offText->boundingRect().width() / 2,
|
b->offText->setPos(b->pos.center().x() - b->offText->boundingRect().width() / 2,
|
||||||
(b->pos.center().y() - b->onText->boundingRect().height() / 2) + 6);
|
(b->pos.center().y() - b->onText->boundingRect().height() / 2) + 6);
|
||||||
}
|
}
|
||||||
|
@ -727,7 +787,7 @@ void controllerSetup::pageChanged(USBDEVICE* dev, int val)
|
||||||
if (k->page == lastPage)
|
if (k->page == lastPage)
|
||||||
{
|
{
|
||||||
if (k->text) {
|
if (k->text) {
|
||||||
dev->scene->removeItem(k->text);
|
tab.value()->scene->removeItem(k->text);
|
||||||
delete k->text;
|
delete k->text;
|
||||||
k->text = Q_NULLPTR;
|
k->text = Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
@ -736,7 +796,7 @@ void controllerSetup::pageChanged(USBDEVICE* dev, int val)
|
||||||
{
|
{
|
||||||
k->text = new QGraphicsTextItem(k->command->text);
|
k->text = new QGraphicsTextItem(k->command->text);
|
||||||
k->text->setDefaultTextColor(k->textColour);
|
k->text->setDefaultTextColor(k->textColour);
|
||||||
dev->scene->addItem(k->text);
|
tab.value()->scene->addItem(k->text);
|
||||||
k->text->setPos(k->pos.center().x() - k->text->boundingRect().width() / 2,
|
k->text->setPos(k->pos.center().x() - k->text->boundingRect().width() / 2,
|
||||||
(k->pos.center().y() - k->text->boundingRect().height() / 2));
|
(k->pos.center().y() - k->text->boundingRect().height() / 2));
|
||||||
}
|
}
|
||||||
|
@ -748,7 +808,9 @@ void controllerSetup::disableClicked(USBDEVICE* dev, bool clicked, QWidget* widg
|
||||||
{
|
{
|
||||||
// Disable checkbox has been clicked
|
// Disable checkbox has been clicked
|
||||||
emit programDisable(dev, clicked);
|
emit programDisable(dev, clicked);
|
||||||
|
|
||||||
widget->setEnabled(!clicked);
|
widget->setEnabled(!clicked);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void controllerSetup::setConnected(USBDEVICE* dev)
|
void controllerSetup::setConnected(USBDEVICE* dev)
|
||||||
|
@ -756,15 +818,16 @@ void controllerSetup::setConnected(USBDEVICE* dev)
|
||||||
QMutexLocker locker(mutex);
|
QMutexLocker locker(mutex);
|
||||||
|
|
||||||
|
|
||||||
if (dev->uiCreated)
|
auto tab = tabs.find(dev->path);
|
||||||
|
if (tab != tabs.end())
|
||||||
{
|
{
|
||||||
if (dev->connected)
|
if (dev->connected)
|
||||||
{
|
{
|
||||||
dev->message->setStyleSheet("QLabel { color : green; }");
|
tab.value()->message.setStyleSheet("QLabel { color : green; }");
|
||||||
dev->message->setText("Connected");
|
tab.value()->message.setText("Connected");
|
||||||
} else {
|
} else {
|
||||||
dev->message->setStyleSheet("QLabel { color : red; }");
|
tab.value()->message.setStyleSheet("QLabel { color : red; }");
|
||||||
dev->message->setText("Not Connected");
|
tab.value()->message.setText("Not Connected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -773,17 +836,60 @@ void controllerSetup::on_backupButton_clicked()
|
||||||
{
|
{
|
||||||
QString file = QFileDialog::getSaveFileName(this,"Select Backup Filename",".","Backup Files (*.ini)");
|
QString file = QFileDialog::getSaveFileName(this,"Select Backup Filename",".","Backup Files (*.ini)");
|
||||||
if (!file.isEmpty()) {
|
if (!file.isEmpty()) {
|
||||||
QFileInfo info = QFileInfo(file);
|
QString path = ui->tabWidget->currentWidget()->objectName();
|
||||||
emit backup(file, ui->tabWidget->currentWidget()->objectName());
|
emit backup(file, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void controllerSetup::on_restoreButton_clicked()
|
void controllerSetup::on_restoreButton_clicked()
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(mutex);
|
||||||
|
|
||||||
QString file = QFileDialog::getOpenFileName(this,"Select Backup Filename",".","Backup Files (*.ini)");
|
QString file = QFileDialog::getOpenFileName(this,"Select Backup Filename",".","Backup Files (*.ini)");
|
||||||
if (!file.isEmpty()) {
|
if (!file.isEmpty()) {
|
||||||
QFileInfo info = QFileInfo(file);
|
QString path = ui->tabWidget->currentWidget()->objectName();
|
||||||
emit restore(file, 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).arg(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).arg(QString(WFVIEW_VERSION)));
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||||
|
msgBox.setDefaultButton(QMessageBox::Cancel);
|
||||||
|
int ret= msgBox.exec();
|
||||||
|
if (ret == QMessageBox::Cancel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit restore(file, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QLayoutItem>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
@ -54,6 +55,40 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct tabContent {
|
||||||
|
QWidget tab;
|
||||||
|
QVBoxLayout mainLayout;
|
||||||
|
QHBoxLayout topLayout;
|
||||||
|
QWidget widget;
|
||||||
|
QVBoxLayout layout;
|
||||||
|
QCheckBox disabled;
|
||||||
|
QLabel message;
|
||||||
|
QGraphicsView view;
|
||||||
|
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 {
|
namespace Ui {
|
||||||
class controllerSetup;
|
class controllerSetup;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +102,7 @@ public:
|
||||||
~controllerSetup();
|
~controllerSetup();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void started();
|
||||||
void sendRequest(USBDEVICE* dev, usbFeatureType request, quint8 val=0, QString text="", QImage* img=Q_NULLPTR, QColor* color=Q_NULLPTR);
|
void sendRequest(USBDEVICE* dev, usbFeatureType request, quint8 val=0, QString text="", QImage* img=Q_NULLPTR, QColor* color=Q_NULLPTR);
|
||||||
void programDisable(USBDEVICE* dev, bool disable);
|
void programDisable(USBDEVICE* dev, bool disable);
|
||||||
void programPages(USBDEVICE* dev, int pages);
|
void programPages(USBDEVICE* dev, int pages);
|
||||||
|
@ -74,8 +110,8 @@ signals:
|
||||||
void restore(QString file, QString path);
|
void restore(QString file, QString path);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void init();
|
void init(usbDevMap* dev, QVector<BUTTON>* but, QVector<KNOB>* kb, QVector<COMMAND>* cmd, QMutex* mut);
|
||||||
void newDevice(USBDEVICE* dev, CONTROLLER* cntrl, QVector<BUTTON>* but, QVector<KNOB>* kb, QVector<COMMAND>* cmd, QMutex* mut);
|
void newDevice(USBDEVICE* dev);
|
||||||
void removeDevice(USBDEVICE* dev);
|
void removeDevice(USBDEVICE* dev);
|
||||||
void mousePressed(controllerScene *scene,QPoint p);
|
void mousePressed(controllerScene *scene,QPoint p);
|
||||||
void onEventIndexChanged(int index);
|
void onEventIndexChanged(int index);
|
||||||
|
@ -85,7 +121,7 @@ public slots:
|
||||||
void brightnessChanged(USBDEVICE* dev, int index);
|
void brightnessChanged(USBDEVICE* dev, int index);
|
||||||
void orientationChanged(USBDEVICE* dev, int index);
|
void orientationChanged(USBDEVICE* dev, int index);
|
||||||
void speedChanged(USBDEVICE* dev, int index);
|
void speedChanged(USBDEVICE* dev, int index);
|
||||||
void colorPicker(USBDEVICE* dev);
|
void colorPicker(USBDEVICE* dev, QPushButton* btn, QColor color);
|
||||||
void buttonOnColorClicked();
|
void buttonOnColorClicked();
|
||||||
void buttonOffColorClicked();
|
void buttonOffColorClicked();
|
||||||
void buttonIconClicked();
|
void buttonIconClicked();
|
||||||
|
@ -103,6 +139,7 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void deleteMyWidget(QWidget *);
|
||||||
usbDeviceType type = usbNone;
|
usbDeviceType type = usbNone;
|
||||||
Ui::controllerSetup* ui;
|
Ui::controllerSetup* ui;
|
||||||
QGraphicsTextItem* textItem;
|
QGraphicsTextItem* textItem;
|
||||||
|
@ -111,8 +148,8 @@ private:
|
||||||
QVector<BUTTON>* buttons;
|
QVector<BUTTON>* buttons;
|
||||||
QVector<KNOB>* knobs;
|
QVector<KNOB>* knobs;
|
||||||
QVector<COMMAND>* commands;
|
QVector<COMMAND>* commands;
|
||||||
|
usbDevMap* devices;
|
||||||
|
|
||||||
usbMap* controllers;
|
|
||||||
BUTTON* currentButton = Q_NULLPTR;
|
BUTTON* currentButton = Q_NULLPTR;
|
||||||
KNOB* currentKnob = Q_NULLPTR;
|
KNOB* currentKnob = Q_NULLPTR;
|
||||||
|
|
||||||
|
@ -137,6 +174,7 @@ private:
|
||||||
QLabel* noControllersText;
|
QLabel* noControllersText;
|
||||||
|
|
||||||
int numTabs=0;
|
int numTabs=0;
|
||||||
|
QMap<QString,tabContent*> tabs;
|
||||||
|
|
||||||
// Below are used for each tab:
|
// Below are used for each tab:
|
||||||
/*
|
/*
|
||||||
|
|
Plik diff jest za duży
Load Diff
|
@ -23,6 +23,8 @@
|
||||||
#include <QImageWriter>
|
#include <QImageWriter>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(USB_CONTROLLER) && QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
#if defined(USB_CONTROLLER) && QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||||
|
@ -94,12 +96,19 @@ struct KNOBVALUE {
|
||||||
struct USBDEVICE {
|
struct USBDEVICE {
|
||||||
USBDEVICE() {}
|
USBDEVICE() {}
|
||||||
USBDEVICE(USBTYPE type) : type(type) {}
|
USBDEVICE(USBTYPE type) : type(type) {}
|
||||||
|
|
||||||
USBTYPE type;
|
USBTYPE type;
|
||||||
|
bool detected = false;
|
||||||
bool remove = false;
|
bool remove = false;
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
bool uiCreated = false;
|
bool uiCreated = false;
|
||||||
bool disabled = 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;
|
hid_device* handle = NULL;
|
||||||
QString product = "";
|
QString product = "";
|
||||||
QString manufacturer = "";
|
QString manufacturer = "";
|
||||||
|
@ -129,6 +138,8 @@ struct USBDEVICE {
|
||||||
|
|
||||||
struct COMMAND {
|
struct COMMAND {
|
||||||
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) :
|
COMMAND(int index, QString text, usbCommandType cmdType, int command, unsigned char suffix) :
|
||||||
index(index), text(text), cmdType(cmdType), command(command), suffix(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) :
|
COMMAND(int index, QString text, usbCommandType cmdType, int command, int getCommand, unsigned char suffix) :
|
||||||
|
@ -158,7 +169,7 @@ struct BUTTON {
|
||||||
dev(dev), num(-1), name(name), pos(pos), textColour(textColour), onCommand(on), offCommand(off), on(onCommand->text), off(offCommand->text) {}
|
dev(dev), num(-1), name(name), pos(pos), textColour(textColour), onCommand(on), offCommand(off), on(onCommand->text), off(offCommand->text) {}
|
||||||
|
|
||||||
usbDeviceType dev;
|
usbDeviceType dev;
|
||||||
USBDEVICE* parent;
|
USBDEVICE* parent = Q_NULLPTR;
|
||||||
int page=1;
|
int page=1;
|
||||||
int num;
|
int num;
|
||||||
QString name;
|
QString name;
|
||||||
|
@ -167,7 +178,7 @@ struct BUTTON {
|
||||||
const COMMAND* onCommand = Q_NULLPTR;
|
const COMMAND* onCommand = Q_NULLPTR;
|
||||||
const COMMAND* offCommand = Q_NULLPTR;
|
const COMMAND* offCommand = Q_NULLPTR;
|
||||||
QGraphicsTextItem* onText = Q_NULLPTR;
|
QGraphicsTextItem* onText = Q_NULLPTR;
|
||||||
QGraphicsTextItem* offText;
|
QGraphicsTextItem* offText = Q_NULLPTR;
|
||||||
QString on;
|
QString on;
|
||||||
QString off;
|
QString off;
|
||||||
QString path;
|
QString path;
|
||||||
|
@ -187,7 +198,7 @@ struct KNOB {
|
||||||
dev(dev), num(num), name(""), pos(pos), textColour(textColour), command(command), cmd(command->text) {}
|
dev(dev), num(num), name(""), pos(pos), textColour(textColour), command(command), cmd(command->text) {}
|
||||||
|
|
||||||
usbDeviceType dev;
|
usbDeviceType dev;
|
||||||
USBDEVICE* parent;
|
USBDEVICE* parent = Q_NULLPTR;
|
||||||
int page=1;
|
int page=1;
|
||||||
int num;
|
int num;
|
||||||
QString name;
|
QString name;
|
||||||
|
@ -200,23 +211,7 @@ struct KNOB {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CONTROLLER {
|
typedef QMap<QString,USBDEVICE> usbDevMap;
|
||||||
CONTROLLER() {}
|
|
||||||
CONTROLLER(USBDEVICE* dev) : dev(dev) {}
|
|
||||||
bool disabled=false;
|
|
||||||
int sensitivity=1;
|
|
||||||
quint8 speed=2;
|
|
||||||
quint8 timeout=30;
|
|
||||||
quint8 brightness=2;
|
|
||||||
quint8 orientation=0;
|
|
||||||
QColor color=Qt::white;
|
|
||||||
int pages=1;
|
|
||||||
cmds lcd=cmdNone;
|
|
||||||
USBDEVICE* dev = Q_NULLPTR;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef QMap<QString,CONTROLLER> usbMap;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(USB_CONTROLLER)
|
#if defined(USB_CONTROLLER)
|
||||||
|
@ -230,7 +225,7 @@ public:
|
||||||
bool hotPlugEvent(const QByteArray & eventType, void * message, long * result);
|
bool hotPlugEvent(const QByteArray & eventType, void * message, long * result);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void init(QMutex* mut,usbMap* prefs ,QVector<BUTTON>* buts,QVector<KNOB>* knobs);
|
void init(QMutex* mut,usbDevMap* prefs ,QVector<BUTTON>* buts,QVector<KNOB>* knobs);
|
||||||
void run();
|
void run();
|
||||||
void runTimer();
|
void runTimer();
|
||||||
void ledControl(bool on, unsigned char num);
|
void ledControl(bool on, unsigned char num);
|
||||||
|
@ -251,8 +246,8 @@ signals:
|
||||||
void doShuttle(bool plus, quint8 level);
|
void doShuttle(bool plus, quint8 level);
|
||||||
void setBand(int band);
|
void setBand(int band);
|
||||||
void button(const COMMAND* cmd);
|
void button(const COMMAND* cmd);
|
||||||
void initUI();
|
void initUI(usbDevMap* devs, QVector<BUTTON>* but, QVector<KNOB>* kb, QVector<COMMAND>* cmd, QMutex* mut);
|
||||||
void newDevice(USBDEVICE* dev, CONTROLLER* cntrl, QVector<BUTTON>* but, QVector<KNOB>* kb, QVector<COMMAND>* cmd, QMutex* mut);
|
void newDevice(USBDEVICE* dev);
|
||||||
void removeDevice(USBDEVICE* dev);
|
void removeDevice(USBDEVICE* dev);
|
||||||
void setConnected(USBDEVICE* dev);
|
void setConnected(USBDEVICE* dev);
|
||||||
void changePage(USBDEVICE* dev, int page);
|
void changePage(USBDEVICE* dev, int page);
|
||||||
|
@ -273,8 +268,8 @@ private:
|
||||||
QVector<KNOB> defaultKnobs;
|
QVector<KNOB> defaultKnobs;
|
||||||
QVector<USBTYPE> knownDevices;
|
QVector<USBTYPE> knownDevices;
|
||||||
QVector<COMMAND> commands;
|
QVector<COMMAND> commands;
|
||||||
QMap<QString,USBDEVICE> usbDevices;
|
usbDevMap* devices;
|
||||||
usbMap *controllers;
|
|
||||||
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
|
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
|
||||||
QGamepad* gamepad=Q_NULLPTR;
|
QGamepad* gamepad=Q_NULLPTR;
|
||||||
#endif
|
#endif
|
||||||
|
|
128
wfmain.cpp
128
wfmain.cpp
|
@ -49,7 +49,6 @@ wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode
|
||||||
sat = new satelliteSetup();
|
sat = new satelliteSetup();
|
||||||
trxadj = new transceiverAdjustments();
|
trxadj = new transceiverAdjustments();
|
||||||
cw = new cwSender();
|
cw = new cwSender();
|
||||||
shut = new controllerSetup();
|
|
||||||
abtBox = new aboutbox();
|
abtBox = new aboutbox();
|
||||||
selRad = new selectRadio();
|
selRad = new selectRadio();
|
||||||
|
|
||||||
|
@ -76,7 +75,6 @@ wfmain::wfmain(const QString settingsFile, const QString logFile, bool debugMode
|
||||||
qRegisterMetaType<QVector<BUTTON>*>();
|
qRegisterMetaType<QVector<BUTTON>*>();
|
||||||
qRegisterMetaType<QVector<KNOB>*>();
|
qRegisterMetaType<QVector<KNOB>*>();
|
||||||
qRegisterMetaType<QVector<COMMAND>*>();
|
qRegisterMetaType<QVector<COMMAND>*>();
|
||||||
qRegisterMetaType<const CONTROLLER*>();
|
|
||||||
qRegisterMetaType<const COMMAND*>();
|
qRegisterMetaType<const COMMAND*>();
|
||||||
qRegisterMetaType<const USBDEVICE*>();
|
qRegisterMetaType<const USBDEVICE*>();
|
||||||
qRegisterMetaType<QList<radio_cap_packet>>();
|
qRegisterMetaType<QList<radio_cap_packet>>();
|
||||||
|
@ -351,9 +349,9 @@ void wfmain::rigConnections()
|
||||||
|
|
||||||
connect(this, SIGNAL(getVox()), rig, SLOT(getVox()));
|
connect(this, SIGNAL(getVox()), rig, SLOT(getVox()));
|
||||||
connect(this, SIGNAL(getMonitor()), rig, SLOT(getMonitor()));
|
connect(this, SIGNAL(getMonitor()), rig, SLOT(getMonitor()));
|
||||||
connect(this, SIGNAL(getComp()), rig, SLOT(getComp()));
|
connect(this, SIGNAL(getCompressor()), rig, SLOT(getCompressor()));
|
||||||
connect(this, SIGNAL(getNB()), rig, SLOT(getNB()));
|
connect(this, SIGNAL(getNb()), rig, SLOT(getNb()));
|
||||||
connect(this, SIGNAL(getNR()), rig, SLOT(getNR()));
|
connect(this, SIGNAL(getNb()), rig, SLOT(getNr()));
|
||||||
|
|
||||||
connect(this, SIGNAL(selectVFO(vfo_t)), rig, SLOT(selectVFO(vfo_t)));
|
connect(this, SIGNAL(selectVFO(vfo_t)), rig, SLOT(selectVFO(vfo_t)));
|
||||||
connect(this, SIGNAL(sendVFOSwap()), rig, SLOT(exchangeVFOs()));
|
connect(this, SIGNAL(sendVFOSwap()), rig, SLOT(exchangeVFOs()));
|
||||||
|
@ -509,7 +507,7 @@ void wfmain::rigConnections()
|
||||||
|
|
||||||
connect(this, SIGNAL(setVox(bool)), rig, SLOT(setVox(bool)));
|
connect(this, SIGNAL(setVox(bool)), rig, SLOT(setVox(bool)));
|
||||||
connect(this, SIGNAL(setMonitor(bool)), rig, SLOT(setMonitor(bool)));
|
connect(this, SIGNAL(setMonitor(bool)), rig, SLOT(setMonitor(bool)));
|
||||||
connect(this, SIGNAL(setComp(bool)), rig, SLOT(setComp(bool)));
|
connect(this, SIGNAL(setCompressor(bool)), rig, SLOT(setCompressor(bool)));
|
||||||
connect(this, SIGNAL(setNb(bool)), rig, SLOT(setNb(bool)));
|
connect(this, SIGNAL(setNb(bool)), rig, SLOT(setNb(bool)));
|
||||||
connect(this, SIGNAL(setNr(bool)), rig, SLOT(setNr(bool)));
|
connect(this, SIGNAL(setNr(bool)), rig, SLOT(setNr(bool)));
|
||||||
|
|
||||||
|
@ -531,7 +529,7 @@ void wfmain::rigConnections()
|
||||||
connect(this, SIGNAL(getPassband()), rig, SLOT(getPassband()));
|
connect(this, SIGNAL(getPassband()), rig, SLOT(getPassband()));
|
||||||
connect(this, SIGNAL(getMonitorGain()), rig, SLOT(getMonitorGain()));
|
connect(this, SIGNAL(getMonitorGain()), rig, SLOT(getMonitorGain()));
|
||||||
connect(this, SIGNAL(getVoxGain()), rig, SLOT(getVoxGain()));
|
connect(this, SIGNAL(getVoxGain()), rig, SLOT(getVoxGain()));
|
||||||
connect(this, SIGNAL(getAntiVoxGain()), rig, SLOT(getAntVoxGain()));
|
connect(this, SIGNAL(getAntiVoxGain()), rig, SLOT(getAntiVoxGain()));
|
||||||
connect(this, SIGNAL(getNBLevel()), rig, SLOT(getNBLevel()));
|
connect(this, SIGNAL(getNBLevel()), rig, SLOT(getNBLevel()));
|
||||||
connect(this, SIGNAL(getNRLevel()), rig, SLOT(getNRLevel()));
|
connect(this, SIGNAL(getNRLevel()), rig, SLOT(getNRLevel()));
|
||||||
connect(this, SIGNAL(getCompLevel()), rig, SLOT(getCompLevel()));
|
connect(this, SIGNAL(getCompLevel()), rig, SLOT(getCompLevel()));
|
||||||
|
@ -1697,6 +1695,10 @@ void wfmain::setupKeyShortcuts()
|
||||||
void wfmain::setupUsbControllerDevice()
|
void wfmain::setupUsbControllerDevice()
|
||||||
{
|
{
|
||||||
#if defined (USB_CONTROLLER)
|
#if defined (USB_CONTROLLER)
|
||||||
|
|
||||||
|
if (usbWindow == Q_NULLPTR) {
|
||||||
|
usbWindow = new controllerSetup();
|
||||||
|
}
|
||||||
usbControllerDev = new usbController();
|
usbControllerDev = new usbController();
|
||||||
usbControllerThread = new QThread(this);
|
usbControllerThread = new QThread(this);
|
||||||
usbControllerDev->moveToThread(usbControllerThread);
|
usbControllerDev->moveToThread(usbControllerThread);
|
||||||
|
@ -1706,23 +1708,23 @@ void wfmain::setupUsbControllerDevice()
|
||||||
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(button(const COMMAND*)), this, SLOT(buttonControl(const COMMAND*)));
|
||||||
connect(usbControllerDev, SIGNAL(setBand(int)), this, SLOT(setBand(int)));
|
connect(usbControllerDev, SIGNAL(setBand(int)), this, SLOT(setBand(int)));
|
||||||
connect(usbControllerDev, SIGNAL(removeDevice(USBDEVICE*)), shut, SLOT(removeDevice(USBDEVICE*)));
|
connect(usbControllerDev, SIGNAL(removeDevice(USBDEVICE*)), usbWindow, SLOT(removeDevice(USBDEVICE*)));
|
||||||
connect(usbControllerDev, SIGNAL(initUI()), shut, SLOT(init()));
|
connect(usbControllerDev, SIGNAL(initUI(usbDevMap*, QVector<BUTTON>*, QVector<KNOB>*, QVector<COMMAND>*, QMutex*)), usbWindow, SLOT(init(usbDevMap*, QVector<BUTTON>*, QVector<KNOB>*, QVector<COMMAND>*, QMutex*)));
|
||||||
connect(usbControllerDev, SIGNAL(changePage(USBDEVICE*, int)), shut, SLOT(pageChanged(USBDEVICE*, int)));
|
connect(usbControllerDev, SIGNAL(changePage(USBDEVICE*, int)), usbWindow, SLOT(pageChanged(USBDEVICE*, int)));
|
||||||
connect(usbControllerDev, SIGNAL(setConnected(USBDEVICE*)), shut, SLOT(setConnected(USBDEVICE*)));
|
connect(usbControllerDev, SIGNAL(setConnected(USBDEVICE*)), usbWindow, SLOT(setConnected(USBDEVICE*)));
|
||||||
connect(usbControllerDev, SIGNAL(newDevice(USBDEVICE*, CONTROLLER *, QVector<BUTTON>*, QVector<KNOB>*, QVector<COMMAND>*, QMutex*)), shut, SLOT(newDevice(USBDEVICE *,CONTROLLER *, QVector<BUTTON>*, QVector<KNOB>*, QVector<COMMAND>*,QMutex*)));
|
connect(usbControllerDev, SIGNAL(newDevice(USBDEVICE*)), usbWindow, SLOT(newDevice(USBDEVICE *)));
|
||||||
usbControllerThread->start(QThread::LowestPriority);
|
usbControllerThread->start(QThread::LowestPriority);
|
||||||
|
|
||||||
connect(shut, SIGNAL(sendRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)), usbControllerDev, SLOT(sendRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)));
|
connect(usbWindow, SIGNAL(sendRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)), usbControllerDev, SLOT(sendRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)));
|
||||||
connect(this, SIGNAL(sendControllerRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)), usbControllerDev, SLOT(sendRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)));
|
connect(this, SIGNAL(sendControllerRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)), usbControllerDev, SLOT(sendRequest(USBDEVICE*, usbFeatureType, quint8, QString, QImage*, QColor *)));
|
||||||
connect(shut, SIGNAL(programPages(USBDEVICE*, int)), usbControllerDev, SLOT(programPages(USBDEVICE*, int)));
|
connect(usbWindow, SIGNAL(programPages(USBDEVICE*, int)), usbControllerDev, SLOT(programPages(USBDEVICE*, int)));
|
||||||
connect(shut, SIGNAL(programDisable(USBDEVICE*, bool)), usbControllerDev, SLOT(programDisable(USBDEVICE*, bool)));
|
connect(usbWindow, SIGNAL(programDisable(USBDEVICE*, bool)), usbControllerDev, SLOT(programDisable(USBDEVICE*, bool)));
|
||||||
connect(this, SIGNAL(setPTT(bool)), usbControllerDev, SLOT(receivePTTStatus(bool)));
|
connect(this, SIGNAL(setPTT(bool)), usbControllerDev, SLOT(receivePTTStatus(bool)));
|
||||||
connect(this, SIGNAL(sendLevel(cmds, unsigned char)), usbControllerDev, SLOT(receiveLevel(cmds, unsigned char)));
|
connect(this, SIGNAL(sendLevel(cmds, unsigned char)), usbControllerDev, SLOT(receiveLevel(cmds, unsigned char)));
|
||||||
connect(this, SIGNAL(initUsbController(QMutex*,usbMap*,QVector<BUTTON>*,QVector<KNOB>*)), usbControllerDev, SLOT(init(QMutex*,usbMap*,QVector<BUTTON>*,QVector<KNOB>*)));
|
connect(this, SIGNAL(initUsbController(QMutex*,usbDevMap*,QVector<BUTTON>*,QVector<KNOB>*)), usbControllerDev, SLOT(init(QMutex*,usbDevMap*,QVector<BUTTON>*,QVector<KNOB>*)));
|
||||||
connect(this, SIGNAL(usbHotplug()), usbControllerDev, SLOT(run()));
|
connect(this, SIGNAL(usbHotplug()), usbControllerDev, SLOT(run()));
|
||||||
connect(shut, SIGNAL(backup(QString, QString)), usbControllerDev, SLOT(backupController(QString, QString)));
|
connect(usbWindow, SIGNAL(backup(QString, QString)), usbControllerDev, SLOT(backupController(QString, QString)));
|
||||||
connect(shut, SIGNAL(restore(QString, QString)), usbControllerDev, SLOT(restoreController(QString, QString)));
|
connect(usbWindow, SIGNAL(restore(QString, QString)), usbControllerDev, SLOT(restoreController(QString, QString)));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2515,12 +2517,12 @@ void wfmain::loadSettings()
|
||||||
settings->endArray();
|
settings->endArray();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
usbControllers.clear();
|
usbDevices.clear();
|
||||||
for (int nc = 0; nc < numControllers; nc++)
|
for (int nc = 0; nc < numControllers; nc++)
|
||||||
{
|
{
|
||||||
settings->setArrayIndex(nc);
|
settings->setArrayIndex(nc);
|
||||||
CONTROLLER tempPrefs;
|
USBDEVICE tempPrefs;
|
||||||
QString tempPath = settings->value("Path", "").toString();
|
tempPrefs.path = settings->value("Path", "").toString();
|
||||||
tempPrefs.disabled = settings->value("Disabled", false).toBool();
|
tempPrefs.disabled = settings->value("Disabled", false).toBool();
|
||||||
tempPrefs.sensitivity = settings->value("Sensitivity", 1).toInt();
|
tempPrefs.sensitivity = settings->value("Sensitivity", 1).toInt();
|
||||||
tempPrefs.pages = settings->value("Pages", 1).toInt();
|
tempPrefs.pages = settings->value("Pages", 1).toInt();
|
||||||
|
@ -2531,8 +2533,8 @@ void wfmain::loadSettings()
|
||||||
tempPrefs.color.setNamedColor(settings->value("Color", QColor(Qt::white).name(QColor::HexArgb)).toString());
|
tempPrefs.color.setNamedColor(settings->value("Color", QColor(Qt::white).name(QColor::HexArgb)).toString());
|
||||||
tempPrefs.lcd = (cmds)settings->value("LCD",0).toInt();
|
tempPrefs.lcd = (cmds)settings->value("LCD",0).toInt();
|
||||||
|
|
||||||
if (!tempPath.isEmpty()) {
|
if (!tempPrefs.path.isEmpty()) {
|
||||||
usbControllers.insert(tempPath,tempPrefs);
|
usbDevices.insert(tempPrefs.path,tempPrefs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings->endArray();
|
settings->endArray();
|
||||||
|
@ -2550,6 +2552,13 @@ void wfmain::loadSettings()
|
||||||
BUTTON butt;
|
BUTTON butt;
|
||||||
butt.path = settings->value("Path", "").toString();
|
butt.path = settings->value("Path", "").toString();
|
||||||
butt.page = settings->value("Page", 1).toInt();
|
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.dev = (usbDeviceType)settings->value("Dev", 0).toInt();
|
||||||
butt.num = settings->value("Num", 0).toInt();
|
butt.num = settings->value("Num", 0).toInt();
|
||||||
butt.name = settings->value("Name", "").toString();
|
butt.name = settings->value("Name", "").toString();
|
||||||
|
@ -2584,6 +2593,13 @@ void wfmain::loadSettings()
|
||||||
settings->setArrayIndex(nk);
|
settings->setArrayIndex(nk);
|
||||||
KNOB kb;
|
KNOB kb;
|
||||||
kb.path = settings->value("Path", "").toString();
|
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.page = settings->value("Page", 1).toInt();
|
||||||
kb.dev = (usbDeviceType)settings->value("Dev", 0).toInt();
|
kb.dev = (usbDeviceType)settings->value("Dev", 0).toInt();
|
||||||
kb.num = settings->value("Num", 0).toInt();
|
kb.num = settings->value("Num", 0).toInt();
|
||||||
|
@ -2606,7 +2622,7 @@ void wfmain::loadSettings()
|
||||||
if (prefs.enableUSBControllers) {
|
if (prefs.enableUSBControllers) {
|
||||||
// Setup USB Controller
|
// Setup USB Controller
|
||||||
setupUsbControllerDevice();
|
setupUsbControllerDevice();
|
||||||
emit initUsbController(&usbMutex,&usbControllers,&usbButtons,&usbKnobs);
|
emit initUsbController(&usbMutex,&usbDevices,&usbButtons,&usbKnobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3020,23 +3036,25 @@ void wfmain::saveSettings()
|
||||||
settings->beginWriteArray("Controllers");
|
settings->beginWriteArray("Controllers");
|
||||||
int nc=0;
|
int nc=0;
|
||||||
|
|
||||||
usbMap::const_iterator i = usbControllers.constBegin();
|
auto it = usbDevices.begin();
|
||||||
while (i != usbControllers.constEnd())
|
while (it != usbDevices.end())
|
||||||
{
|
{
|
||||||
|
auto dev = &it.value();
|
||||||
settings->setArrayIndex(nc);
|
settings->setArrayIndex(nc);
|
||||||
|
|
||||||
settings->setValue("Path", i.key());
|
settings->setValue("Model", dev->product);
|
||||||
settings->setValue("Disabled", i.value().disabled);
|
settings->setValue("Path", dev->path);
|
||||||
settings->setValue("Sensitivity", i.value().sensitivity);
|
settings->setValue("Disabled", dev->disabled);
|
||||||
settings->setValue("Brightness", i.value().brightness);
|
settings->setValue("Sensitivity", dev->sensitivity);
|
||||||
settings->setValue("Orientation", i.value().orientation);
|
settings->setValue("Brightness", dev->brightness);
|
||||||
settings->setValue("Speed", i.value().speed);
|
settings->setValue("Orientation", dev->orientation);
|
||||||
settings->setValue("Timeout", i.value().timeout);
|
settings->setValue("Speed", dev->speed);
|
||||||
settings->setValue("Pages", i.value().pages);
|
settings->setValue("Timeout", dev->timeout);
|
||||||
settings->setValue("Color", i.value().color.name(QColor::HexArgb));
|
settings->setValue("Pages", dev->pages);
|
||||||
settings->setValue("LCD", i.value().lcd);
|
settings->setValue("Color", dev->color.name(QColor::HexArgb));
|
||||||
|
settings->setValue("LCD", dev->lcd);
|
||||||
|
|
||||||
++i;
|
++it;
|
||||||
++nc;
|
++nc;
|
||||||
}
|
}
|
||||||
settings->endArray();
|
settings->endArray();
|
||||||
|
@ -5376,20 +5394,18 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e
|
||||||
|
|
||||||
#if defined (USB_CONTROLLER)
|
#if defined (USB_CONTROLLER)
|
||||||
// Send to USB Controllers if requested
|
// Send to USB Controllers if requested
|
||||||
usbMap::const_iterator i = usbControllers.constBegin();
|
auto i = usbDevices.begin();
|
||||||
while (i != usbControllers.constEnd())
|
while (i != usbDevices.end())
|
||||||
{
|
{
|
||||||
if (i.value().dev != Q_NULLPTR && i.value().dev->connected
|
if (i.value().connected && i.value().type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDWaterfall )
|
||||||
&& i.value().dev->type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDWaterfall )
|
|
||||||
{
|
{
|
||||||
lcdImage = wf->toPixmap().toImage();
|
lcdImage = wf->toPixmap().toImage();
|
||||||
emit sendControllerRequest(i.value().dev, usbFeatureType::featureLCD, 0, "", &lcdImage);
|
emit sendControllerRequest(&i.value(), usbFeatureType::featureLCD, 0, "", &lcdImage);
|
||||||
}
|
}
|
||||||
else if (i.value().dev != Q_NULLPTR && i.value().dev->connected
|
else if (i.value().connected && i.value().type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDSpectrum)
|
||||||
&& i.value().dev->type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDSpectrum)
|
|
||||||
{
|
{
|
||||||
lcdImage = plot->toPixmap().toImage();
|
lcdImage = plot->toPixmap().toImage();
|
||||||
emit sendControllerRequest(i.value().dev, usbFeatureType::featureLCD, 0, "", &lcdImage);
|
emit sendControllerRequest(&i.value(), usbFeatureType::featureLCD, 0, "", &lcdImage);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -9389,16 +9405,16 @@ void wfmain::on_enableUsbChk_clicked(bool checked)
|
||||||
usbControllerThread->wait();
|
usbControllerThread->wait();
|
||||||
usbControllerThread = Q_NULLPTR;
|
usbControllerThread = Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checked) {
|
if (checked) {
|
||||||
// Setup USB Controller
|
// Setup USB Controller
|
||||||
setupUsbControllerDevice();
|
setupUsbControllerDevice();
|
||||||
emit initUsbController(&usbMutex,&usbControllers,&usbButtons,&usbKnobs);
|
emit initUsbController(&usbMutex,&usbDevices,&usbButtons,&usbKnobs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (shut != Q_NULLPTR) {
|
if (usbWindow != Q_NULLPTR) {
|
||||||
if (shut->isVisible()) {
|
delete usbWindow;
|
||||||
shut->hide();
|
usbWindow = Q_NULLPTR;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -9406,14 +9422,14 @@ void wfmain::on_enableUsbChk_clicked(bool checked)
|
||||||
|
|
||||||
void wfmain::on_usbControllerBtn_clicked()
|
void wfmain::on_usbControllerBtn_clicked()
|
||||||
{
|
{
|
||||||
if (shut != Q_NULLPTR) {
|
if (usbWindow != Q_NULLPTR) {
|
||||||
if (shut->isVisible()) {
|
if (usbWindow->isVisible()) {
|
||||||
shut->hide();
|
usbWindow->hide();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qInfo(logUsbControl()) << "Showing USB Controller window";
|
qInfo(logUsbControl()) << "Showing USB Controller window";
|
||||||
shut->show();
|
usbWindow->show();
|
||||||
shut->raise();
|
usbWindow->raise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9432,7 +9448,7 @@ void wfmain::on_usbControllersResetBtn_clicked()
|
||||||
|
|
||||||
usbButtons.clear();
|
usbButtons.clear();
|
||||||
usbKnobs.clear();
|
usbKnobs.clear();
|
||||||
usbControllers.clear();
|
usbDevices.clear();
|
||||||
|
|
||||||
if (enabled) on_enableUsbChk_clicked(true); // Force connect of USB controllers
|
if (enabled) on_enableUsbChk_clicked(true); // Force connect of USB controllers
|
||||||
}
|
}
|
||||||
|
|
7
wfmain.h
7
wfmain.h
|
@ -266,7 +266,7 @@ signals:
|
||||||
void openShuttle();
|
void openShuttle();
|
||||||
void requestRigState();
|
void requestRigState();
|
||||||
void stateUpdated();
|
void stateUpdated();
|
||||||
void initUsbController(QMutex* mutex,usbMap* prefs ,QVector<BUTTON>* buts,QVector<KNOB>* knobs);
|
void initUsbController(QMutex* mutex,usbDevMap* devs ,QVector<BUTTON>* buts,QVector<KNOB>* knobs);
|
||||||
void setClusterUdpPort(int port);
|
void setClusterUdpPort(int port);
|
||||||
void setClusterEnableUdp(bool udp);
|
void setClusterEnableUdp(bool udp);
|
||||||
void setClusterEnableTcp(bool tcp);
|
void setClusterEnableTcp(bool tcp);
|
||||||
|
@ -1142,7 +1142,7 @@ private:
|
||||||
satelliteSetup *sat;
|
satelliteSetup *sat;
|
||||||
transceiverAdjustments *trxadj;
|
transceiverAdjustments *trxadj;
|
||||||
cwSender *cw;
|
cwSender *cw;
|
||||||
controllerSetup* shut;
|
controllerSetup* usbWindow = Q_NULLPTR;
|
||||||
aboutbox *abtBox;
|
aboutbox *abtBox;
|
||||||
selectRadio *selRad;
|
selectRadio *selRad;
|
||||||
loggingWindow *logWindow;
|
loggingWindow *logWindow;
|
||||||
|
@ -1193,7 +1193,7 @@ private:
|
||||||
QString typeName;
|
QString typeName;
|
||||||
QVector<BUTTON> usbButtons;
|
QVector<BUTTON> usbButtons;
|
||||||
QVector<KNOB> usbKnobs;
|
QVector<KNOB> usbKnobs;
|
||||||
usbMap usbControllers;
|
usbDevMap usbDevices;
|
||||||
QMutex usbMutex;
|
QMutex usbMutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1232,7 +1232,6 @@ Q_DECLARE_METATYPE(rigstate*)
|
||||||
Q_DECLARE_METATYPE(QVector <BUTTON>*)
|
Q_DECLARE_METATYPE(QVector <BUTTON>*)
|
||||||
Q_DECLARE_METATYPE(QVector <KNOB>*)
|
Q_DECLARE_METATYPE(QVector <KNOB>*)
|
||||||
Q_DECLARE_METATYPE(QVector <COMMAND>*)
|
Q_DECLARE_METATYPE(QVector <COMMAND>*)
|
||||||
Q_DECLARE_METATYPE(const CONTROLLER*)
|
|
||||||
Q_DECLARE_METATYPE(const COMMAND*)
|
Q_DECLARE_METATYPE(const COMMAND*)
|
||||||
Q_DECLARE_METATYPE(const USBDEVICE*)
|
Q_DECLARE_METATYPE(const USBDEVICE*)
|
||||||
Q_DECLARE_METATYPE(codecType)
|
Q_DECLARE_METATYPE(codecType)
|
||||||
|
|
|
@ -205,7 +205,7 @@ enum usbDeviceType { usbNone = 0, shuttleXpress, shuttlePro2,
|
||||||
StreamDeckOriginalMK2,StreamDeckXL,StreamDeckXLV2,StreamDeckPedal, StreamDeckPlus
|
StreamDeckOriginalMK2,StreamDeckXL,StreamDeckXLV2,StreamDeckPedal, StreamDeckPlus
|
||||||
};
|
};
|
||||||
|
|
||||||
enum usbCommandType{ commandButton, commandKnob };
|
enum usbCommandType{ commandButton, commandKnob, commandAny };
|
||||||
enum usbFeatureType { featureReset,featureResetKeys, featureEventsA, featureEventsB, featureFirmware, featureSerial, featureButton, featureSensitivity, featureBrightness,
|
enum usbFeatureType { featureReset,featureResetKeys, featureEventsA, featureEventsB, featureFirmware, featureSerial, featureButton, featureSensitivity, featureBrightness,
|
||||||
featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featureLCD, featureGraph };
|
featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featureLCD, featureGraph };
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue