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.
23 #include "ui_setup_timer.h"
24 #include "ui_setup_module.h"
27 #include "modelprinter.h"
29 TimerPanel::TimerPanel(QWidget
*parent
, ModelData
& model
, TimerData
& timer
, GeneralSettings
& generalSettings
, Firmware
* firmware
, QWidget
* prevFocus
):
30 ModelPanel(parent
, model
, generalSettings
, firmware
),
34 BoardEnum board
= firmware
->getBoard();
41 int length
= firmware
->getCapability(TimersName
);
46 ui
->name
->setMaxLength(length
);
47 ui
->name
->setText(timer
.name
);
51 populateSwitchCB(ui
->mode
, timer
.mode
, generalSettings
, TimersContext
);
53 if (!firmware
->getCapability(PermTimers
)) {
54 ui
->persistent
->hide();
55 ui
->persistentValue
->hide();
58 ui
->countdownBeep
->setField(timer
.countdownBeep
, this);
59 ui
->countdownBeep
->addItem(tr("Silent"), TimerData::COUNTDOWN_SILENT
);
60 ui
->countdownBeep
->addItem(tr("Beeps"), TimerData::COUNTDOWN_BEEPS
);
61 if (IS_ARM(board
) || IS_2560(board
)) {
62 ui
->countdownBeep
->addItem(tr("Voice"), TimerData::COUNTDOWN_VOICE
);
63 ui
->countdownBeep
->addItem(tr("Haptic"), TimerData::COUNTDOWN_HAPTIC
);
66 ui
->value
->setMaximumTime(firmware
->getMaxTimerStart());
68 ui
->persistent
->setField(timer
.persistent
, this);
69 ui
->persistent
->addItem(tr("Not persistent"), 0);
70 ui
->persistent
->addItem(tr("Persistent (flight)"), 1);
71 ui
->persistent
->addItem(tr("Persistent (manual reset)"), 2);
73 disableMouseScrolling();
74 QWidget::setTabOrder(prevFocus
, ui
->name
);
75 QWidget::setTabOrder(ui
->name
, ui
->value
);
76 QWidget::setTabOrder(ui
->value
, ui
->mode
);
77 QWidget::setTabOrder(ui
->mode
, ui
->countdownBeep
);
78 QWidget::setTabOrder(ui
->countdownBeep
, ui
->minuteBeep
);
79 QWidget::setTabOrder(ui
->minuteBeep
, ui
->persistent
);
84 TimerPanel::~TimerPanel()
89 void TimerPanel::update()
91 int hour
= timer
.val
/ 3600;
92 int min
= (timer
.val
- (hour
* 3600)) / 60;
93 int sec
= (timer
.val
- (hour
* 3600)) % 60;
95 ui
->value
->setTime(QTime(hour
, min
, sec
));
97 if (firmware
->getCapability(PermTimers
)) {
99 int pvalue
= timer
.pvalue
;
104 int hours
= pvalue
/ 3600;
105 pvalue
-= hours
* 3600;
106 int minutes
= pvalue
/ 60;
107 int seconds
= pvalue
% 60;
108 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')));
111 ui
->minuteBeep
->setChecked(timer
.minuteBeep
);
114 QWidget
* TimerPanel::getLastFocus()
116 return ui
->persistent
;
119 void TimerPanel::on_value_editingFinished()
121 timer
.val
= ui
->value
->time().hour()*3600 + ui
->value
->time().minute()*60 + ui
->value
->time().second();
125 void TimerPanel::on_mode_currentIndexChanged(int index
)
128 timer
.mode
= RawSwitch(ui
->mode
->itemData(index
).toInt());
133 void TimerPanel::on_minuteBeep_toggled(bool checked
)
135 timer
.minuteBeep
= checked
;
139 void TimerPanel::on_name_editingFinished()
141 int length
= ui
->name
->maxLength();
142 strncpy(timer
.name
, ui
->name
->text().toLatin1(), length
);
146 /******************************************************************************/
148 #define FAILSAFE_CHANNEL_HOLD 2000
149 #define FAILSAFE_CHANNEL_NOPULSE 2001
151 ModulePanel::ModulePanel(QWidget
* parent
, ModelData
& model
, ModuleData
& module
, GeneralSettings
& generalSettings
, Firmware
* firmware
, int moduleIdx
):
152 ModelPanel(parent
, model
, generalSettings
, firmware
),
154 moduleIdx(moduleIdx
),
163 label
= tr("Trainer Port");
164 if (generalSettings
.hw_uartMode
!= UART_MODE_SBUS_TRAINER
) {
165 ui
->trainerMode
->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT
, 0, Qt::UserRole
- 1);
167 ui
->trainerMode
->setCurrentIndex(model
.trainerMode
);
168 if (!IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
169 ui
->label_trainerMode
->hide();
170 ui
->trainerMode
->hide();
174 ui
->label_trainerMode
->hide();
175 ui
->trainerMode
->hide();
176 if (firmware
->getCapability(NumModules
) > 1) {
177 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
179 label
= tr("Internal Radio System");
181 label
= tr("External Radio Module");
185 label
= tr("Radio System");
187 label
= tr("Extra Radio System");
191 label
= tr("Radio System");
194 ui
->label_module
->setText(label
);
196 // The protocols available on this board
197 for (int i
=0; i
<PULSES_PROTOCOL_LAST
; i
++) {
198 if (firmware
->isAvailable((PulsesProtocol
)i
, moduleIdx
)) {
199 ui
->protocol
->addItem(ModelPrinter::printModuleProtocol(i
), (QVariant
)i
);
200 if (i
== module
.protocol
) ui
->protocol
->setCurrentIndex(ui
->protocol
->count()-1);
204 for (int i
=0; i
<=MM_RF_PROTO_LAST
; i
++) {
205 ui
->multiProtocol
->addItem(ModelPrinter::printMultiRfProtocol(i
, false), (QVariant
) i
);
208 if (firmware
->getCapability(HasFailsafe
)) {
209 for (int i
=0; i
<maxChannels
; i
++) {
210 QLabel
* label
= new QLabel(this);
211 label
->setText(QString::number(i
+1));
212 QComboBox
* combo
= new QComboBox(this);
213 combo
->setProperty("index", i
);
214 combo
->addItem(tr("Value"), 0);
215 combo
->addItem(tr("Hold"), FAILSAFE_CHANNEL_HOLD
);
216 combo
->addItem(tr("No Pulse"), FAILSAFE_CHANNEL_NOPULSE
);
217 QDoubleSpinBox
* spinbox
= new QDoubleSpinBox(this);
218 spinbox
->setMinimumSize(QSize(20, 0));
219 spinbox
->setRange(-150, 150);
220 spinbox
->setSingleStep(0.1);
221 spinbox
->setDecimals(1);
222 label
->setProperty("index", i
);
223 spinbox
->setProperty("index", i
);
224 ui
->failsafesLayout
->addWidget(label
, 3*(i
/8), i
%8, Qt::AlignHCenter
);
225 ui
->failsafesLayout
->addWidget(combo
, 1+3*(i
/8), i
%8, Qt::AlignHCenter
);
226 ui
->failsafesLayout
->addWidget(spinbox
, 2+3*(i
/8), i
%8, Qt::AlignHCenter
);
227 failsafeGroups
[i
].combo
= combo
;
228 failsafeGroups
[i
].spinbox
= spinbox
;
229 failsafeGroups
[i
].label
= label
;
231 connect(combo
, SIGNAL(currentIndexChanged(int)), this, SLOT(onFailsafeComboIndexChanged(int)));
232 connect(spinbox
, SIGNAL(valueChanged(double)), this, SLOT(onFailsafeSpinChanged(double)));
236 disableMouseScrolling();
241 ModulePanel::~ModulePanel()
246 #define MASK_PROTOCOL 1
247 #define MASK_CHANNELS_COUNT 2
248 #define MASK_RX_NUMBER 4
249 #define MASK_CHANNELS_RANGE 8
250 #define MASK_PPM_FIELDS 16
251 #define MASK_FAILSAFES 32
252 #define MASK_OPEN_DRAIN 64
253 #define MASK_MULTIMODULE 128
255 void ModulePanel::update()
257 unsigned int mask
= 0;
258 PulsesProtocol protocol
= (PulsesProtocol
)module
.protocol
;
259 unsigned int max_rx_num
= 63;
261 if (moduleIdx
>= 0) {
262 mask
|= MASK_PROTOCOL
;
264 case PULSES_PXX_XJT_X16
:
265 case PULSES_PXX_XJT_D8
:
266 case PULSES_PXX_XJT_LR12
:
268 mask
|= MASK_CHANNELS_RANGE
| MASK_CHANNELS_COUNT
;
269 if (protocol
==PULSES_PXX_XJT_X16
) mask
|= MASK_FAILSAFES
| MASK_RX_NUMBER
;
270 if (protocol
==PULSES_PXX_XJT_LR12
) mask
|= MASK_RX_NUMBER
;
275 mask
|= MASK_CHANNELS_RANGE
| MASK_RX_NUMBER
;
276 module
.channelsCount
= 6;
279 case PULSES_CROSSFIRE
:
280 mask
|= MASK_CHANNELS_RANGE
;
281 module
.channelsCount
= 16;
284 mask
|= MASK_PPM_FIELDS
| MASK_CHANNELS_RANGE
| MASK_CHANNELS_COUNT
;
285 if (IS_9XRPRO(firmware
->getBoard())) {
286 mask
|= MASK_OPEN_DRAIN
;
289 case PULSES_MULTIMODULE
:
290 mask
|= MASK_CHANNELS_RANGE
| MASK_RX_NUMBER
| MASK_MULTIMODULE
;
297 else if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
298 if (model
->trainerMode
== TRAINER_SLAVE_JACK
) {
299 mask
|= MASK_PPM_FIELDS
| MASK_CHANNELS_RANGE
| MASK_CHANNELS_COUNT
;
302 else if (model
->trainerMode
!= TRAINER_MASTER_JACK
) {
303 mask
|= MASK_PPM_FIELDS
| MASK_CHANNELS_RANGE
| MASK_CHANNELS_COUNT
;
306 ui
->label_protocol
->setVisible(mask
& MASK_PROTOCOL
);
307 ui
->protocol
->setVisible(mask
& MASK_PROTOCOL
);
308 ui
->label_rxNumber
->setVisible(mask
& MASK_RX_NUMBER
);
309 ui
->rxNumber
->setVisible(mask
& MASK_RX_NUMBER
);
310 ui
->rxNumber
->setMaximum(max_rx_num
);
311 ui
->rxNumber
->setValue(module
.modelId
);
312 ui
->label_channelsStart
->setVisible(mask
& MASK_CHANNELS_RANGE
);
313 ui
->channelsStart
->setVisible(mask
& MASK_CHANNELS_RANGE
);
314 ui
->channelsStart
->setValue(module
.channelsStart
+1);
315 ui
->label_channelsCount
->setVisible(mask
& MASK_CHANNELS_RANGE
);
316 ui
->channelsCount
->setVisible(mask
& MASK_CHANNELS_RANGE
);
317 ui
->channelsCount
->setEnabled(mask
& MASK_CHANNELS_COUNT
);
318 ui
->channelsCount
->setValue(module
.channelsCount
);
319 ui
->channelsCount
->setSingleStep(firmware
->getCapability(HasPPMStart
) ? 1 : 2);
321 // PPM settings fields
322 ui
->label_ppmPolarity
->setVisible(mask
& MASK_PPM_FIELDS
);
323 ui
->ppmPolarity
->setVisible(mask
& MASK_PPM_FIELDS
);
324 ui
->ppmPolarity
->setCurrentIndex(module
.ppm
.pulsePol
);
325 ui
->label_ppmOutputType
->setVisible(mask
& MASK_OPEN_DRAIN
);
326 ui
->ppmOutputType
->setVisible(mask
& MASK_OPEN_DRAIN
);
327 ui
->ppmOutputType
->setCurrentIndex(module
.ppm
.outputType
);
328 ui
->label_ppmDelay
->setVisible(mask
& MASK_PPM_FIELDS
);
329 ui
->ppmDelay
->setVisible(mask
& MASK_PPM_FIELDS
);
330 ui
->ppmDelay
->setValue(module
.ppm
.delay
);
331 ui
->label_ppmFrameLength
->setVisible(mask
& MASK_PPM_FIELDS
);
332 ui
->ppmFrameLength
->setVisible(mask
& MASK_PPM_FIELDS
);
333 ui
->ppmFrameLength
->setMinimum(module
.channelsCount
*(model
->extendedLimits
? 2.250 : 2)+3.5);
334 ui
->ppmFrameLength
->setMaximum(firmware
->getCapability(PPMFrameLength
));
335 ui
->ppmFrameLength
->setValue(22.5+((double)module
.ppm
.frameLength
)*0.5);
337 // Multi settings fields
338 ui
->label_multiProtocol
->setVisible(mask
& MASK_MULTIMODULE
);
339 ui
->multiProtocol
->setVisible(mask
& MASK_MULTIMODULE
);
340 ui
->multiProtocol
->setCurrentIndex(module
.multi
.rfProtocol
);
341 ui
->label_multiSubType
->setVisible(mask
& MASK_MULTIMODULE
);
342 ui
->multiSubType
->setVisible(mask
& MASK_MULTIMODULE
);
344 if (mask
& MASK_MULTIMODULE
) {
345 int numEntries
= getNumSubtypes(static_cast<MultiModuleRFProtocols
>(module
.multi
.rfProtocol
));
346 if (module
.multi
.customProto
)
348 // Removes extra items
349 ui
->multiSubType
->setMaxCount(numEntries
);
350 for (int i
=0; i
< numEntries
; i
++) {
351 if (i
< ui
->multiSubType
->count())
352 ui
->multiSubType
->setItemText(i
, ModelPrinter::printMultiSubType(module
.multi
.rfProtocol
, module
.multi
.customProto
, i
));
354 ui
->multiSubType
->addItem(ModelPrinter::printMultiSubType(module
.multi
.rfProtocol
, module
.multi
.customProto
, i
), (QVariant
) i
);
357 ui
->multiSubType
->setCurrentIndex(module
.subType
);
359 ui
->autoBind
->setVisible(mask
& MASK_MULTIMODULE
);
360 ui
->autoBind
->setChecked(module
.multi
.autoBindMode
? Qt::Checked
: Qt::Unchecked
);
361 ui
->lowPower
->setVisible(mask
& MASK_MULTIMODULE
);
362 ui
->lowPower
->setChecked(module
.multi
.lowPowerMode
? Qt::Checked
: Qt::Unchecked
);
365 if (firmware
->getCapability(HasFailsafe
)) {
366 ui
->label_failsafeMode
->setVisible(mask
& MASK_FAILSAFES
);
367 ui
->failsafeMode
->setVisible(mask
& MASK_FAILSAFES
);
368 ui
->failsafeMode
->setCurrentIndex(module
.failsafeMode
);
369 ui
->failsafesFrame
->setEnabled(module
.failsafeMode
== FAILSAFE_CUSTOM
);
370 if (firmware
->getCapability(ChannelsName
) > 0) {
371 for(int i
=0; i
<maxChannels
;i
++) {
372 QString name
= QString(model
->limitData
[i
+module
.channelsStart
].name
).trimmed();
373 if (!name
.isEmpty()) {
374 failsafeGroups
[i
].label
->setText(name
);
377 failsafeGroups
[i
].label
->setText(QString::number(i
+1));
386 ui
->failsafesLayoutLabel
->setVisible(mask
& MASK_FAILSAFES
);
387 ui
->failsafesFrame
->setVisible(mask
& MASK_FAILSAFES
);
389 if (mask
& MASK_CHANNELS_RANGE
) {
390 ui
->channelsStart
->setMaximum(33 - ui
->channelsCount
->value());
391 ui
->channelsCount
->setMaximum(qMin(16, 33-ui
->channelsStart
->value()));
395 void ModulePanel::on_trainerMode_currentIndexChanged(int index
)
398 model
->trainerMode
= index
;
404 void ModulePanel::on_protocol_currentIndexChanged(int index
)
407 module
.protocol
= ui
->protocol
->itemData(index
).toInt();
413 void ModulePanel::on_ppmPolarity_currentIndexChanged(int index
)
415 module
.ppm
.pulsePol
= index
;
419 void ModulePanel::on_ppmOutputType_currentIndexChanged(int index
)
421 module
.ppm
.outputType
= index
;
425 void ModulePanel::on_channelsCount_editingFinished()
428 module
.channelsCount
= ui
->channelsCount
->value();
434 void ModulePanel::on_channelsStart_editingFinished()
437 module
.channelsStart
= ui
->channelsStart
->value() - 1;
443 void ModulePanel::on_ppmDelay_editingFinished()
446 // TODO only accept valid values
447 module
.ppm
.delay
= ui
->ppmDelay
->value();
452 void ModulePanel::on_rxNumber_editingFinished()
454 module
.modelId
= ui
->rxNumber
->value();
458 void ModulePanel::on_ppmFrameLength_editingFinished()
460 module
.ppm
.frameLength
= (ui
->ppmFrameLength
->value()-22.5) / 0.5;
464 void ModulePanel::on_failsafeMode_currentIndexChanged(int value
)
467 module
.failsafeMode
= value
;
473 void ModulePanel::onFailsafeSpinChanged(double value
)
476 int channel
= sender()->property("index").toInt();
477 module
.failsafeChannels
[channel
] = (value
*1024)/100;
482 void ModulePanel::onFailsafeComboIndexChanged(int index
)
486 int channel
= sender()->property("index").toInt();
487 module
.failsafeChannels
[channel
] = ((QComboBox
*)sender())->itemData(index
).toInt();
488 updateFailsafe(channel
);
494 void ModulePanel::on_multiProtocol_currentIndexChanged(int index
)
498 module
.multi
.rfProtocol
= index
;
499 unsigned int maxSubTypes
= getNumSubtypes(static_cast<MultiModuleRFProtocols
>(index
));
500 if (module
.multi
.customProto
)
502 module
.subType
= std::min(module
.subType
, maxSubTypes
-1);
509 void ModulePanel::on_multiSubType_currentIndexChanged(int index
)
513 module
.subType
= index
;
520 void ModulePanel::on_autoBind_stateChanged(int state
)
522 module
.multi
.autoBindMode
= (state
== Qt::Checked
);
524 void ModulePanel::on_lowPower_stateChanged(int state
)
526 module
.multi
.lowPowerMode
= (state
== Qt::Checked
);
529 void ModulePanel::updateFailsafe(int channel
)
531 int failsafeValue
= module
.failsafeChannels
[channel
];
532 QComboBox
* combo
= failsafeGroups
[channel
].combo
;
533 QDoubleSpinBox
* spinbox
= failsafeGroups
[channel
].spinbox
;
534 if (failsafeValue
== FAILSAFE_CHANNEL_HOLD
) {
535 combo
->setCurrentIndex(1);
536 spinbox
->setEnabled(false);
537 spinbox
->setValue(0);
539 else if (failsafeValue
== FAILSAFE_CHANNEL_NOPULSE
) {
540 combo
->setCurrentIndex(2);
541 spinbox
->setEnabled(false);
542 spinbox
->setValue(0);
545 combo
->setCurrentIndex(0);
546 spinbox
->setEnabled(true);
547 spinbox
->setValue(((double)failsafeValue
*100)/1024);
551 /******************************************************************************/
553 SetupPanel::SetupPanel(QWidget
* parent
, ModelData
& model
, GeneralSettings
& generalSettings
, Firmware
* firmware
):
554 ModelPanel(parent
, model
, generalSettings
, firmware
),
557 BoardEnum board
= firmware
->getBoard();
561 memset(modules
, 0, sizeof(modules
));
565 QRegExp
rx(CHAR_FOR_NAMES_REGEX
);
566 ui
->name
->setValidator(new QRegExpValidator(rx
, this));
567 ui
->name
->setMaxLength(firmware
->getCapability(ModelName
));
569 if (firmware
->getCapability(ModelImage
)) {
572 QString path
= g
.profile
[g
.id()].sdPath();
573 path
.append("/IMAGES/");
577 filters
<< "*.bmp" << "*.bmp";
578 foreach ( QString file
, qd
.entryList(filters
, QDir::Files
) ) {
580 QString temp
= fi
.completeBaseName();
581 if (!items
.contains(temp
) && temp
.length() <= 10+4) {
586 if (!items
.contains(model
.bitmap
)) {
587 items
.append(model
.bitmap
);
590 foreach ( QString file
, items
) {
591 ui
->image
->addItem(file
);
592 if (file
== model
.bitmap
) {
593 ui
->image
->setCurrentIndex(ui
->image
->count()-1);
594 QString fileName
= path
;
595 fileName
.append(model
.bitmap
);
596 fileName
.append(".bmp");
597 QImage
image(fileName
);
598 if (image
.isNull()) {
600 fileName
.append(model
.bitmap
);
601 fileName
.append(".BMP");
602 image
.load(fileName
);
604 if (!image
.isNull()) {
605 ui
->imagePreview
->setPixmap(QPixmap::fromImage(image
.scaled( 64,32)));;
612 ui
->modelImage_label
->hide();
613 ui
->imagePreview
->hide();
616 QWidget
* prevFocus
= ui
->image
;
617 for (int i
=0; i
<CPN_MAX_TIMERS
; i
++) {
618 if (i
<firmware
->getCapability(Timers
)) {
619 timers
[i
] = new TimerPanel(this, model
, model
.timers
[i
], generalSettings
, firmware
, prevFocus
);
620 ui
->gridLayout
->addWidget(timers
[i
], 1+i
, 1);
621 connect(timers
[i
], SIGNAL(modified()), this, SLOT(onChildModified()));
622 prevFocus
= timers
[i
]->getLastFocus();
625 foreach(QLabel
*label
, findChildren
<QLabel
*>(QRegExp(QString("label_timer%1").arg(i
+1)))) {
631 if (firmware
->getCapability(HasTopLcd
)) {
632 ui
->toplcdTimer
->setField(model
.toplcdTimer
, this);
633 for (int i
=0; i
<CPN_MAX_TIMERS
; i
++) {
634 if (i
<firmware
->getCapability(Timers
)) {
635 ui
->toplcdTimer
->addItem(tr("Timer %1").arg(i
+1), i
);
640 ui
->toplcdTimerLabel
->hide();
641 ui
->toplcdTimer
->hide();
644 if (!firmware
->getCapability(HasDisplayText
)) {
645 ui
->displayText
->hide();
648 if (!firmware
->getCapability(GlobalFunctions
)) {
649 ui
->gfEnabled
->hide();
652 // Beep Center checkboxes
653 prevFocus
= ui
->trimsDisplay
;
654 int analogs
= CPN_MAX_STICKS
+ firmware
->getCapability(Pots
) + firmware
->getCapability(Sliders
);
655 for (int i
=0; i
<analogs
+firmware
->getCapability(RotaryEncoders
); i
++) {
656 QCheckBox
* checkbox
= new QCheckBox(this);
657 checkbox
->setProperty("index", i
);
658 checkbox
->setText(i
<analogs
? firmware
->getAnalogInputName(i
) : RotaryEncoderString(i
-analogs
));
659 ui
->centerBeepLayout
->addWidget(checkbox
, 0, i
+1);
660 connect(checkbox
, SIGNAL(toggled(bool)), this, SLOT(onBeepCenterToggled(bool)));
661 centerBeepCheckboxes
<< checkbox
;
662 if (IS_HORUS_OR_TARANIS(board
)) {
663 RawSource
src(SOURCE_TYPE_STICK
, i
);
664 if (src
.isPot() && !generalSettings
.isPotAvailable(i
-CPN_MAX_STICKS
)) {
667 else if (src
.isSlider() && !generalSettings
.isSliderAvailable(i
-CPN_MAX_STICKS
-firmware
->getCapability(Pots
))) {
671 QWidget::setTabOrder(prevFocus
, checkbox
);
672 prevFocus
= checkbox
;
675 // Startup switches warnings
676 for (int i
=0; i
<firmware
->getCapability(Switches
); i
++) {
677 Firmware::Switch sw
= firmware
->getSwitch(i
);
678 if (IS_HORUS_OR_TARANIS(board
)) {
679 sw
.type
= GeneralSettings::SwitchConfig(generalSettings
.switchConfig
[i
]);
681 if (sw
.type
== GeneralSettings::SWITCH_NONE
|| sw
.type
== GeneralSettings::SWITCH_TOGGLE
) {
684 QLabel
* label
= new QLabel(this);
685 QSlider
* slider
= new QSlider(this);
686 QCheckBox
* cb
= new QCheckBox(this);
687 slider
->setProperty("index", i
);
688 slider
->setOrientation(Qt::Vertical
);
689 slider
->setMinimum(0);
690 slider
->setInvertedAppearance(true);
691 slider
->setTickPosition(QSlider::TicksBothSides
);
692 slider
->setMinimumSize(QSize(30, 50));
693 slider
->setMaximumSize(QSize(50, 50));
694 slider
->setSingleStep(1);
695 slider
->setPageStep(1);
696 slider
->setTickInterval(1);
697 label
->setText(sw
.name
);
698 slider
->setMaximum(sw
.type
== GeneralSettings::SWITCH_3POS
? 2 : 1);
699 cb
->setProperty("index", i
);
700 ui
->switchesStartupLayout
->addWidget(label
, 0, i
+1);
701 ui
->switchesStartupLayout
->setAlignment(label
, Qt::AlignCenter
);
702 ui
->switchesStartupLayout
->addWidget(slider
, 1, i
+1);
703 ui
->switchesStartupLayout
->setAlignment(slider
, Qt::AlignCenter
);
704 ui
->switchesStartupLayout
->addWidget(cb
, 2, i
+1);
705 ui
->switchesStartupLayout
->setAlignment(cb
, Qt::AlignCenter
);
706 connect(slider
, SIGNAL(valueChanged(int)), this, SLOT(startupSwitchEdited(int)));
707 connect(cb
, SIGNAL(toggled(bool)), this, SLOT(startupSwitchToggled(bool)));
708 startupSwitchesSliders
<< slider
;
709 startupSwitchesCheckboxes
<< cb
;
710 QWidget::setTabOrder(prevFocus
, slider
);
711 QWidget::setTabOrder(slider
, cb
);
716 prevFocus
= ui
->potWarningMode
;
717 if (IS_HORUS_OR_TARANIS(board
)) {
718 for (int i
=0; i
<firmware
->getCapability(Pots
)+firmware
->getCapability(Sliders
); i
++) {
719 QCheckBox
* cb
= new QCheckBox(this);
720 cb
->setProperty("index", i
);
721 cb
->setText(firmware
->getAnalogInputName(i
+4));
722 ui
->potWarningLayout
->addWidget(cb
, 0, i
+1);
723 connect(cb
, SIGNAL(toggled(bool)), this, SLOT(potWarningToggled(bool)));
724 potWarningCheckboxes
<< cb
;
725 if (RawSource(SOURCE_TYPE_STICK
, CPN_MAX_STICKS
+i
).isPot()) {
726 if (!generalSettings
.isPotAvailable(i
)) {
731 if (!generalSettings
.isSliderAvailable(i
-firmware
->getCapability(Pots
))) {
735 QWidget::setTabOrder(prevFocus
, cb
);
740 ui
->label_potWarning
->hide();
741 ui
->potWarningMode
->hide();
745 ui
->trimsDisplay
->setField(model
.trimsDisplay
, this);
748 ui
->labelTrimsDisplay
->hide();
749 ui
->trimsDisplay
->hide();
752 for (int i
=0; i
<firmware
->getCapability(NumModules
); i
++) {
753 modules
[i
] = new ModulePanel(this, model
, model
.moduleData
[i
], generalSettings
, firmware
, i
);
754 ui
->modulesLayout
->addWidget(modules
[i
]);
755 connect(modules
[i
], SIGNAL(modified()), this, SLOT(onChildModified()));
758 if (firmware
->getCapability(ModelTrainerEnable
)) {
759 modules
[CPN_MAX_MODULES
] = new ModulePanel(this, model
, model
.moduleData
[CPN_MAX_MODULES
], generalSettings
, firmware
, -1);
760 ui
->modulesLayout
->addWidget(modules
[CPN_MAX_MODULES
]);
761 connect(modules
[CPN_MAX_MODULES
], SIGNAL(modified()), this, SLOT(onChildModified()));
764 disableMouseScrolling();
769 SetupPanel::~SetupPanel()
774 void SetupPanel::on_extendedLimits_toggled(bool checked
)
776 model
->extendedLimits
= checked
;
777 emit
extendedLimitsToggled();
781 void SetupPanel::on_throttleWarning_toggled(bool checked
)
783 model
->disableThrottleWarning
= !checked
;
787 void SetupPanel::on_throttleReverse_toggled(bool checked
)
789 model
->throttleReversed
= checked
;
793 void SetupPanel::on_extendedTrims_toggled(bool checked
)
795 model
->extendedTrims
= checked
;
799 void SetupPanel::on_trimIncrement_currentIndexChanged(int index
)
801 model
->trimInc
= index
-2;
805 void SetupPanel::on_throttleSource_currentIndexChanged(int index
)
808 model
->thrTraceSrc
= index
;
813 void SetupPanel::on_name_editingFinished()
815 int length
= ui
->name
->maxLength();
816 strncpy(model
->name
, ui
->name
->text().toLatin1(), length
);
820 void SetupPanel::on_image_currentIndexChanged(int index
)
823 strncpy(model
->bitmap
, ui
->image
->currentText().toLatin1(), 10);
824 QString path
= g
.profile
[g
.id()].sdPath();
825 path
.append("/IMAGES/");
828 QString fileName
=path
;
829 fileName
.append(model
->bitmap
);
830 fileName
.append(".bmp");
831 QImage
image(fileName
);
832 if (image
.isNull()) {
834 fileName
.append(model
->bitmap
);
835 fileName
.append(".BMP");
836 image
.load(fileName
);
838 if (!image
.isNull()) {
839 ui
->imagePreview
->setPixmap(QPixmap::fromImage(image
.scaled(64, 32)));;
842 ui
->imagePreview
->clear();
846 ui
->imagePreview
->clear();
852 void SetupPanel::populateThrottleSourceCB()
855 ui
->throttleSource
->clear();
856 ui
->throttleSource
->addItem(QObject::tr("THR"));
857 for (int i
=0; i
<firmware
->getCapability(Pots
)+firmware
->getCapability(Sliders
); i
++) {
858 ui
->throttleSource
->addItem(firmware
->getAnalogInputName(4+i
), i
);
860 for (int i
=0; i
<firmware
->getCapability(Outputs
); i
++) {
861 ui
->throttleSource
->addItem(ModelPrinter::printChannelName(i
));
863 ui
->throttleSource
->setCurrentIndex(model
->thrTraceSrc
);
867 void SetupPanel::update()
869 ui
->name
->setText(model
->name
);
870 ui
->throttleReverse
->setChecked(model
->throttleReversed
);
871 populateThrottleSourceCB();
872 ui
->throttleWarning
->setChecked(!model
->disableThrottleWarning
);
873 ui
->trimIncrement
->setCurrentIndex(model
->trimInc
+2);
874 ui
->throttleTrim
->setChecked(model
->thrTrim
);
875 ui
->extendedLimits
->setChecked(model
->extendedLimits
);
876 ui
->extendedTrims
->setChecked(model
->extendedTrims
);
877 ui
->displayText
->setChecked(model
->displayChecklist
);
878 ui
->gfEnabled
->setChecked(!model
->noGlobalFunctions
);
881 updateStartupSwitches();
883 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
887 for (int i
=0; i
<firmware
->getCapability(Timers
); i
++) {
891 for (int i
=0; i
<CPN_MAX_MODULES
+1; i
++) {
893 modules
[i
]->update();
898 void SetupPanel::updateBeepCenter()
900 for (int i
=0; i
<centerBeepCheckboxes
.size(); i
++) {
901 centerBeepCheckboxes
[i
]->setChecked(model
->beepANACenter
& (0x01 << i
));
905 void SetupPanel::updateStartupSwitches()
909 uint64_t switchStates
= model
->switchWarningStates
;
912 for (int i
=0; i
<startupSwitchesSliders
.size(); i
++) {
913 QSlider
* slider
= startupSwitchesSliders
[i
];
914 QCheckBox
* cb
= startupSwitchesCheckboxes
[i
];
915 int index
= slider
->property("index").toInt();
916 bool enabled
= !(model
->switchWarningEnable
& (1 << index
));
917 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
918 value
= (switchStates
>> 2*index
) & 0x03;
919 if (generalSettings
.switchConfig
[index
] != GeneralSettings::SWITCH_3POS
&& value
== 2) {
924 value
= (i
==0 ? switchStates
& 0x3 : switchStates
& 0x1);
925 switchStates
>>= (i
==0 ? 2 : 1);
927 slider
->setValue(value
);
928 slider
->setEnabled(enabled
);
929 cb
->setChecked(enabled
);
935 void SetupPanel::startupSwitchEdited(int value
)
940 int index
= sender()->property("index").toInt();
942 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
944 mask
= 0x03ul
<< shift
;
952 mask
= 0x01ull
<< shift
;
956 model
->switchWarningStates
&= ~mask
;
958 if (IS_HORUS_OR_TARANIS(firmware
->getBoard()) && generalSettings
.switchConfig
[index
] != GeneralSettings::SWITCH_3POS
) {
965 model
->switchWarningStates
|= ((uint64_t)value
<< shift
);
968 updateStartupSwitches();
973 void SetupPanel::startupSwitchToggled(bool checked
)
976 int index
= sender()->property("index").toInt();
979 model
->switchWarningEnable
&= ~(1 << index
);
981 model
->switchWarningEnable
|= (1 << index
);
983 updateStartupSwitches();
988 void SetupPanel::updatePotWarnings()
991 ui
->potWarningMode
->setCurrentIndex(model
->potsWarningMode
);
992 for (int i
=0; i
<potWarningCheckboxes
.size(); i
++) {
993 QCheckBox
*checkbox
= potWarningCheckboxes
[i
];
994 int index
= checkbox
->property("index").toInt();
995 checkbox
->setChecked(!model
->potsWarningEnabled
[index
]);
996 checkbox
->setDisabled(model
->potsWarningMode
== 0);
1001 void SetupPanel::potWarningToggled(bool checked
)
1004 int index
= sender()->property("index").toInt();
1005 model
->potsWarningEnabled
[index
] = !checked
;
1006 updatePotWarnings();
1011 void SetupPanel::on_potWarningMode_currentIndexChanged(int index
)
1014 model
->potsWarningMode
= index
;
1015 updatePotWarnings();
1020 void SetupPanel::on_displayText_toggled(bool checked
)
1022 model
->displayChecklist
= checked
;
1026 void SetupPanel::on_gfEnabled_toggled(bool checked
)
1028 model
->noGlobalFunctions
= !checked
;
1032 void SetupPanel::on_throttleTrim_toggled(bool checked
)
1034 model
->thrTrim
= checked
;
1038 void SetupPanel::onBeepCenterToggled(bool checked
)
1041 int index
= sender()->property("index").toInt();
1042 unsigned int mask
= (0x01 << index
);
1044 model
->beepANACenter
|= mask
;
1046 model
->beepANACenter
&= ~mask
;
1051 void SetupPanel::onChildModified()