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 "customfunctions.h"
22 #include "switchitemmodel.h"
28 RepeatComboBox::RepeatComboBox(QWidget
*parent
, int & repeatParam
):
30 repeatParam(repeatParam
)
32 unsigned int step
= IS_ARM(getCurrentBoard()) ? 1 : 10;
33 int value
= repeatParam
/step
;
35 setSizePolicy(QSizePolicy::Maximum
, QSizePolicy::Fixed
);
38 addItem(tr("Played once, not during startup"), -1);
42 addItem(tr("No repeat"), 0);
44 for (unsigned int i
=step
; i
<=60; i
+=step
) {
45 addItem(tr("%1s").arg(i
), i
);
48 setCurrentIndex(value
);
50 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onIndexChanged(int)));
53 void RepeatComboBox::onIndexChanged(int index
)
55 repeatParam
= itemData(index
).toInt();
59 void RepeatComboBox::update()
61 unsigned int step
= IS_ARM(getCurrentBoard()) ? 1 : 10;
62 int value
= repeatParam
/step
;
66 setCurrentIndex(value
);
69 CustomFunctionsPanel::CustomFunctionsPanel(QWidget
* parent
, ModelData
* model
, GeneralSettings
& generalSettings
, Firmware
* firmware
):
70 GenericPanel(parent
, model
, generalSettings
, firmware
),
71 functions(model
? model
->customFn
: generalSettings
.customFn
),
72 rawSwitchItemModel(NULL
),
73 rawSrcInputsItemModel(NULL
),
74 rawSrcAllItemModel(NULL
),
75 mediaPlayerCurrent(-1),
78 Stopwatch
s1("CustomFunctionsPanel - populate");
80 int num_fsw
= model
? firmware
->getCapability(CustomFunctions
) : firmware
->getCapability(GlobalFunctions
);
84 if (!firmware
->getCapability(VoicesAsNumbers
)) {
85 tracksSet
= getFilesSet(getSoundsPath(generalSettings
), QStringList() << "*.wav" << "*.WAV", firmware
->getCapability(VoicesMaxLength
));
86 for (int i
=0; i
<num_fsw
; i
++) {
87 if (functions
[i
].func
==FuncPlayPrompt
|| functions
[i
].func
==FuncBackgroundMusic
) {
88 QString temp
= functions
[i
].paramarm
;
89 if (!temp
.isEmpty()) {
90 tracksSet
.insert(temp
);
96 s1
.report("get tracks");
98 if (IS_STM32(firmware
->getBoard())) {
99 scriptsSet
= getFilesSet(g
.profile
[g
.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware
->getCapability(VoicesMaxLength
));
100 for (int i
=0; i
<num_fsw
; i
++) {
101 if (functions
[i
].func
==FuncPlayScript
) {
102 QString temp
= functions
[i
].paramarm
;
103 if (!temp
.isEmpty()) {
104 scriptsSet
.insert(temp
);
109 s1
.report("get scripts");
111 CompanionIcon
playIcon("play.png");
113 QStringList headerLabels
;
114 headerLabels
<< "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Enable");
115 TableLayout
* tableLayout
= new TableLayout(this, num_fsw
, headerLabels
);
117 for (int i
=0; i
<num_fsw
; i
++) {
119 QLabel
* label
= new QLabel(this);
120 label
->setContextMenuPolicy(Qt::CustomContextMenu
);
121 label
->setMouseTracking(true);
122 label
->setProperty("index", i
);
124 label
->setText(tr("SF%1").arg(i
+1));
126 label
->setText(tr("GF%1").arg(i
+1));
127 label
->setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Minimum
);
128 connect(label
, SIGNAL(customContextMenuRequested(QPoint
)), this, SLOT(fsw_customContextMenuRequested(QPoint
)));
129 tableLayout
->addWidget(i
, 0, label
);
130 // s1.report("label");
133 fswtchSwtch
[i
] = new QComboBox(this);
134 fswtchSwtch
[i
]->setModel(rawSwitchItemModel
);
135 fswtchSwtch
[i
]->setCurrentIndex(fswtchSwtch
[i
]->findData(functions
[i
].swtch
.toValue()));
136 fswtchSwtch
[i
]->setProperty("index", i
);
137 fswtchSwtch
[i
]->setSizePolicy(QSizePolicy::Maximum
, QSizePolicy::Minimum
);
138 fswtchSwtch
[i
]->setMaxVisibleItems(10);
139 connect(fswtchSwtch
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
140 tableLayout
->addWidget(i
, 1, fswtchSwtch
[i
]);
141 // s1.report("switch");
144 fswtchFunc
[i
] = new QComboBox(this);
146 populateFuncCB(fswtchFunc
[i
], functions
[i
].func
);
149 fswtchFunc
[i
]->setModel(fswtchFunc
[0]->model());
150 fswtchFunc
[i
]->setCurrentIndex(fswtchFunc
[i
]->findData(functions
[i
].func
));
152 fswtchFunc
[i
]->setProperty("index", i
);
153 connect(fswtchFunc
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(functionEdited()));
154 tableLayout
->addWidget(i
, 2, fswtchFunc
[i
]);
155 // s1.report("func");
158 QHBoxLayout
* paramLayout
= new QHBoxLayout();
159 tableLayout
->addLayout(i
, 3, paramLayout
);
161 fswtchGVmode
[i
] = new QComboBox(this);
162 fswtchGVmode
[i
]->setProperty("index", i
);
163 populateGVmodeCB(fswtchGVmode
[i
], functions
[i
].adjustMode
);
164 fswtchGVmode
[i
]->setSizeAdjustPolicy(QComboBox::AdjustToContents
);
165 connect(fswtchGVmode
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
166 paramLayout
->addWidget(fswtchGVmode
[i
]);
168 fswtchParamGV
[i
] = new QCheckBox(this);
169 fswtchParamGV
[i
]->setProperty("index", i
);
170 fswtchParamGV
[i
]->setText("GV");
171 fswtchParamGV
[i
]->setSizePolicy(QSizePolicy::Minimum
,QSizePolicy::Minimum
);
172 connect(fswtchParamGV
[i
], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
173 paramLayout
->addWidget(fswtchParamGV
[i
]);
175 fswtchParam
[i
] = new QDoubleSpinBox(this);
176 fswtchParam
[i
]->setProperty("index", i
);
177 fswtchParam
[i
]->setAccelerated(true);
178 fswtchParam
[i
]->setDecimals(0);
179 connect(fswtchParam
[i
], SIGNAL(editingFinished()), this, SLOT(customFunctionEdited()));
180 paramLayout
->addWidget(fswtchParam
[i
]);
182 fswtchParamTime
[i
] = new TimerEdit(this);
183 fswtchParamTime
[i
]->setProperty("index", i
);
184 connect(fswtchParamTime
[i
], SIGNAL(editingFinished()), this, SLOT(customFunctionEdited()));
185 paramLayout
->addWidget(fswtchParamTime
[i
]);
187 fswtchParamT
[i
] = new QComboBox(this);
188 fswtchParamT
[i
]->setProperty("index", i
);
189 populateFuncParamCB(fswtchParamT
[i
], functions
[i
].func
, functions
[i
].param
, functions
[i
].adjustMode
);
190 paramLayout
->addWidget(fswtchParamT
[i
]);
191 fswtchParamT
[i
]->setSizeAdjustPolicy(QComboBox::AdjustToContents
);
192 connect(fswtchParamT
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
194 fswtchParamArmT
[i
] = new QComboBox(this);
195 fswtchParamArmT
[i
]->setProperty("index", i
);
196 fswtchParamArmT
[i
]->setEditable(true);
197 fswtchParamArmT
[i
]->setSizeAdjustPolicy(QComboBox::AdjustToContents
);
198 paramLayout
->addWidget(fswtchParamArmT
[i
]);
200 connect(fswtchParamArmT
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
201 connect(fswtchParamArmT
[i
], SIGNAL(editTextChanged ( const QString
)), this, SLOT(customFunctionEdited()));
203 fswtchBLcolor
[i
] = new QSlider(this);
204 fswtchBLcolor
[i
]->setProperty("index", i
);
205 fswtchBLcolor
[i
]->setMinimum(0);
206 fswtchBLcolor
[i
]->setMaximum(100);
207 fswtchBLcolor
[i
]->setSingleStep(1);
208 fswtchBLcolor
[i
]->setOrientation(Qt::Horizontal
);
209 paramLayout
->addWidget(fswtchBLcolor
[i
]);
210 connect(fswtchBLcolor
[i
], SIGNAL(sliderReleased()), this, SLOT(customFunctionEdited()));
212 playBT
[i
] = new QPushButton(this);
213 playBT
[i
]->setSizePolicy(QSizePolicy::Minimum
, QSizePolicy::Fixed
);
214 playBT
[i
]->setProperty("index", i
);
215 playBT
[i
]->setIcon(playIcon
);
216 paramLayout
->addWidget(playBT
[i
]);
217 connect(playBT
[i
], SIGNAL(pressed()), this, SLOT(playMusic()));
219 QHBoxLayout
* repeatLayout
= new QHBoxLayout();
220 tableLayout
->addLayout(i
, 4, repeatLayout
);
221 fswtchRepeat
[i
] = new RepeatComboBox(this, functions
[i
].repeatParam
);
222 repeatLayout
->addWidget(fswtchRepeat
[i
], i
+1);
223 connect(fswtchRepeat
[i
], SIGNAL(modified()), this, SLOT(onChildModified()));
225 fswtchEnable
[i
] = new QCheckBox(this);
226 fswtchEnable
[i
]->setProperty("index", i
);
227 fswtchEnable
[i
]->setText(tr("ON"));
228 fswtchEnable
[i
]->setFixedWidth(200);
229 repeatLayout
->addWidget(fswtchEnable
[i
], i
+1);
230 connect(fswtchEnable
[i
], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
233 s1
.report("add items");
235 disableMouseScrolling();
236 s1
.report("disableMouseScrolling");
242 tableLayout
->resizeColumnsToContents();
243 s1
.report("resizeColumnsToContents");
244 tableLayout
->setColumnWidth(3, 300);
245 tableLayout
->pushRowsUp(num_fsw
+1);
249 CustomFunctionsPanel::~CustomFunctionsPanel()
253 void CustomFunctionsPanel::setDataModels()
255 if (rawSwitchItemModel
)
256 rawSwitchItemModel
->update();
258 rawSwitchItemModel
= new RawSwitchFilterItemModel(&generalSettings
, model
, model
? SpecialFunctionsContext
: GlobalFunctionsContext
);
260 // The RawSource item models have to be reloaded on every update(). TODO: convert to filtered model like for RawSwitches
262 if (rawSrcInputsItemModel
)
263 rawSrcInputsItemModel
->deleteLater();
264 if (rawSrcAllItemModel
)
265 rawSrcAllItemModel
->deleteLater();
267 rawSrcInputsItemModel
= Helpers::getRawSourceItemModel(&generalSettings
, model
, POPULATE_NONE
|POPULATE_SOURCES
|POPULATE_VIRTUAL_INPUTS
|POPULATE_TRIMS
|POPULATE_SWITCHES
);
268 rawSrcInputsItemModel
->setParent(this);
269 rawSrcAllItemModel
= Helpers::getRawSourceItemModel(&generalSettings
, model
, POPULATE_NONE
|POPULATE_SOURCES
|POPULATE_VIRTUAL_INPUTS
|POPULATE_SWITCHES
|POPULATE_GVARS
|POPULATE_TRIMS
|POPULATE_TELEMETRY
|POPULATE_TELEMETRYEXT
|POPULATE_SCRIPT_OUTPUTS
);
270 rawSrcAllItemModel
->setParent(this);
273 void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state
)
277 if (state
==QMediaPlayer::StoppedState
|| state
==QMediaPlayer::PausedState
) {
279 if (mediaPlayerCurrent
>= 0) {
280 playBT
[mediaPlayerCurrent
]->setIcon(CompanionIcon("play.png"));
281 mediaPlayerCurrent
= -1;
288 void CustomFunctionsPanel::onMediaPlayerError(QMediaPlayer::Error error
)
292 if (mediaPlayerCurrent
>= 0) {
293 playBT
[mediaPlayerCurrent
]->setIcon(CompanionIcon("play.png"));
294 mediaPlayerCurrent
= -1;
300 void CustomFunctionsPanel::playMusic()
303 mediaPlayer
= new QMediaPlayer(this);
304 connect(mediaPlayer
, SIGNAL(stateChanged(QMediaPlayer::State
)), this, SLOT(onMediaPlayerStateChanged(QMediaPlayer::State
)));
305 connect(mediaPlayer
, SIGNAL(error(QMediaPlayer::Error
)), this, SLOT(onMediaPlayerError(QMediaPlayer::Error
)));
308 int index
= sender()->property("index").toInt();
309 QString path
= g
.profile
[g
.id()].sdPath();
313 if (firmware
->getCapability(VoicesAsNumbers
)) {
314 track
= path
+ QString("/%1.wav").arg(int(fswtchParam
[index
]->value()), 4, 10, (const QChar
)'0');
317 path
.append("/SOUNDS/");
318 QString lang
= generalSettings
.ttsLanguage
;
322 if (fswtchParamArmT
[index
]->currentText() != "----") {
323 track
= path
+ "/" + fswtchParamArmT
[index
]->currentText() + ".wav";
327 if (!file
.exists()) {
328 QMessageBox::critical(this, CPN_STR_TTL_ERROR
, tr("Unable to find sound file %1!").arg(track
));
332 if (mediaPlayerCurrent
== index
) {
334 playBT
[index
]->setIcon(CompanionIcon("play.png"));
335 mediaPlayerCurrent
= -1;
338 if (mediaPlayerCurrent
>= 0) {
339 playBT
[mediaPlayerCurrent
]->setIcon(CompanionIcon("play.png"));
341 mediaPlayerCurrent
= index
;
342 mediaPlayer
->setMedia(QUrl::fromLocalFile(track
));
344 playBT
[index
]->setIcon(CompanionIcon("stop.png"));
349 #define CUSTOM_FUNCTION_NUMERIC_PARAM (1<<0)
350 #define CUSTOM_FUNCTION_SOURCE_PARAM (1<<1)
351 #define CUSTOM_FUNCTION_FILE_PARAM (1<<2)
352 #define CUSTOM_FUNCTION_TIME_PARAM (1<<3)
353 #define CUSTOM_FUNCTION_GV_MODE (1<<4)
354 #define CUSTOM_FUNCTION_GV_TOOGLE (1<<5)
355 #define CUSTOM_FUNCTION_ENABLE (1<<6)
356 #define CUSTOM_FUNCTION_REPEAT (1<<7)
357 #define CUSTOM_FUNCTION_PLAY (1<<8)
358 #define CUSTOM_FUNCTION_BL_COLOR (1<<9)
359 #define CUSTOM_FUNCTION_SHOW_FUNC (1<<10)
361 void CustomFunctionsPanel::customFunctionEdited()
365 int index
= sender()->property("index").toInt();
366 refreshCustomFunction(index
, true);
372 void CustomFunctionsPanel::functionEdited()
376 int index
= sender()->property("index").toInt();
377 RawSwitch swtch
= functions
[index
].swtch
;
378 functions
[index
].clear();
379 functions
[index
].swtch
= swtch
;
380 functions
[index
].func
= (AssignFunc
)fswtchFunc
[index
]->currentData().toInt();
381 refreshCustomFunction(index
);
387 void CustomFunctionsPanel::onChildModified()
392 void CustomFunctionsPanel::refreshCustomFunction(int i
, bool modified
)
394 CustomFunctionData
& cfn
= functions
[i
];
395 AssignFunc func
= (AssignFunc
)fswtchFunc
[i
]->currentData().toInt();
397 unsigned int widgetsMask
= 0;
399 cfn
.swtch
= RawSwitch(fswtchSwtch
[i
]->currentData().toInt());
401 cfn
.enabled
= fswtchEnable
[i
]->isChecked();
402 cfn
.adjustMode
= (AssignFunc
)fswtchGVmode
[i
]->currentIndex();
405 if (!cfn
.isEmpty()) {
406 widgetsMask
|= CUSTOM_FUNCTION_SHOW_FUNC
;
408 if (func
>=FuncOverrideCH1
&& func
<=FuncOverrideCH32
) {
410 int channelsMax
= model
->getChannelsMax(true);
411 fswtchParam
[i
]->setDecimals(0);
412 fswtchParam
[i
]->setSingleStep(1);
413 fswtchParam
[i
]->setMinimum(-channelsMax
);
414 fswtchParam
[i
]->setMaximum(channelsMax
);
416 cfn
.param
= fswtchParam
[i
]->value();
418 fswtchParam
[i
]->setValue(cfn
.param
);
419 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
| CUSTOM_FUNCTION_ENABLE
;
422 else if (func
==FuncLogs
) {
423 fswtchParam
[i
]->setDecimals(1);
424 fswtchParam
[i
]->setMinimum(0);
425 fswtchParam
[i
]->setMaximum(25.5);
426 fswtchParam
[i
]->setSingleStep(0.1);
428 cfn
.param
= fswtchParam
[i
]->value()*10.0;
429 fswtchParam
[i
]->setValue(cfn
.param
/10.0);
430 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
;
432 else if (func
>=FuncAdjustGV1
&& func
<=FuncAdjustGVLast
) {
433 int gvidx
= func
- FuncAdjustGV1
;
435 cfn
.adjustMode
= fswtchGVmode
[i
]->currentIndex();
436 widgetsMask
|= CUSTOM_FUNCTION_GV_MODE
| CUSTOM_FUNCTION_ENABLE
;
437 if (cfn
.adjustMode
==FUNC_ADJUST_GVAR_CONSTANT
|| cfn
.adjustMode
==FUNC_ADJUST_GVAR_INCDEC
) {
439 cfn
.param
= fswtchParam
[i
]->value() * model
->gvarData
[gvidx
].multiplierSet();
440 if (IS_ARM(getCurrentBoard())) {
441 fswtchParam
[i
]->setDecimals(model
->gvarData
[gvidx
].prec
);
442 fswtchParam
[i
]->setSingleStep(model
->gvarData
[gvidx
].multiplierGet());
443 fswtchParam
[i
]->setSuffix(model
->gvarData
[gvidx
].unitToString());
444 fswtchParam
[i
]->setMinimum(model
->gvarData
[gvidx
].getMinPrec());
445 fswtchParam
[i
]->setMaximum(model
->gvarData
[gvidx
].getMaxPrec());
446 fswtchParam
[i
]->setValue(cfn
.param
* model
->gvarData
[gvidx
].multiplierGet());
449 fswtchParam
[i
]->setDecimals(0);
450 fswtchParam
[i
]->setSingleStep(1);
451 fswtchParam
[i
]->setMinimum(-125);
452 fswtchParam
[i
]->setMaximum(125);
453 fswtchParam
[i
]->setValue(cfn
.param
);
455 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
;
459 cfn
.param
= fswtchParamT
[i
]->currentData().toInt();
460 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
, cfn
.adjustMode
);
461 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
;
464 else if (func
==FuncReset
) {
466 cfn
.param
= fswtchParamT
[i
]->currentData().toInt();
467 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
468 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
| CUSTOM_FUNCTION_ENABLE
;
470 else if (func
>=FuncSetTimer1
&& func
<=FuncSetTimer3
) {
472 cfn
.param
= fswtchParamTime
[i
]->timeInSeconds();
473 RawSourceRange range
= RawSource(SOURCE_TYPE_SPECIAL
, func
- FuncSetTimer1
+ 2).getRange(model
, generalSettings
);
474 fswtchParamTime
[i
]->setTimeRange((int)range
.min
, (int)range
.max
);
475 fswtchParamTime
[i
]->setTime(cfn
.param
);
476 widgetsMask
|= CUSTOM_FUNCTION_TIME_PARAM
| CUSTOM_FUNCTION_ENABLE
;
478 else if (func
>=FuncSetFailsafeInternalModule
&& func
<=FuncBindExternalModule
) {
479 widgetsMask
|= CUSTOM_FUNCTION_ENABLE
;
481 else if (func
==FuncVolume
) {
483 cfn
.param
= fswtchParamT
[i
]->currentData().toInt();
484 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
485 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
| CUSTOM_FUNCTION_ENABLE
;
487 else if (func
==FuncPlaySound
|| func
==FuncPlayHaptic
|| func
==FuncPlayValue
|| func
==FuncPlayPrompt
|| func
==FuncPlayBoth
|| func
==FuncBackgroundMusic
) {
488 if (func
!= FuncBackgroundMusic
) {
489 widgetsMask
|= CUSTOM_FUNCTION_REPEAT
;
490 fswtchRepeat
[i
]->update();
492 if (func
==FuncPlayValue
) {
494 cfn
.param
= fswtchParamT
[i
]->currentData().toInt();
495 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
496 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
| CUSTOM_FUNCTION_REPEAT
;
498 else if (func
==FuncPlayPrompt
|| func
==FuncPlayBoth
) {
499 if (firmware
->getCapability(VoicesAsNumbers
)) {
500 fswtchParam
[i
]->setDecimals(0);
501 fswtchParam
[i
]->setSingleStep(1);
502 fswtchParam
[i
]->setMinimum(0);
503 if (func
==FuncPlayPrompt
) {
504 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
| CUSTOM_FUNCTION_REPEAT
| CUSTOM_FUNCTION_GV_TOOGLE
;
507 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
| CUSTOM_FUNCTION_REPEAT
;
508 fswtchParamGV
[i
]->setChecked(false);
510 fswtchParam
[i
]->setMaximum(func
==FuncPlayBoth
? 254 : 255);
512 if (fswtchParamGV
[i
]->isChecked()) {
513 fswtchParam
[i
]->setMinimum(1);
514 cfn
.param
= std::min(fswtchParam
[i
]->value(),5.0)+(fswtchParamGV
[i
]->isChecked() ? 250 : 0);
517 cfn
.param
= fswtchParam
[i
]->value();
520 if (cfn
.param
>250 && (func
!=FuncPlayBoth
)) {
521 fswtchParamGV
[i
]->setChecked(true);
522 fswtchParam
[i
]->setValue(cfn
.param
-250);
523 fswtchParam
[i
]->setMaximum(5);
526 fswtchParamGV
[i
]->setChecked(false);
527 fswtchParam
[i
]->setValue(cfn
.param
);
530 widgetsMask
|= CUSTOM_FUNCTION_PLAY
;
533 widgetsMask
|= CUSTOM_FUNCTION_FILE_PARAM
;
535 Helpers::getFileComboBoxValue(fswtchParamArmT
[i
], cfn
.paramarm
, firmware
->getCapability(VoicesMaxLength
));
537 Helpers::populateFileComboBox(fswtchParamArmT
[i
], tracksSet
, cfn
.paramarm
);
538 if (fswtchParamArmT
[i
]->currentText() != "----") {
539 widgetsMask
|= CUSTOM_FUNCTION_PLAY
;
543 else if (func
==FuncBackgroundMusic
) {
544 widgetsMask
|= CUSTOM_FUNCTION_FILE_PARAM
;
546 Helpers::getFileComboBoxValue(fswtchParamArmT
[i
], cfn
.paramarm
, firmware
->getCapability(VoicesMaxLength
));
548 Helpers::populateFileComboBox(fswtchParamArmT
[i
], tracksSet
, cfn
.paramarm
);
549 if (fswtchParamArmT
[i
]->currentText() != "----") {
550 widgetsMask
|= CUSTOM_FUNCTION_PLAY
;
553 else if (func
==FuncPlaySound
) {
555 cfn
.param
= (uint8_t)fswtchParamT
[i
]->currentIndex();
556 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
557 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
;
559 else if (func
==FuncPlayHaptic
) {
561 cfn
.param
= (uint8_t)fswtchParamT
[i
]->currentIndex();
562 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
563 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
;
566 else if (func
==FuncPlayScript
) {
567 widgetsMask
|= CUSTOM_FUNCTION_FILE_PARAM
;
569 Helpers::getFileComboBoxValue(fswtchParamArmT
[i
], cfn
.paramarm
, 8);
571 Helpers::populateFileComboBox(fswtchParamArmT
[i
], scriptsSet
, cfn
.paramarm
);
573 else if (func
==FuncBacklight
&& IS_TARANIS_PLUS(getCurrentBoard())) {
575 cfn
.param
= (uint8_t)fswtchBLcolor
[i
]->value();
576 fswtchBLcolor
[i
]->setValue(cfn
.param
);
577 widgetsMask
|= CUSTOM_FUNCTION_BL_COLOR
;
581 cfn
.param
= fswtchParam
[i
]->value();
582 fswtchParam
[i
]->setDecimals(0);
583 fswtchParam
[i
]->setSingleStep(1);
584 fswtchParam
[i
]->setValue(cfn
.param
);
585 if (func
<= FuncInstantTrim
) {
586 widgetsMask
|= CUSTOM_FUNCTION_ENABLE
;
592 fswtchFunc
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_SHOW_FUNC
);
593 fswtchParam
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_NUMERIC_PARAM
);
594 fswtchParamTime
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_TIME_PARAM
);
595 fswtchParamGV
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_GV_TOOGLE
);
596 fswtchParamT
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_SOURCE_PARAM
);
597 fswtchParamArmT
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_FILE_PARAM
);
598 fswtchEnable
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_ENABLE
);
599 if (widgetsMask
& CUSTOM_FUNCTION_ENABLE
)
600 fswtchEnable
[i
]->setChecked(cfn
.enabled
);
602 fswtchEnable
[i
]->setChecked(false);
603 fswtchRepeat
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_REPEAT
);
604 fswtchGVmode
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_GV_MODE
);
605 fswtchBLcolor
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_BL_COLOR
);
606 playBT
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_PLAY
);
609 void CustomFunctionsPanel::update()
614 int num_fsw
= model
? firmware
->getCapability(CustomFunctions
) : firmware
->getCapability(GlobalFunctions
);
615 for (int i
=0; i
<num_fsw
; i
++) {
616 refreshCustomFunction(i
);
621 void CustomFunctionsPanel::fswPaste()
623 const QClipboard
*clipboard
= QApplication::clipboard();
624 const QMimeData
*mimeData
= clipboard
->mimeData();
625 if (mimeData
->hasFormat("application/x-companion-fsw")) {
626 QByteArray fswData
= mimeData
->data("application/x-companion-fsw");
627 CustomFunctionData
*fsw
= &functions
[selectedFunction
];
628 memcpy(fsw
, fswData
.constData(), sizeof(CustomFunctionData
));
630 fswtchSwtch
[selectedFunction
]->setCurrentIndex(fswtchSwtch
[selectedFunction
]->findData(functions
[selectedFunction
].swtch
.toValue()));
631 fswtchFunc
[selectedFunction
]->setCurrentIndex(fswtchFunc
[selectedFunction
]->findData(functions
[selectedFunction
].func
));
632 populateGVmodeCB(fswtchGVmode
[selectedFunction
], functions
[selectedFunction
].adjustMode
);
633 populateFuncParamCB(fswtchParamT
[selectedFunction
], functions
[selectedFunction
].func
, functions
[selectedFunction
].param
, functions
[selectedFunction
].adjustMode
);
634 refreshCustomFunction(selectedFunction
);
640 void CustomFunctionsPanel::fswDelete()
642 functions
[selectedFunction
].clear();
643 // TODO update switch and func
645 fswtchSwtch
[selectedFunction
]->setCurrentIndex(fswtchSwtch
[selectedFunction
]->findData(functions
[selectedFunction
].swtch
.toValue()));
646 fswtchFunc
[selectedFunction
]->setCurrentIndex(fswtchFunc
[selectedFunction
]->findData(functions
[selectedFunction
].func
));
647 refreshCustomFunction(selectedFunction
);
652 void CustomFunctionsPanel::fswCopy()
655 fswData
.append((char*)&functions
[selectedFunction
], sizeof(CustomFunctionData
));
656 QMimeData
*mimeData
= new QMimeData
;
657 mimeData
->setData("application/x-companion-fsw", fswData
);
658 QApplication::clipboard()->setMimeData(mimeData
, QClipboard::Clipboard
);
661 void CustomFunctionsPanel::fswCut()
667 void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos
)
669 QLabel
*label
= (QLabel
*)sender();
670 selectedFunction
= label
->property("index").toInt();
672 QPoint globalPos
= label
->mapToGlobal(pos
);
674 const QClipboard
*clipboard
= QApplication::clipboard();
675 const QMimeData
*mimeData
= clipboard
->mimeData();
676 bool hasData
= mimeData
->hasFormat("application/x-companion-fsw");
679 contextMenu
.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(fswCopy()));
680 contextMenu
.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(fswCut()));
681 contextMenu
.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(fswPaste()))->setEnabled(hasData
);
682 contextMenu
.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(fswDelete()));
684 contextMenu
.exec(globalPos
);
687 void CustomFunctionsPanel::populateFuncCB(QComboBox
*b
, unsigned int value
)
690 for (unsigned int i
=0; i
<FuncCount
; i
++) {
691 if (((i
>=FuncOverrideCH1
&& i
<=FuncOverrideCH32
) && (!model
|| !firmware
->getCapability(SafetyChannelCustomFunction
))) ||
692 ((i
==FuncVolume
|| i
==FuncBackgroundMusic
|| i
==FuncBackgroundMusicPause
) && !firmware
->getCapability(HasVolume
)) ||
693 ((i
==FuncPlayScript
&& !IS_HORUS_OR_TARANIS(firmware
->getBoard()))) ||
694 ((i
==FuncPlayHaptic
) && !firmware
->getCapability(Haptic
)) ||
695 ((i
==FuncPlayBoth
) && !firmware
->getCapability(HasBeeper
)) ||
696 ((i
==FuncLogs
) && !firmware
->getCapability(HasSDLogs
)) ||
697 ((i
==FuncSetTimer1
|| i
==FuncSetTimer2
) && !IS_ARM(firmware
->getBoard())) ||
698 ((i
==FuncSetTimer3
) && firmware
->getCapability(Timers
) < 3) ||
699 ((i
==FuncScreenshot
) && !IS_TARANIS(firmware
->getBoard())) ||
700 ((i
>=FuncRangeCheckInternalModule
&& i
<=FuncBindExternalModule
) && (!model
|| !firmware
->getCapability(DangerousFunctions
))) ||
701 ((i
>=FuncAdjustGV1
&& i
<=FuncAdjustGVLast
) && (!model
|| !firmware
->getCapability(Gvars
)))
707 b
->addItem(CustomFunctionData(AssignFunc(i
)).funcToString(model
), i
);
709 b
->setCurrentIndex(b
->count()-1);
715 void CustomFunctionsPanel::populateGVmodeCB(QComboBox
*b
, unsigned int value
)
718 b
->addItem(tr("Value"));
719 b
->addItem(tr("Source"));
720 b
->addItem(tr("GVAR"));
721 b
->addItem(tr("Increment"));
722 b
->setCurrentIndex(value
);
725 void CustomFunctionsPanel::populateFuncParamCB(QComboBox
*b
, uint function
, unsigned int value
, unsigned int adjustmode
)
728 b
->setModel(new QStandardItemModel(b
)); // clear combo box but not any shared item model
729 if (function
==FuncPlaySound
) {
730 CustomFunctionData::populatePlaySoundParams(qs
);
732 b
->setCurrentIndex(value
);
734 else if (function
==FuncPlayHaptic
) {
735 CustomFunctionData::populateHapticParams(qs
);
737 b
->setCurrentIndex(value
);
739 else if (function
==FuncReset
) {
740 CustomFunctionData::populateResetParams(model
, b
, value
);
742 else if (function
==FuncVolume
) {
743 b
->setModel(rawSrcInputsItemModel
);
744 b
->setCurrentIndex(b
->findData(value
));
746 else if (function
==FuncPlayValue
) {
747 b
->setModel(rawSrcAllItemModel
);
748 b
->setCurrentIndex(b
->findData(value
));
750 else if (function
>=FuncAdjustGV1
&& function
<=FuncAdjustGVLast
) {
751 switch (adjustmode
) {
753 b
->setModel(rawSrcInputsItemModel
);
754 b
->setCurrentIndex(b
->findData(value
));
757 b
->setModel(Helpers::getRawSourceItemModel(&generalSettings
, model
, POPULATE_GVARS
));
758 b
->setCurrentIndex(b
->findData(value
));