Implement R9M Companion support (#5157)
[opentx.git] / companion / src / modeledit / setup.cpp
blob6168574f666413d9b52441c4beb99a929b371455
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include "setup.h"
22 #include "ui_setup.h"
23 #include "ui_setup_timer.h"
24 #include "ui_setup_module.h"
25 #include "switchitemmodel.h"
26 #include "helpers.h"
27 #include "appdata.h"
28 #include "modelprinter.h"
29 #include "multiprotocols.h"
30 #include "checklistdialog.h"
32 TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, GeneralSettings & generalSettings, Firmware * firmware, QWidget * prevFocus):
33 ModelPanel(parent, model, generalSettings, firmware),
34 timer(timer),
35 ui(new Ui::Timer)
37 Board::Type board = firmware->getBoard();
39 ui->setupUi(this);
41 lock = true;
43 // Name
44 int length = firmware->getCapability(TimersName);
45 if (length == 0) {
46 ui->name->hide();
48 else {
49 ui->name->setMaxLength(length);
50 ui->name->setText(timer.name);
53 // Mode
54 rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, TimersContext);
55 ui->mode->setModel(rawSwitchItemModel);
56 ui->mode->setCurrentIndex(ui->mode->findData(timer.mode.toValue()));
58 if (!firmware->getCapability(PermTimers)) {
59 ui->persistent->hide();
60 ui->persistentValue->hide();
63 ui->countdownBeep->setField(timer.countdownBeep, this);
64 ui->countdownBeep->addItem(tr("Silent"), TimerData::COUNTDOWN_SILENT);
65 ui->countdownBeep->addItem(tr("Beeps"), TimerData::COUNTDOWN_BEEPS);
66 if (IS_ARM(board) || IS_2560(board)) {
67 ui->countdownBeep->addItem(tr("Voice"), TimerData::COUNTDOWN_VOICE);
68 ui->countdownBeep->addItem(tr("Haptic"), TimerData::COUNTDOWN_HAPTIC);
71 ui->value->setMaximumTime(firmware->getMaxTimerStart());
73 ui->persistent->setField(timer.persistent, this);
74 ui->persistent->addItem(tr("Not persistent"), 0);
75 ui->persistent->addItem(tr("Persistent (flight)"), 1);
76 ui->persistent->addItem(tr("Persistent (manual reset)"), 2);
78 disableMouseScrolling();
79 QWidget::setTabOrder(prevFocus, ui->name);
80 QWidget::setTabOrder(ui->name, ui->value);
81 QWidget::setTabOrder(ui->value, ui->mode);
82 QWidget::setTabOrder(ui->mode, ui->countdownBeep);
83 QWidget::setTabOrder(ui->countdownBeep, ui->minuteBeep);
84 QWidget::setTabOrder(ui->minuteBeep, ui->persistent);
86 lock = false;
89 TimerPanel::~TimerPanel()
91 delete ui;
94 void TimerPanel::update()
96 rawSwitchItemModel->update();
98 int hour = timer.val / 3600;
99 int min = (timer.val - (hour * 3600)) / 60;
100 int sec = (timer.val - (hour * 3600)) % 60;
102 ui->value->setTime(QTime(hour, min, sec));
104 if (firmware->getCapability(PermTimers)) {
105 int sign = 1;
106 int pvalue = timer.pvalue;
107 if (pvalue < 0) {
108 pvalue = -pvalue;
109 sign = -1;
111 int hours = pvalue / 3600;
112 pvalue -= hours * 3600;
113 int minutes = pvalue / 60;
114 int seconds = pvalue % 60;
115 ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign<0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
118 ui->minuteBeep->setChecked(timer.minuteBeep);
121 QWidget * TimerPanel::getLastFocus()
123 return ui->persistent;
126 void TimerPanel::on_value_editingFinished()
128 unsigned val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second();
129 if (timer.val != val) {
130 timer.val = val;
131 emit modified();
135 void TimerPanel::on_mode_currentIndexChanged(int index)
137 if (!lock) {
138 timer.mode = RawSwitch(ui->mode->itemData(index).toInt());
139 emit modified();
143 void TimerPanel::on_minuteBeep_toggled(bool checked)
145 timer.minuteBeep = checked;
146 emit modified();
149 void TimerPanel::on_name_editingFinished()
151 if (QString(timer.name) != ui->name->text()) {
152 int length = ui->name->maxLength();
153 strncpy(timer.name, ui->name->text().toLatin1(), length);
154 emit modified();
158 /******************************************************************************/
160 #define FAILSAFE_CHANNEL_HOLD 2000
161 #define FAILSAFE_CHANNEL_NOPULSE 2001
163 #define MASK_PROTOCOL 1
164 #define MASK_CHANNELS_COUNT 2
165 #define MASK_RX_NUMBER 4
166 #define MASK_CHANNELS_RANGE 8
167 #define MASK_PPM_FIELDS 16
168 #define MASK_FAILSAFES 32
169 #define MASK_OPEN_DRAIN 64
170 #define MASK_MULTIMODULE 128
171 #define MASK_ANTENNA 256
172 #define MASK_MULTIOPTION 512
173 #define MASK_R9M 1024
175 quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT;
177 ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx):
178 ModelPanel(parent, model, generalSettings, firmware),
179 module(module),
180 moduleIdx(moduleIdx),
181 ui(new Ui::Module)
183 lock = true;
185 ui->setupUi(this);
187 QString label;
188 if (moduleIdx < 0) {
189 label = tr("Trainer Port");
190 if (IS_HORUS(firmware->getBoard())) {
191 ui->trainerMode->setItemData(TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
192 ui->trainerMode->setItemData(TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
194 if (generalSettings.hw_uartMode != UART_MODE_SBUS_TRAINER) {
195 ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1);
197 ui->trainerMode->setCurrentIndex(model.trainerMode);
198 if (!IS_HORUS_OR_TARANIS(firmware->getBoard())) {
199 ui->label_trainerMode->hide();
200 ui->trainerMode->hide();
202 ui->formLayout_col1->setSpacing(0);
204 else {
205 ui->label_trainerMode->hide();
206 ui->trainerMode->hide();
207 if (firmware->getCapability(NumModules) > 1) {
208 if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
209 if (moduleIdx == 0)
210 label = tr("Internal Radio System");
211 else
212 label = tr("External Radio Module");
214 else {
215 if (moduleIdx == 0)
216 label = tr("Radio System");
217 else
218 label = tr("Extra Radio System");
221 else {
222 label = tr("Radio System");
225 ui->label_module->setText(label);
227 // The protocols available on this board
228 for (int i=0; i<PULSES_PROTOCOL_LAST; i++) {
229 if (firmware->isAvailable((PulsesProtocol)i, moduleIdx)) {
230 ui->protocol->addItem(ModelPrinter::printModuleProtocol(i), (QVariant)i);
231 if (i == module.protocol)
232 ui->protocol->setCurrentIndex(ui->protocol->count()-1);
235 for (int i=0; i<=MM_RF_PROTO_LAST; i++) {
236 ui->multiProtocol->addItem(ModelPrinter::printMultiRfProtocol(i, false), (QVariant) i);
239 ui->btnGrpValueType->setId(ui->optPercent, FAILSAFE_DISPLAY_PERCENT);
240 ui->btnGrpValueType->setId(ui->optUs, FAILSAFE_DISPLAY_USEC);
241 ui->btnGrpValueType->button(failsafesValueDisplayType)->setChecked(true);
243 setupFailsafes();
245 disableMouseScrolling();
247 update();
249 connect(ui->protocol, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ModulePanel::onProtocolChanged);
250 connect(ui->multiProtocol, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ModulePanel::onMultiProtocolChanged);
251 connect(this, &ModulePanel::channelsRangeChanged, this, &ModulePanel::setupFailsafes);
252 connect(ui->btnGrpValueType, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &ModulePanel::onFailsafesDisplayValueTypeChanged);
254 lock = false;
258 ModulePanel::~ModulePanel()
260 delete ui;
263 bool ModulePanel::moduleHasFailsafes()
265 return (((PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_XJT_X16 || (PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_R9M)
266 && firmware->getCapability(HasFailsafe));;
269 void ModulePanel::setupFailsafes()
271 ChannelFailsafeWidgetsGroup grp;
272 const int start = module.channelsStart;
273 const int end = start + module.channelsCount;
274 const bool hasFailsafe = moduleHasFailsafes();
276 lock = true;
278 QMutableMapIterator<int, ChannelFailsafeWidgetsGroup> i(failsafeGroupsMap);
279 while (i.hasNext()) {
280 i.next();
281 grp = i.value();
282 ui->failsafesLayout->removeWidget(grp.label);
283 ui->failsafesLayout->removeWidget(grp.combo);
284 ui->failsafesLayout->removeWidget(grp.sbPercent);
285 ui->failsafesLayout->removeWidget(grp.sbUsec);
286 if (i.key() < start || i.key() >= end || !hasFailsafe) {
287 grp.label->deleteLater();
288 grp.combo->deleteLater();
289 grp.sbPercent->deleteLater();
290 grp.sbUsec->deleteLater();
291 i.remove();
295 if (!hasFailsafe)
296 return;
298 int row = 0;
299 int col = 0;
300 int channelMax = model->getChannelsMax();
301 int channelMaxUs = 512 * channelMax / 100 * 2;
303 for (int i = start; i < end; ++i) {
304 if (failsafeGroupsMap.contains(i)) {
305 grp = failsafeGroupsMap.value(i);
307 else {
308 QLabel * label = new QLabel(this);
309 label->setProperty("index", i);
310 label->setText(QString::number(i+1));
312 QComboBox * combo = new QComboBox(this);
313 combo->setProperty("index", i);
314 combo->addItem(tr("Value"), 0);
315 combo->addItem(tr("Hold"), FAILSAFE_CHANNEL_HOLD);
316 combo->addItem(tr("No Pulse"), FAILSAFE_CHANNEL_NOPULSE);
318 QDoubleSpinBox * sbDbl = new QDoubleSpinBox(this);
319 sbDbl->setProperty("index", i);
320 sbDbl->setMinimumSize(QSize(20, 0));
321 sbDbl->setRange(-channelMax, channelMax);
322 sbDbl->setSingleStep(0.1);
323 sbDbl->setDecimals(1);
325 QSpinBox * sbInt = new QSpinBox(this);
326 sbInt->setProperty("index", i);
327 sbInt->setMinimumSize(QSize(20, 0));
328 sbInt->setRange(-channelMaxUs, channelMaxUs);
329 sbInt->setSingleStep(1);
331 grp = ChannelFailsafeWidgetsGroup();
332 grp.combo = combo;
333 grp.sbPercent = sbDbl;
334 grp.sbUsec = sbInt;
335 grp.label = label;
336 failsafeGroupsMap.insert(i, grp);
338 connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(onFailsafeComboIndexChanged(int)));
339 connect(sbInt, SIGNAL(valueChanged(int)), this, SLOT(onFailsafeUsecChanged(int)));
340 connect(sbDbl, SIGNAL(valueChanged(double)), this, SLOT(onFailsafePercentChanged(double)));
343 ui->failsafesLayout->addWidget(grp.label, row, col, Qt::AlignHCenter);
344 ui->failsafesLayout->addWidget(grp.combo, row + 1, col, Qt::AlignHCenter);
345 ui->failsafesLayout->addWidget(grp.sbPercent, row + 2, col, Qt::AlignHCenter);
346 ui->failsafesLayout->addWidget(grp.sbUsec, row + 3, col, Qt::AlignHCenter);
347 grp.sbPercent->setVisible(failsafesValueDisplayType == FAILSAFE_DISPLAY_PERCENT);
348 grp.sbUsec->setVisible(failsafesValueDisplayType == FAILSAFE_DISPLAY_USEC);
350 updateFailsafe(i);
352 if (++col > 7) {
353 row += 4;
354 col = 0;
358 lock = false;
361 void ModulePanel::update()
363 unsigned int mask = 0;
364 PulsesProtocol protocol = (PulsesProtocol)module.protocol;
365 unsigned int max_rx_num = 63;
367 if (moduleIdx >= 0) {
368 mask |= MASK_PROTOCOL;
369 switch (protocol) {
370 case PULSES_PXX_R9M:
371 mask |= MASK_R9M;
372 case PULSES_PXX_XJT_X16:
373 case PULSES_PXX_XJT_D8:
374 case PULSES_PXX_XJT_LR12:
375 case PULSES_PXX_DJT:
376 mask |= MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
377 if (protocol==PULSES_PXX_XJT_X16 || protocol==PULSES_PXX_XJT_LR12 || protocol==PULSES_PXX_R9M)
378 mask |= MASK_RX_NUMBER;
379 if (IS_HORUS(firmware->getBoard()) && moduleIdx==0)
380 mask |= MASK_ANTENNA;
381 break;
382 case PULSES_LP45:
383 case PULSES_DSM2:
384 case PULSES_DSMX:
385 mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER;
386 module.channelsCount = 6;
387 max_rx_num = 20;
388 break;
389 case PULSES_CROSSFIRE:
390 mask |= MASK_CHANNELS_RANGE;
391 module.channelsCount = 16;
392 break;
393 case PULSES_PPM:
394 mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE| MASK_CHANNELS_COUNT;
395 if (IS_9XRPRO(firmware->getBoard())) {
396 mask |= MASK_OPEN_DRAIN;
398 break;
399 case PULSES_MULTIMODULE:
400 mask |= MASK_CHANNELS_RANGE | MASK_RX_NUMBER | MASK_MULTIMODULE;
401 max_rx_num = 15;
402 if (module.multi.rfProtocol == MM_RF_PROTO_DSM2)
403 mask |= MASK_CHANNELS_COUNT;
404 else
405 module.channelsCount = 16;
406 if (multiProtocols.getProtocol(module.multi.rfProtocol).optionsstr != nullptr)
407 mask |= MASK_MULTIOPTION;
408 break;
409 case PULSES_OFF:
410 break;
411 default:
412 break;
415 else if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
416 if (model->trainerMode == TRAINER_SLAVE_JACK) {
417 mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
420 else if (model->trainerMode != TRAINER_MASTER_JACK) {
421 mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
424 if (moduleHasFailsafes()) {
425 mask |= MASK_FAILSAFES;
428 ui->label_protocol->setVisible(mask & MASK_PROTOCOL);
429 ui->protocol->setVisible(mask & MASK_PROTOCOL);
430 ui->label_rxNumber->setVisible(mask & MASK_RX_NUMBER);
431 ui->rxNumber->setVisible(mask & MASK_RX_NUMBER);
432 ui->rxNumber->setMaximum(max_rx_num);
433 ui->rxNumber->setValue(module.modelId);
434 ui->label_channelsStart->setVisible(mask & MASK_CHANNELS_RANGE);
435 ui->channelsStart->setVisible(mask & MASK_CHANNELS_RANGE);
436 ui->channelsStart->setValue(module.channelsStart+1);
437 ui->label_channelsCount->setVisible(mask & MASK_CHANNELS_RANGE);
438 ui->channelsCount->setVisible(mask & MASK_CHANNELS_RANGE);
439 ui->channelsCount->setEnabled(mask & MASK_CHANNELS_COUNT);
440 ui->channelsCount->setValue(module.channelsCount);
441 ui->channelsCount->setSingleStep(firmware->getCapability(HasPPMStart) ? 1 : 2);
443 // PPM settings fields
444 ui->label_ppmPolarity->setVisible(mask & MASK_PPM_FIELDS);
445 ui->ppmPolarity->setVisible(mask & MASK_PPM_FIELDS);
446 ui->ppmPolarity->setCurrentIndex(module.ppm.pulsePol);
447 ui->label_ppmOutputType->setVisible(mask & MASK_OPEN_DRAIN);
448 ui->ppmOutputType->setVisible(mask & MASK_OPEN_DRAIN);
449 ui->ppmOutputType->setCurrentIndex(module.ppm.outputType);
450 ui->label_ppmDelay->setVisible(mask & MASK_PPM_FIELDS);
451 ui->ppmDelay->setVisible(mask & MASK_PPM_FIELDS);
452 ui->ppmDelay->setValue(module.ppm.delay);
453 ui->label_ppmFrameLength->setVisible(mask & MASK_PPM_FIELDS);
454 ui->ppmFrameLength->setVisible(mask & MASK_PPM_FIELDS);
455 ui->ppmFrameLength->setMinimum(module.channelsCount*(model->extendedLimits ? 2.250 : 2)+3.5);
456 ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength));
457 ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5);
459 // Antenna slection on Horus
460 ui->label_antenna->setVisible(mask & MASK_ANTENNA);
461 ui->antennaMode->setVisible(mask & MASK_ANTENNA);
462 ui->antennaMode->setCurrentIndex(module.pxx.external_antenna);
464 // R9M S.port output
465 ui->sportOut->setVisible(mask & MASK_R9M);
466 ui->label_sportOut->setVisible(mask & MASK_R9M);
467 ui->sportOut->setCurrentIndex(module.pxx.sport_out);
469 ui->r9mPower->setVisible(mask & MASK_R9M);
470 ui->label_r9mPower->setVisible(mask & MASK_R9M);
471 ui->r9mPower->setCurrentIndex(module.pxx.power);
474 // Multi settings fields
475 ui->label_multiProtocol->setVisible(mask & MASK_MULTIMODULE);
476 ui->multiProtocol->setVisible(mask & MASK_MULTIMODULE);
477 ui->multiProtocol->setCurrentIndex(module.multi.rfProtocol);
478 ui->label_multiSubType->setVisible(mask & MASK_MULTIMODULE);
479 ui->multiSubType->setVisible(mask & MASK_MULTIMODULE);
480 ui->label_option->setVisible(mask & MASK_MULTIOPTION);
481 ui->optionValue->setVisible(mask & MASK_MULTIOPTION);
483 if (mask & MASK_MULTIMODULE) {
484 int numEntries = multiProtocols.getProtocol(module.multi.rfProtocol).numSubytes();
485 if (module.multi.customProto)
486 numEntries=8;
487 // Removes extra items
488 ui->multiSubType->setMaxCount(numEntries);
489 for (int i=0; i < numEntries; i++) {
490 if (i < ui->multiSubType->count())
491 ui->multiSubType->setItemText(i, ModelPrinter::printMultiSubType(module.multi.rfProtocol, module.multi.customProto, i));
492 else
493 ui->multiSubType->addItem(ModelPrinter::printMultiSubType(module.multi.rfProtocol, module.multi.customProto, i), (QVariant) i);
497 if (mask & MASK_MULTIOPTION) {
498 auto pdef = multiProtocols.getProtocol(module.multi.rfProtocol);
499 ui->optionValue->setMinimum(pdef.getOptionMin());
500 ui->optionValue->setMaximum(pdef.getOptionMax());
501 ui->optionValue->setValue(module.multi.optionValue);
502 ui->label_option->setText(qApp->translate("Multiprotocols", qPrintable(pdef.optionsstr)));
504 ui->multiSubType->setCurrentIndex(module.subType);
506 ui->autoBind->setVisible(mask & MASK_MULTIMODULE);
507 ui->autoBind->setChecked(module.multi.autoBindMode ? Qt::Checked : Qt::Unchecked);
508 ui->lowPower->setVisible(mask & MASK_MULTIMODULE);
509 ui->lowPower->setChecked(module.multi.lowPowerMode ? Qt::Checked : Qt::Unchecked);
512 ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES);
513 ui->failsafeMode->setVisible(mask & MASK_FAILSAFES);
515 if ((mask & MASK_FAILSAFES) && module.failsafeMode == FAILSAFE_CUSTOM) {
516 if (ui->failsafesGroupBox->isHidden()) {
517 setupFailsafes();
518 ui->failsafesGroupBox->setVisible(true);
521 else {
522 ui->failsafesGroupBox->setVisible(false);
525 if (mask & MASK_FAILSAFES) {
526 ui->failsafeMode->setCurrentIndex(module.failsafeMode);
528 if (firmware->getCapability(ChannelsName)) {
529 int chan;
530 QString name;
531 QMapIterator<int, ChannelFailsafeWidgetsGroup> i(failsafeGroupsMap);
532 while (i.hasNext()) {
533 i.next();
534 chan = i.key();
535 name = QString(model->limitData[chan + module.channelsStart].name).trimmed();
536 if (name.isEmpty())
537 i.value().label->setText(QString::number(chan + 1));
538 else
539 i.value().label->setText(name);
544 if (mask & MASK_CHANNELS_RANGE) {
545 ui->channelsStart->setMaximum(33 - ui->channelsCount->value());
546 ui->channelsCount->setMaximum(qMin(16, 33-ui->channelsStart->value()));
550 void ModulePanel::on_trainerMode_currentIndexChanged(int index)
552 if (!lock) {
553 model->trainerMode = index;
554 update();
555 emit modified();
559 void ModulePanel::onProtocolChanged(int index)
561 if (!lock) {
562 module.protocol = ui->protocol->itemData(index).toInt();
563 update();
564 emit modified();
568 void ModulePanel::on_ppmPolarity_currentIndexChanged(int index)
570 module.ppm.pulsePol = index;
571 emit modified();
574 void ModulePanel::on_antennaMode_currentIndexChanged(int index)
576 module.pxx.external_antenna = index;
577 emit modified();
580 void ModulePanel::on_sportOut_currentIndexChanged(int index)
582 module.pxx.sport_out = index;
583 emit modified();
586 void ModulePanel::on_r9mPower_currentIndexChanged(int index)
588 module.pxx.power = index;
589 emit modified();
592 void ModulePanel::on_ppmOutputType_currentIndexChanged(int index)
594 module.ppm.outputType = index;
595 emit modified();
598 void ModulePanel::on_channelsCount_editingFinished()
600 if (!lock && module.channelsCount != ui->channelsCount->value()) {
601 module.channelsCount = ui->channelsCount->value();
602 update();
603 emit channelsRangeChanged();
604 emit modified();
608 void ModulePanel::on_channelsStart_editingFinished()
610 if (!lock && module.channelsStart != (unsigned)ui->channelsStart->value() - 1) {
611 module.channelsStart = (unsigned)ui->channelsStart->value() - 1;
612 update();
613 emit channelsRangeChanged();
614 emit modified();
618 void ModulePanel::on_ppmDelay_editingFinished()
620 if (!lock && module.ppm.delay != ui->ppmDelay->value()) {
621 // TODO only accept valid values
622 module.ppm.delay = ui->ppmDelay->value();
623 emit modified();
627 void ModulePanel::on_rxNumber_editingFinished()
629 if (module.modelId != (unsigned)ui->rxNumber->value()) {
630 module.modelId = (unsigned)ui->rxNumber->value();
631 emit modified();
635 void ModulePanel::on_ppmFrameLength_editingFinished()
637 int val = (ui->ppmFrameLength->value()-22.5) / 0.5;
638 if (module.ppm.frameLength != val) {
639 module.ppm.frameLength = val;
640 emit modified();
644 void ModulePanel::on_failsafeMode_currentIndexChanged(int value)
646 if (!lock) {
647 module.failsafeMode = value;
648 update();
649 emit modified();
653 void ModulePanel::onMultiProtocolChanged(int index)
655 if (!lock) {
656 lock=true;
657 module.multi.rfProtocol = (unsigned int) index;
658 unsigned int maxSubTypes = multiProtocols.getProtocol(index).numSubytes();
659 if (module.multi.customProto)
660 maxSubTypes=8;
661 module.subType = std::min(module.subType, maxSubTypes -1);
662 update();
663 emit modified();
664 lock = false;
668 void ModulePanel::on_optionValue_editingFinished()
670 if (module.multi.optionValue != ui->optionValue->value()) {
671 module.multi.optionValue = ui->optionValue->value();
672 emit modified();
676 void ModulePanel::on_multiSubType_currentIndexChanged(int index)
678 if (!lock) {
679 lock=true;
680 module.subType = index;
681 update();
682 emit modified();
683 lock = false;
687 void ModulePanel::on_autoBind_stateChanged(int state)
689 module.multi.autoBindMode = (state == Qt::Checked);
691 void ModulePanel::on_lowPower_stateChanged(int state)
693 module.multi.lowPowerMode = (state == Qt::Checked);
696 // updtSb (update spin box(es)): 0=none or bitmask of FailsafeValueDisplayTypes
697 void ModulePanel::setChannelFailsafeValue(const int channel, const int value, quint8 updtSb)
699 if (channel < 0 || channel >= CPN_MAX_CHNOUT)
700 return;
702 module.failsafeChannels[channel] = value;
703 double pctVal = divRoundClosest(value * 1000, 1024) / 10.0;
704 // qDebug() << value << pctVal;
706 if (failsafeGroupsMap.contains(channel)) {
707 const ChannelFailsafeWidgetsGroup & grp = failsafeGroupsMap.value(channel);
708 if ((updtSb & FAILSAFE_DISPLAY_PERCENT) && grp.sbPercent) {
709 grp.sbPercent->blockSignals(true);
710 grp.sbPercent->setValue(pctVal);
711 grp.sbPercent->blockSignals(false);
713 if ((updtSb & FAILSAFE_DISPLAY_USEC) && grp.sbUsec) {
714 grp.sbUsec->blockSignals(true);
715 grp.sbUsec->setValue(value);
716 grp.sbUsec->blockSignals(false);
719 if (!lock)
720 emit modified();
723 void ModulePanel::onFailsafeUsecChanged(int value)
725 if (!sender())
726 return;
728 bool ok = false;
729 int channel = sender()->property("index").toInt(&ok);
730 if (ok)
731 setChannelFailsafeValue(channel, value, FAILSAFE_DISPLAY_PERCENT);
734 void ModulePanel::onFailsafePercentChanged(double value)
736 if (!sender())
737 return;
739 bool ok = false;
740 int channel = sender()->property("index").toInt(&ok);
741 if (ok)
742 setChannelFailsafeValue(channel, divRoundClosest(int(value * 1024), 100), FAILSAFE_DISPLAY_USEC);
745 void ModulePanel::onFailsafeComboIndexChanged(int index)
747 if (!sender())
748 return;
750 QComboBox * cb = qobject_cast<QComboBox *>(sender());
752 if (cb && !lock) {
753 lock = true;
754 bool ok = false;
755 int channel = sender()->property("index").toInt(&ok);
756 if (ok) {
757 module.failsafeChannels[channel] = cb->itemData(index).toInt();
758 updateFailsafe(channel);
759 emit modified();
761 lock = false;
765 void ModulePanel::onFailsafesDisplayValueTypeChanged(int type)
767 if (failsafesValueDisplayType != type) {
768 failsafesValueDisplayType = type;
769 foreach (ChannelFailsafeWidgetsGroup grp, failsafeGroupsMap) {
770 if (grp.sbPercent)
771 grp.sbPercent->setVisible(type == FAILSAFE_DISPLAY_PERCENT);
772 if (grp.sbUsec)
773 grp.sbUsec->setVisible(type == FAILSAFE_DISPLAY_USEC);
778 void ModulePanel::onExtendedLimitsToggled()
780 double channelMaxPct = double(model->getChannelsMax());
781 int channelMaxUs = 512 * channelMaxPct / 100 * 2;
782 foreach (ChannelFailsafeWidgetsGroup grp, failsafeGroupsMap) {
783 if (grp.sbPercent)
784 grp.sbPercent->setRange(-channelMaxPct, channelMaxPct);
785 if (grp.sbUsec)
786 grp.sbUsec->setRange(-channelMaxUs, channelMaxUs);
790 void ModulePanel::updateFailsafe(int channel)
792 if (channel >= CPN_MAX_CHNOUT || !failsafeGroupsMap.contains(channel))
793 return;
795 const int failsafeValue = module.failsafeChannels[channel];
796 const ChannelFailsafeWidgetsGroup & grp = failsafeGroupsMap.value(channel);
797 const bool valDisable = (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE);
799 if (grp.combo)
800 grp.combo->setCurrentIndex(grp.combo->findData(valDisable ? failsafeValue : 0));
801 if (grp.sbPercent)
802 grp.sbPercent->setDisabled(valDisable);
803 if (grp.sbUsec)
804 grp.sbUsec->setDisabled(valDisable);
806 if (!valDisable)
807 setChannelFailsafeValue(channel, failsafeValue, (FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC));
810 /******************************************************************************/
812 SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
813 ModelPanel(parent, model, generalSettings, firmware),
814 ui(new Ui::Setup)
816 Board::Type board = firmware->getBoard();
818 lock = true;
820 memset(modules, 0, sizeof(modules));
822 ui->setupUi(this);
824 QRegExp rx(CHAR_FOR_NAMES_REGEX);
825 ui->name->setValidator(new QRegExpValidator(rx, this));
826 ui->name->setMaxLength(firmware->getCapability(ModelName));
828 if (firmware->getCapability(ModelImage)) {
829 QStringList items;
830 items.append("");
831 QString path = g.profile[g.id()].sdPath();
832 path.append("/IMAGES/");
833 QDir qd(path);
834 if (qd.exists()) {
835 QStringList filters;
836 if(IS_HORUS(board)) {
837 filters << "*.bmp" << "*.jpg" << "*.png";
838 foreach ( QString file, qd.entryList(filters, QDir::Files) ) {
839 QFileInfo fi(file);
840 QString temp = fi.fileName();
841 if (!items.contains(temp) && temp.length() <= 6+4) {
842 items.append(temp);
846 else {
847 filters << "*.bmp";
848 foreach (QString file, qd.entryList(filters, QDir::Files)) {
849 QFileInfo fi(file);
850 QString temp = fi.completeBaseName();
851 if (!items.contains(temp) && temp.length() <= 10+4) {
852 items.append(temp);
857 if (!items.contains(model.bitmap)) {
858 items.append(model.bitmap);
860 items.sort();
861 foreach (QString file, items) {
862 ui->image->addItem(file);
863 if (file == model.bitmap) {
864 ui->image->setCurrentIndex(ui->image->count()-1);
865 QString fileName = path;
866 fileName.append(model.bitmap);
867 if (!IS_HORUS(board))
868 fileName.append(".bmp");
869 QImage image(fileName);
870 if (image.isNull() && !IS_HORUS(board)) {
871 fileName = path;
872 fileName.append(model.bitmap);
873 fileName.append(".BMP");
874 image.load(fileName);
876 if (!image.isNull()) {
877 if (IS_HORUS(board)) {
878 ui->imagePreview->setFixedSize(QSize(192, 114));
879 ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(192, 114)));
881 else {
882 ui->imagePreview->setFixedSize(QSize(64, 32));
883 ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(64, 32)));
889 else {
890 ui->image->hide();
891 ui->modelImage_label->hide();
892 ui->imagePreview->hide();
895 QWidget * prevFocus = ui->image;
896 for (int i=0; i<CPN_MAX_TIMERS; i++) {
897 if (i<firmware->getCapability(Timers)) {
898 timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus);
899 ui->gridLayout->addWidget(timers[i], 1+i, 1);
900 connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified);
901 prevFocus = timers[i]->getLastFocus();
903 else {
904 foreach(QLabel *label, findChildren<QLabel *>(QRegExp(QString("label_timer%1").arg(i+1)))) {
905 label->hide();
910 if (firmware->getCapability(HasTopLcd)) {
911 ui->toplcdTimer->setField(model.toplcdTimer, this);
912 for (int i=0; i<CPN_MAX_TIMERS; i++) {
913 if (i<firmware->getCapability(Timers)) {
914 ui->toplcdTimer->addItem(tr("Timer %1").arg(i+1), i);
918 else {
919 ui->toplcdTimerLabel->hide();
920 ui->toplcdTimer->hide();
923 if (!firmware->getCapability(HasDisplayText)) {
924 ui->displayText->hide();
925 ui->editText->hide();
928 if (!firmware->getCapability(GlobalFunctions)) {
929 ui->gfEnabled->hide();
932 // Beep Center checkboxes
933 prevFocus = ui->trimsDisplay;
934 int analogs = CPN_MAX_STICKS + getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders);
935 int genAryIdx = 0;
936 for (int i=0; i < analogs + firmware->getCapability(RotaryEncoders); i++) {
937 RawSource src((i < analogs) ? SOURCE_TYPE_STICK : SOURCE_TYPE_ROTARY_ENCODER, (i < analogs) ? i : analogs - i);
938 QCheckBox * checkbox = new QCheckBox(this);
939 checkbox->setProperty("index", i);
940 checkbox->setText(src.toString(&model, &generalSettings));
941 ui->centerBeepLayout->addWidget(checkbox, 0, i+1);
942 connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool)));
943 centerBeepCheckboxes << checkbox;
944 if (IS_HORUS_OR_TARANIS(board)) {
945 if (src.isPot(&genAryIdx) && !generalSettings.isPotAvailable(genAryIdx)) {
946 checkbox->hide();
948 else if (src.isSlider(&genAryIdx) && !generalSettings.isSliderAvailable(genAryIdx)) {
949 checkbox->hide();
952 QWidget::setTabOrder(prevFocus, checkbox);
953 prevFocus = checkbox;
956 // Startup switches warnings
957 for (int i=0; i<getBoardCapability(board, Board::Switches); i++) {
958 Board::SwitchInfo switchInfo = Boards::getSwitchInfo(board, i);
959 switchInfo.config = Board::SwitchType(generalSettings.switchConfig[i]);
960 if (switchInfo.config == Board::SWITCH_NOT_AVAILABLE || switchInfo.config == Board::SWITCH_TOGGLE) {
961 continue;
963 RawSource src(RawSourceType::SOURCE_TYPE_SWITCH, i);
964 QLabel * label = new QLabel(this);
965 QSlider * slider = new QSlider(this);
966 QCheckBox * cb = new QCheckBox(this);
967 slider->setProperty("index", i);
968 slider->setOrientation(Qt::Vertical);
969 slider->setMinimum(0);
970 slider->setInvertedAppearance(true);
971 slider->setInvertedControls(true);
972 slider->setTickPosition(QSlider::TicksBothSides);
973 slider->setMinimumSize(QSize(30, 50));
974 slider->setMaximumSize(QSize(50, 50));
975 slider->setSingleStep(1);
976 slider->setPageStep(1);
977 slider->setTickInterval(1);
978 label->setText(src.toString(&model, &generalSettings));
979 slider->setMaximum(switchInfo.config == Board::SWITCH_3POS ? 2 : 1);
980 cb->setProperty("index", i);
981 ui->switchesStartupLayout->addWidget(label, 0, i+1);
982 ui->switchesStartupLayout->setAlignment(label, Qt::AlignCenter);
983 ui->switchesStartupLayout->addWidget(slider, 1, i+1);
984 ui->switchesStartupLayout->setAlignment(slider, Qt::AlignCenter);
985 ui->switchesStartupLayout->addWidget(cb, 2, i+1);
986 ui->switchesStartupLayout->setAlignment(cb, Qt::AlignCenter);
987 connect(slider, SIGNAL(valueChanged(int)), this, SLOT(startupSwitchEdited(int)));
988 connect(cb, SIGNAL(toggled(bool)), this, SLOT(startupSwitchToggled(bool)));
989 startupSwitchesSliders << slider;
990 startupSwitchesCheckboxes << cb;
991 QWidget::setTabOrder(prevFocus, slider);
992 QWidget::setTabOrder(slider, cb);
993 prevFocus = cb;
996 // Pot warnings
997 prevFocus = ui->potWarningMode;
998 if (IS_HORUS_OR_TARANIS(board)) {
999 for (int i=0; i<getBoardCapability(board, Board::Pots)+getBoardCapability(board, Board::Sliders); i++) {
1000 RawSource src(SOURCE_TYPE_STICK, CPN_MAX_STICKS + i);
1001 QCheckBox * cb = new QCheckBox(this);
1002 cb->setProperty("index", i);
1003 cb->setText(src.toString(&model, &generalSettings));
1004 ui->potWarningLayout->addWidget(cb, 0, i+1);
1005 connect(cb, SIGNAL(toggled(bool)), this, SLOT(potWarningToggled(bool)));
1006 potWarningCheckboxes << cb;
1007 if (src.isPot(&genAryIdx) && !generalSettings.isPotAvailable(genAryIdx)) {
1008 cb->hide();
1010 else if (src.isSlider(&genAryIdx) && !generalSettings.isSliderAvailable(genAryIdx)) {
1011 cb->hide();
1013 QWidget::setTabOrder(prevFocus, cb);
1014 prevFocus = cb;
1017 else {
1018 ui->label_potWarning->hide();
1019 ui->potWarningMode->hide();
1022 if (IS_ARM(board)) {
1023 ui->trimsDisplay->setField(model.trimsDisplay, this);
1025 else {
1026 ui->labelTrimsDisplay->hide();
1027 ui->trimsDisplay->hide();
1030 for (int i=0; i<firmware->getCapability(NumModules); i++) {
1031 modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i);
1032 ui->modulesLayout->addWidget(modules[i]);
1033 connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified);
1034 connect(this, &SetupPanel::extendedLimitsToggled, modules[i], &ModulePanel::onExtendedLimitsToggled);
1037 if (firmware->getCapability(ModelTrainerEnable)) {
1038 modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1);
1039 ui->modulesLayout->addWidget(modules[CPN_MAX_MODULES]);
1040 connect(modules[CPN_MAX_MODULES], &ModulePanel::modified, this, &SetupPanel::modified);
1043 disableMouseScrolling();
1045 lock = false;
1048 SetupPanel::~SetupPanel()
1050 delete ui;
1053 void SetupPanel::on_extendedLimits_toggled(bool checked)
1055 model->extendedLimits = checked;
1056 emit extendedLimitsToggled();
1057 emit modified();
1060 void SetupPanel::on_throttleWarning_toggled(bool checked)
1062 model->disableThrottleWarning = !checked;
1063 emit modified();
1066 void SetupPanel::on_throttleReverse_toggled(bool checked)
1068 model->throttleReversed = checked;
1069 emit modified();
1072 void SetupPanel::on_extendedTrims_toggled(bool checked)
1074 model->extendedTrims = checked;
1075 emit modified();
1078 void SetupPanel::on_trimIncrement_currentIndexChanged(int index)
1080 model->trimInc = index-2;
1081 emit modified();
1084 void SetupPanel::on_throttleSource_currentIndexChanged(int index)
1086 if (!lock) {
1087 model->thrTraceSrc = index;
1088 emit modified();
1092 void SetupPanel::on_name_editingFinished()
1094 if (QString(model->name) != ui->name->text()) {
1095 int length = ui->name->maxLength();
1096 strncpy(model->name, ui->name->text().toLatin1(), length);
1097 emit modified();
1101 void SetupPanel::on_image_currentIndexChanged(int index)
1103 if (!lock) {
1104 Board::Type board = firmware->getBoard();
1105 strncpy(model->bitmap, ui->image->currentText().toLatin1(), 10);
1106 QString path = g.profile[g.id()].sdPath();
1107 path.append("/IMAGES/");
1108 QDir qd(path);
1109 if (qd.exists()) {
1110 QString fileName=path;
1111 fileName.append(model->bitmap);
1112 if (!IS_HORUS(board))
1113 fileName.append(".bmp");
1114 QImage image(fileName);
1115 if (image.isNull() && !IS_HORUS(board)) {
1116 fileName=path;
1117 fileName.append(model->bitmap);
1118 fileName.append(".BMP");
1119 image.load(fileName);
1121 if (!image.isNull()) {
1122 if (IS_HORUS(board)) {
1123 ui->imagePreview->setFixedSize(QSize(192, 114));
1124 ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(192, 114)));
1126 else {
1127 ui->imagePreview->setFixedSize(QSize(64, 32));
1128 ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(64, 32)));
1131 else {
1132 ui->imagePreview->clear();
1135 else {
1136 ui->imagePreview->clear();
1138 emit modified();
1142 void SetupPanel::populateThrottleSourceCB()
1144 Board::Type board = firmware->getBoard();
1145 lock = true;
1146 ui->throttleSource->clear();
1147 ui->throttleSource->addItem(QObject::tr("THR"));
1148 for (int i=0; i<getBoardCapability(board, Board::Pots)+getBoardCapability(board, Board::Sliders); i++) {
1149 ui->throttleSource->addItem(firmware->getAnalogInputName(4+i), i);
1151 for (int i=0; i<firmware->getCapability(Outputs); i++) {
1152 ui->throttleSource->addItem(RawSource(SOURCE_TYPE_CH, i).toString(model, &generalSettings));
1154 ui->throttleSource->setCurrentIndex(model->thrTraceSrc);
1155 lock = false;
1158 void SetupPanel::update()
1160 ui->name->setText(model->name);
1161 ui->throttleReverse->setChecked(model->throttleReversed);
1162 populateThrottleSourceCB();
1163 ui->throttleWarning->setChecked(!model->disableThrottleWarning);
1164 ui->trimIncrement->setCurrentIndex(model->trimInc+2);
1165 ui->throttleTrim->setChecked(model->thrTrim);
1166 ui->extendedLimits->setChecked(model->extendedLimits);
1167 ui->extendedTrims->setChecked(model->extendedTrims);
1168 ui->displayText->setChecked(model->displayChecklist);
1169 ui->editText->setEnabled(model->displayChecklist);
1170 ui->gfEnabled->setChecked(!model->noGlobalFunctions);
1172 updateBeepCenter();
1173 updateStartupSwitches();
1175 if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
1176 updatePotWarnings();
1179 for (int i=0; i<firmware->getCapability(Timers); i++) {
1180 timers[i]->update();
1183 for (int i=0; i<CPN_MAX_MODULES+1; i++) {
1184 if (modules[i]) {
1185 modules[i]->update();
1190 void SetupPanel::updateBeepCenter()
1192 for (int i=0; i<centerBeepCheckboxes.size(); i++) {
1193 centerBeepCheckboxes[i]->setChecked(model->beepANACenter & (0x01 << i));
1197 void SetupPanel::updateStartupSwitches()
1199 lock = true;
1201 uint64_t switchStates = model->switchWarningStates;
1202 uint64_t value;
1204 for (int i=0; i<startupSwitchesSliders.size(); i++) {
1205 QSlider * slider = startupSwitchesSliders[i];
1206 QCheckBox * cb = startupSwitchesCheckboxes[i];
1207 int index = slider->property("index").toInt();
1208 bool enabled = !(model->switchWarningEnable & (1 << index));
1209 if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
1210 value = (switchStates >> (2*index)) & 0x03;
1211 if (generalSettings.switchConfig[index] != Board::SWITCH_3POS && value == 2) {
1212 value = 1;
1215 else {
1216 value = (i==0 ? switchStates & 0x3 : switchStates & 0x1);
1217 switchStates >>= (i==0 ? 2 : 1);
1219 slider->setValue(value);
1220 slider->setEnabled(enabled);
1221 cb->setChecked(enabled);
1224 lock = false;
1227 void SetupPanel::startupSwitchEdited(int value)
1229 if (!lock) {
1230 int shift = 0;
1231 uint64_t mask;
1232 int index = sender()->property("index").toInt();
1234 if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
1235 shift = index * 2;
1236 mask = 0x03ull << shift;
1238 else {
1239 if (index == 0) {
1240 mask = 0x03;
1242 else {
1243 shift = index+1;
1244 mask = 0x01ull << shift;
1248 model->switchWarningStates &= ~mask;
1250 if (IS_HORUS_OR_TARANIS(firmware->getBoard()) && generalSettings.switchConfig[index] != Board::SWITCH_3POS) {
1251 if (value == 1) {
1252 value = 2;
1256 if (value) {
1257 model->switchWarningStates |= ((uint64_t)value << shift);
1260 updateStartupSwitches();
1261 emit modified();
1265 void SetupPanel::startupSwitchToggled(bool checked)
1267 if (!lock) {
1268 int index = sender()->property("index").toInt();
1270 if (checked)
1271 model->switchWarningEnable &= ~(1 << index);
1272 else
1273 model->switchWarningEnable |= (1 << index);
1275 updateStartupSwitches();
1276 emit modified();
1280 void SetupPanel::updatePotWarnings()
1282 lock = true;
1283 ui->potWarningMode->setCurrentIndex(model->potsWarningMode);
1284 for (int i=0; i<potWarningCheckboxes.size(); i++) {
1285 QCheckBox *checkbox = potWarningCheckboxes[i];
1286 int index = checkbox->property("index").toInt();
1287 checkbox->setChecked(!model->potsWarningEnabled[index]);
1288 checkbox->setDisabled(model->potsWarningMode == 0);
1290 lock = false;
1293 void SetupPanel::potWarningToggled(bool checked)
1295 if (!lock) {
1296 int index = sender()->property("index").toInt();
1297 model->potsWarningEnabled[index] = !checked;
1298 updatePotWarnings();
1299 emit modified();
1303 void SetupPanel::on_potWarningMode_currentIndexChanged(int index)
1305 if (!lock) {
1306 model->potsWarningMode = index;
1307 updatePotWarnings();
1308 emit modified();
1312 void SetupPanel::on_displayText_toggled(bool checked)
1314 model->displayChecklist = checked;
1315 ui->editText->setEnabled(checked);
1316 emit modified();
1319 void SetupPanel::on_gfEnabled_toggled(bool checked)
1321 model->noGlobalFunctions = !checked;
1322 emit modified();
1325 void SetupPanel::on_throttleTrim_toggled(bool checked)
1327 model->thrTrim = checked;
1328 emit modified();
1331 void SetupPanel::onBeepCenterToggled(bool checked)
1333 if (!lock) {
1334 int index = sender()->property("index").toInt();
1335 unsigned int mask = (0x01 << index);
1336 if (checked)
1337 model->beepANACenter |= mask;
1338 else
1339 model->beepANACenter &= ~mask;
1340 emit modified();
1344 void SetupPanel::on_editText_clicked()
1346 ChecklistDialog *g = new ChecklistDialog(this, ui->name->text());
1347 g->exec();