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"
25 RepeatComboBox::RepeatComboBox(QWidget
*parent
, int & repeatParam
):
27 repeatParam(repeatParam
)
29 unsigned int step
= IS_ARM(getCurrentBoard()) ? 1 : 10;
30 int value
= repeatParam
/step
;
33 addItem(QObject::tr("Played once, not during startup"), -1);
37 addItem(QObject::tr("No repeat"), 0);
39 for (unsigned int i
=step
; i
<=60; i
+=step
) {
40 addItem(QObject::tr("%1s").arg(i
), i
);
43 setCurrentIndex(value
);
45 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onIndexChanged(int)));
48 void RepeatComboBox::onIndexChanged(int index
)
50 repeatParam
= itemData(index
).toInt();
54 void RepeatComboBox::update()
56 unsigned int step
= IS_ARM(getCurrentBoard()) ? 1 : 10;
57 int value
= repeatParam
/step
;
61 setCurrentIndex(value
);
64 CustomFunctionsPanel::CustomFunctionsPanel(QWidget
* parent
, ModelData
* model
, GeneralSettings
& generalSettings
, Firmware
* firmware
):
65 GenericPanel(parent
, model
, generalSettings
, firmware
),
66 functions(model
? model
->customFn
: generalSettings
.customFn
),
67 mediaPlayerCurrent(-1),
70 Stopwatch
s1("CustomFunctionsPanel - populate");
72 int num_fsw
= model
? firmware
->getCapability(CustomFunctions
) : firmware
->getCapability(GlobalFunctions
);
74 if (!firmware
->getCapability(VoicesAsNumbers
)) {
75 tracksSet
= getFilesSet(getSoundsPath(generalSettings
), QStringList() << "*.wav" << "*.WAV", firmware
->getCapability(VoicesMaxLength
));
76 for (int i
=0; i
<num_fsw
; i
++) {
77 if (functions
[i
].func
==FuncPlayPrompt
|| functions
[i
].func
==FuncBackgroundMusic
) {
78 QString temp
= functions
[i
].paramarm
;
79 if (!temp
.isEmpty()) {
80 tracksSet
.insert(temp
);
86 s1
.report("get tracks");
88 if (IS_STM32(firmware
->getBoard())) {
89 scriptsSet
= getFilesSet(g
.profile
[g
.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware
->getCapability(VoicesMaxLength
));
90 for (int i
=0; i
<num_fsw
; i
++) {
91 if (functions
[i
].func
==FuncPlayScript
) {
92 QString temp
= functions
[i
].paramarm
;
93 if (!temp
.isEmpty()) {
94 scriptsSet
.insert(temp
);
99 s1
.report("get scripts");
101 CompanionIcon
playIcon("play.png");
103 QStringList headerLabels
;
104 headerLabels
<< "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Enable");
105 TableLayout
* tableLayout
= new TableLayout(this, num_fsw
, headerLabels
);
107 for (int i
=0; i
<num_fsw
; i
++) {
109 QLabel
* label
= new QLabel(this);
110 label
->setContextMenuPolicy(Qt::CustomContextMenu
);
111 label
->setMouseTracking(true);
112 label
->setProperty("index", i
);
114 label
->setText(tr("SF%1").arg(i
+1));
116 label
->setText(tr("GF%1").arg(i
+1));
117 label
->setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Minimum
);
118 connect(label
, SIGNAL(customContextMenuRequested(QPoint
)), this, SLOT(fsw_customContextMenuRequested(QPoint
)));
119 tableLayout
->addWidget(i
, 0, label
);
120 // s1.report("label");
123 fswtchSwtch
[i
] = new QComboBox(this);
124 fswtchSwtch
[i
]->setProperty("index", i
);
125 populateSwitchCB(fswtchSwtch
[i
], functions
[i
].swtch
, generalSettings
, model
? SpecialFunctionsContext
: GlobalFunctionsContext
);
126 fswtchSwtch
[i
]->setSizePolicy(QSizePolicy::Maximum
, QSizePolicy::Minimum
);
127 fswtchSwtch
[i
]->setMaxVisibleItems(10);
128 connect(fswtchSwtch
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
129 tableLayout
->addWidget(i
, 1, fswtchSwtch
[i
]);
130 // s1.report("switch");
133 fswtchFunc
[i
] = new QComboBox(this);
134 fswtchFunc
[i
]->setProperty("index", i
);
135 populateFuncCB(fswtchFunc
[i
], functions
[i
].func
);
136 connect(fswtchFunc
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(functionEdited()));
137 tableLayout
->addWidget(i
, 2, fswtchFunc
[i
]);
138 // s1.report("func");
141 QHBoxLayout
* paramLayout
= new QHBoxLayout();
142 tableLayout
->addLayout(i
, 3, paramLayout
);
144 fswtchGVmode
[i
] = new QComboBox(this);
145 fswtchGVmode
[i
]->setProperty("index", i
);
146 populateGVmodeCB(fswtchGVmode
[i
], functions
[i
].adjustMode
);
147 fswtchGVmode
[i
]->setSizeAdjustPolicy(QComboBox::AdjustToContents
);
148 connect(fswtchGVmode
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
149 paramLayout
->addWidget(fswtchGVmode
[i
]);
151 fswtchParamGV
[i
] = new QCheckBox(this);
152 fswtchParamGV
[i
]->setProperty("index", i
);
153 fswtchParamGV
[i
]->setText("GV");
154 fswtchParamGV
[i
]->setSizePolicy(QSizePolicy::Minimum
,QSizePolicy::Minimum
);
155 connect(fswtchParamGV
[i
], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
156 paramLayout
->addWidget(fswtchParamGV
[i
]);
158 fswtchParam
[i
] = new QDoubleSpinBox(this);
159 fswtchParam
[i
]->setProperty("index", i
);
160 fswtchParam
[i
]->setAccelerated(true);
161 fswtchParam
[i
]->setDecimals(0);
162 connect(fswtchParam
[i
], SIGNAL(editingFinished()), this, SLOT(customFunctionEdited()));
163 paramLayout
->addWidget(fswtchParam
[i
]);
165 fswtchParamTime
[i
] = new QTimeEdit(this);
166 fswtchParamTime
[i
]->setProperty("index", i
);
167 fswtchParamTime
[i
]->setAccelerated(true);
168 fswtchParamTime
[i
]->setDisplayFormat("hh:mm:ss");
169 connect(fswtchParamTime
[i
], SIGNAL(editingFinished()), this, SLOT(customFunctionEdited()));
170 paramLayout
->addWidget(fswtchParamTime
[i
]);
172 fswtchParamT
[i
] = new QComboBox(this);
173 fswtchParamT
[i
]->setProperty("index", i
);
174 populateFuncParamCB(fswtchParamT
[i
], functions
[i
].func
, functions
[i
].param
, functions
[i
].adjustMode
);
175 paramLayout
->addWidget(fswtchParamT
[i
]);
176 fswtchParamT
[i
]->setSizeAdjustPolicy(QComboBox::AdjustToContents
);
177 connect(fswtchParamT
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
179 fswtchParamArmT
[i
] = new QComboBox(this);
180 fswtchParamArmT
[i
]->setProperty("index", i
);
181 fswtchParamArmT
[i
]->setEditable(true);
182 fswtchParamArmT
[i
]->setSizeAdjustPolicy(QComboBox::AdjustToContents
);
183 paramLayout
->addWidget(fswtchParamArmT
[i
]);
185 connect(fswtchParamArmT
[i
], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
186 connect(fswtchParamArmT
[i
], SIGNAL(editTextChanged ( const QString
)), this, SLOT(customFunctionEdited()));
188 fswtchBLcolor
[i
] = new QSlider(this);
189 fswtchBLcolor
[i
]->setProperty("index", i
);
190 fswtchBLcolor
[i
]->setMinimum(0);
191 fswtchBLcolor
[i
]->setMaximum(100);
192 fswtchBLcolor
[i
]->setSingleStep(1);
193 fswtchBLcolor
[i
]->setOrientation(Qt::Horizontal
);
194 paramLayout
->addWidget(fswtchBLcolor
[i
]);
195 connect(fswtchBLcolor
[i
], SIGNAL(sliderReleased()), this, SLOT(customFunctionEdited()));
197 playBT
[i
] = new QPushButton(this);
198 playBT
[i
]->setSizePolicy(QSizePolicy::Minimum
, QSizePolicy::Fixed
);
199 playBT
[i
]->setProperty("index", i
);
200 playBT
[i
]->setIcon(playIcon
);
201 paramLayout
->addWidget(playBT
[i
]);
202 connect(playBT
[i
], SIGNAL(pressed()), this, SLOT(playMusic()));
204 QHBoxLayout
* repeatLayout
= new QHBoxLayout();
205 tableLayout
->addLayout(i
, 4, repeatLayout
);
206 fswtchRepeat
[i
] = new RepeatComboBox(this, functions
[i
].repeatParam
);
207 repeatLayout
->addWidget(fswtchRepeat
[i
], i
+1);
208 connect(fswtchRepeat
[i
], SIGNAL(modified()), this, SLOT(onChildModified()));
210 fswtchEnable
[i
] = new QCheckBox(this);
211 fswtchEnable
[i
]->setProperty("index", i
);
212 fswtchEnable
[i
]->setText(tr("ON"));
213 fswtchEnable
[i
]->setFixedWidth(200);
214 repeatLayout
->addWidget(fswtchEnable
[i
], i
+1);
215 connect(fswtchEnable
[i
], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
217 s1
.report("add items");
219 disableMouseScrolling();
220 s1
.report("disableMouseScrolling");
226 tableLayout
->resizeColumnsToContents();
227 s1
.report("resizeColumnsToContents");
228 tableLayout
->setColumnWidth(3, 300);
229 tableLayout
->pushRowsUp(num_fsw
+1);
233 CustomFunctionsPanel::~CustomFunctionsPanel()
237 void CustomFunctionsPanel::onMediaPlayerStateChanged(QMediaPlayer::State state
)
241 if (state
==QMediaPlayer::StoppedState
|| state
==QMediaPlayer::PausedState
) {
243 if (mediaPlayerCurrent
>= 0) {
244 playBT
[mediaPlayerCurrent
]->setIcon(CompanionIcon("play.png"));
245 mediaPlayerCurrent
= -1;
252 void CustomFunctionsPanel::onMediaPlayerError(QMediaPlayer::Error error
)
256 if (mediaPlayerCurrent
>= 0) {
257 playBT
[mediaPlayerCurrent
]->setIcon(CompanionIcon("play.png"));
258 mediaPlayerCurrent
= -1;
264 void CustomFunctionsPanel::playMusic()
267 mediaPlayer
= new QMediaPlayer(this);
268 connect(mediaPlayer
, SIGNAL(stateChanged(QMediaPlayer::State
)), this, SLOT(onMediaPlayerStateChanged(QMediaPlayer::State
)));
269 connect(mediaPlayer
, SIGNAL(error(QMediaPlayer::Error
)), this, SLOT(onMediaPlayerError(QMediaPlayer::Error
)));
272 int index
= sender()->property("index").toInt();
273 QString path
= g
.profile
[g
.id()].sdPath();
277 if (firmware
->getCapability(VoicesAsNumbers
)) {
278 track
= path
+ QString("/%1.wav").arg(int(fswtchParam
[index
]->value()), 4, 10, (const QChar
)'0');
281 path
.append("/SOUNDS/");
282 QString lang
= generalSettings
.ttsLanguage
;
286 if (fswtchParamArmT
[index
]->currentText() != "----") {
287 track
= path
+ "/" + fswtchParamArmT
[index
]->currentText() + ".wav";
291 if (!file
.exists()) {
292 QMessageBox::critical(this, tr("Error"), tr("Unable to find sound file %1!").arg(track
));
296 if (mediaPlayerCurrent
== index
) {
298 playBT
[index
]->setIcon(CompanionIcon("play.png"));
299 mediaPlayerCurrent
= -1;
302 if (mediaPlayerCurrent
>= 0) {
303 playBT
[mediaPlayerCurrent
]->setIcon(CompanionIcon("play.png"));
305 mediaPlayerCurrent
= index
;
306 mediaPlayer
->setMedia(QUrl::fromLocalFile(track
));
308 playBT
[index
]->setIcon(CompanionIcon("stop.png"));
313 #define CUSTOM_FUNCTION_NUMERIC_PARAM (1<<0)
314 #define CUSTOM_FUNCTION_SOURCE_PARAM (1<<1)
315 #define CUSTOM_FUNCTION_FILE_PARAM (1<<2)
316 #define CUSTOM_FUNCTION_TIME_PARAM (1<<3)
317 #define CUSTOM_FUNCTION_GV_MODE (1<<4)
318 #define CUSTOM_FUNCTION_GV_TOOGLE (1<<5)
319 #define CUSTOM_FUNCTION_ENABLE (1<<6)
320 #define CUSTOM_FUNCTION_REPEAT (1<<7)
321 #define CUSTOM_FUNCTION_PLAY (1<<8)
322 #define CUSTOM_FUNCTION_BL_COLOR (1<<9)
324 void CustomFunctionsPanel::customFunctionEdited()
328 int index
= sender()->property("index").toInt();
329 refreshCustomFunction(index
, true);
335 void CustomFunctionsPanel::functionEdited()
339 int index
= sender()->property("index").toInt();
340 RawSwitch swtch
= functions
[index
].swtch
;
341 functions
[index
].clear();
342 functions
[index
].swtch
= swtch
;
343 functions
[index
].func
= (AssignFunc
)fswtchFunc
[index
]->itemData(fswtchFunc
[index
]->currentIndex()).toInt();
344 refreshCustomFunction(index
);
350 void CustomFunctionsPanel::onChildModified()
355 void CustomFunctionsPanel::refreshCustomFunction(int i
, bool modified
)
357 CustomFunctionData
& cfn
= functions
[i
];
358 AssignFunc func
= (AssignFunc
)fswtchFunc
[i
]->itemData(fswtchFunc
[i
]->currentIndex()).toInt();
360 unsigned int widgetsMask
= 0;
362 cfn
.swtch
= RawSwitch(fswtchSwtch
[i
]->itemData(fswtchSwtch
[i
]->currentIndex()).toInt());
364 cfn
.enabled
= fswtchEnable
[i
]->isChecked();
365 cfn
.adjustMode
= (AssignFunc
)fswtchGVmode
[i
]->currentIndex();
368 if (func
>=FuncOverrideCH1
&& func
<=FuncOverrideCH32
) {
370 int channelsMax
= model
->getChannelsMax(true);
371 fswtchParam
[i
]->setDecimals(0);
372 fswtchParam
[i
]->setSingleStep(1);
373 fswtchParam
[i
]->setMinimum(-channelsMax
);
374 fswtchParam
[i
]->setMaximum(channelsMax
);
376 cfn
.param
= fswtchParam
[i
]->value();
378 fswtchParam
[i
]->setValue(cfn
.param
);
379 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
+ CUSTOM_FUNCTION_ENABLE
;
382 else if (func
==FuncLogs
) {
383 fswtchParam
[i
]->setDecimals(1);
384 fswtchParam
[i
]->setMinimum(0);
385 fswtchParam
[i
]->setMaximum(25.5);
386 fswtchParam
[i
]->setSingleStep(0.1);
387 if (modified
) cfn
.param
= fswtchParam
[i
]->value()*10.0;
388 fswtchParam
[i
]->setValue(cfn
.param
/10.0);
389 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
;
391 else if (func
>=FuncAdjustGV1
&& func
<=FuncAdjustGVLast
) {
392 if (modified
) cfn
.adjustMode
= fswtchGVmode
[i
]->currentIndex();
393 widgetsMask
|= CUSTOM_FUNCTION_GV_MODE
| CUSTOM_FUNCTION_ENABLE
;
394 if (cfn
.adjustMode
==FUNC_ADJUST_GVAR_CONSTANT
|| cfn
.adjustMode
==FUNC_ADJUST_GVAR_INCDEC
) {
395 if (modified
) cfn
.param
= fswtchParam
[i
]->value();
396 fswtchParam
[i
]->setDecimals(0);
397 fswtchParam
[i
]->setSingleStep(1);
398 if (IS_ARM(getCurrentBoard())) {
399 fswtchParam
[i
]->setMinimum(-500);
400 fswtchParam
[i
]->setMaximum(500);
403 fswtchParam
[i
]->setMinimum(-125);
404 fswtchParam
[i
]->setMaximum(125);
406 fswtchParam
[i
]->setValue(cfn
.param
);
407 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
;
410 if (modified
) cfn
.param
= fswtchParamT
[i
]->itemData(fswtchParamT
[i
]->currentIndex()).toInt();
411 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
, cfn
.adjustMode
);
412 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
;
415 else if (func
==FuncReset
) {
416 if (modified
) cfn
.param
= fswtchParamT
[i
]->itemData(fswtchParamT
[i
]->currentIndex()).toInt();
417 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
418 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
| CUSTOM_FUNCTION_ENABLE
;
420 else if (func
>=FuncSetTimer1
&& func
<=FuncSetTimer3
) {
421 if (modified
) cfn
.param
= QTimeS(fswtchParamTime
[i
]->time()).seconds();
422 fswtchParamTime
[i
]->setMinimumTime(QTime(0, 0, 0));
423 fswtchParamTime
[i
]->setMaximumTime(firmware
->getMaxTimerStart());
424 fswtchParamTime
[i
]->setTime(QTimeS(cfn
.param
));
425 widgetsMask
|= CUSTOM_FUNCTION_TIME_PARAM
+ CUSTOM_FUNCTION_ENABLE
;
427 else if (func
>=FuncSetFailsafeInternalModule
&& func
<=FuncBindExternalModule
) {
428 widgetsMask
|= CUSTOM_FUNCTION_ENABLE
;
430 else if (func
==FuncVolume
) {
431 if (modified
) cfn
.param
= fswtchParamT
[i
]->itemData(fswtchParamT
[i
]->currentIndex()).toInt();
432 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
433 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
+ CUSTOM_FUNCTION_ENABLE
;
435 else if (func
==FuncPlaySound
|| func
==FuncPlayHaptic
|| func
==FuncPlayValue
|| func
==FuncPlayPrompt
|| func
==FuncPlayBoth
|| func
==FuncBackgroundMusic
) {
436 if (func
!= FuncBackgroundMusic
) {
437 widgetsMask
|= CUSTOM_FUNCTION_REPEAT
;
438 fswtchRepeat
[i
]->update();
440 if (func
==FuncPlayValue
) {
441 if (modified
) cfn
.param
= fswtchParamT
[i
]->itemData(fswtchParamT
[i
]->currentIndex()).toInt();
442 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
443 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
+ CUSTOM_FUNCTION_REPEAT
;
445 else if (func
==FuncPlayPrompt
|| func
==FuncPlayBoth
) {
446 if (firmware
->getCapability(VoicesAsNumbers
)) {
447 fswtchParam
[i
]->setDecimals(0);
448 fswtchParam
[i
]->setSingleStep(1);
449 fswtchParam
[i
]->setMinimum(0);
450 if (func
==FuncPlayPrompt
) {
451 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
+ CUSTOM_FUNCTION_REPEAT
+ CUSTOM_FUNCTION_GV_TOOGLE
;
454 widgetsMask
|= CUSTOM_FUNCTION_NUMERIC_PARAM
+ CUSTOM_FUNCTION_REPEAT
;
455 fswtchParamGV
[i
]->setChecked(false);
457 fswtchParam
[i
]->setMaximum(func
==FuncPlayBoth
? 254 : 255);
459 if (fswtchParamGV
[i
]->isChecked()) {
460 fswtchParam
[i
]->setMinimum(1);
461 cfn
.param
= std::min(fswtchParam
[i
]->value(),5.0)+(fswtchParamGV
[i
]->isChecked() ? 250 : 0);
464 cfn
.param
= fswtchParam
[i
]->value();
467 if (cfn
.param
>250 && (func
!=FuncPlayBoth
)) {
468 fswtchParamGV
[i
]->setChecked(true);
469 fswtchParam
[i
]->setValue(cfn
.param
-250);
470 fswtchParam
[i
]->setMaximum(5);
473 fswtchParamGV
[i
]->setChecked(false);
474 fswtchParam
[i
]->setValue(cfn
.param
);
477 widgetsMask
|= CUSTOM_FUNCTION_PLAY
;
480 widgetsMask
|= CUSTOM_FUNCTION_FILE_PARAM
;
482 getFileComboBoxValue(fswtchParamArmT
[i
], cfn
.paramarm
, firmware
->getCapability(VoicesMaxLength
));
484 populateFileComboBox(fswtchParamArmT
[i
], tracksSet
, cfn
.paramarm
);
485 if (fswtchParamArmT
[i
]->currentText() != "----") {
486 widgetsMask
|= CUSTOM_FUNCTION_PLAY
;
490 else if (func
==FuncBackgroundMusic
) {
491 widgetsMask
|= CUSTOM_FUNCTION_FILE_PARAM
;
493 getFileComboBoxValue(fswtchParamArmT
[i
], cfn
.paramarm
, firmware
->getCapability(VoicesMaxLength
));
495 populateFileComboBox(fswtchParamArmT
[i
], tracksSet
, cfn
.paramarm
);
496 if (fswtchParamArmT
[i
]->currentText() != "----") {
497 widgetsMask
|= CUSTOM_FUNCTION_PLAY
;
500 else if (func
==FuncPlaySound
) {
501 if (modified
) cfn
.param
= (uint8_t)fswtchParamT
[i
]->currentIndex();
502 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
503 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
;
505 else if (func
==FuncPlayHaptic
) {
506 if (modified
) cfn
.param
= (uint8_t)fswtchParamT
[i
]->currentIndex();
507 populateFuncParamCB(fswtchParamT
[i
], func
, cfn
.param
);
508 widgetsMask
|= CUSTOM_FUNCTION_SOURCE_PARAM
;
511 else if (func
==FuncPlayScript
) {
512 widgetsMask
|= CUSTOM_FUNCTION_FILE_PARAM
;
514 getFileComboBoxValue(fswtchParamArmT
[i
], cfn
.paramarm
, 8);
516 populateFileComboBox(fswtchParamArmT
[i
], scriptsSet
, cfn
.paramarm
);
518 else if (func
==FuncBacklight
&& IS_TARANIS_PLUS(getCurrentBoard())) {
519 if (modified
) cfn
.param
= (uint8_t)fswtchBLcolor
[i
]->value();
520 fswtchBLcolor
[i
]->setValue(cfn
.param
);
521 widgetsMask
|= CUSTOM_FUNCTION_BL_COLOR
;
524 if (modified
) cfn
.param
= fswtchParam
[i
]->value();
525 fswtchParam
[i
]->setDecimals(0);
526 fswtchParam
[i
]->setSingleStep(1);
527 fswtchParam
[i
]->setValue(cfn
.param
);
528 if (func
<= FuncInstantTrim
) {
529 widgetsMask
|= CUSTOM_FUNCTION_ENABLE
;
533 fswtchParam
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_NUMERIC_PARAM
);
534 fswtchParamTime
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_TIME_PARAM
);
535 fswtchParamGV
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_GV_TOOGLE
);
536 fswtchParamT
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_SOURCE_PARAM
);
537 fswtchParamArmT
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_FILE_PARAM
);
538 fswtchEnable
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_ENABLE
);
539 if (widgetsMask
& CUSTOM_FUNCTION_ENABLE
)
540 fswtchEnable
[i
]->setChecked(cfn
.enabled
);
542 fswtchEnable
[i
]->setChecked(false);
543 fswtchRepeat
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_REPEAT
);
544 fswtchGVmode
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_GV_MODE
);
545 fswtchBLcolor
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_BL_COLOR
);
546 playBT
[i
]->setVisible(widgetsMask
& CUSTOM_FUNCTION_PLAY
);
549 void CustomFunctionsPanel::update()
552 int num_fsw
= model
? firmware
->getCapability(CustomFunctions
) : firmware
->getCapability(GlobalFunctions
);
553 for (int i
=0; i
<num_fsw
; i
++) {
554 refreshCustomFunction(i
);
559 void CustomFunctionsPanel::fswPaste()
561 const QClipboard
*clipboard
= QApplication::clipboard();
562 const QMimeData
*mimeData
= clipboard
->mimeData();
563 if (mimeData
->hasFormat("application/x-companion-fsw")) {
564 QByteArray fswData
= mimeData
->data("application/x-companion-fsw");
565 CustomFunctionData
*fsw
= &functions
[selectedFunction
];
566 memcpy(fsw
, fswData
.constData(), sizeof(CustomFunctionData
));
568 populateSwitchCB(fswtchSwtch
[selectedFunction
], functions
[selectedFunction
].swtch
, generalSettings
, model
? SpecialFunctionsContext
: GlobalFunctionsContext
);
569 populateFuncCB(fswtchFunc
[selectedFunction
], functions
[selectedFunction
].func
);
570 populateGVmodeCB(fswtchGVmode
[selectedFunction
], functions
[selectedFunction
].adjustMode
);
571 populateFuncParamCB(fswtchParamT
[selectedFunction
], functions
[selectedFunction
].func
, functions
[selectedFunction
].param
, functions
[selectedFunction
].adjustMode
);
572 refreshCustomFunction(selectedFunction
);
578 void CustomFunctionsPanel::fswDelete()
580 functions
[selectedFunction
].clear();
581 // TODO update switch and func
583 populateSwitchCB(fswtchSwtch
[selectedFunction
], functions
[selectedFunction
].swtch
, generalSettings
, model
? SpecialFunctionsContext
: GlobalFunctionsContext
);
584 populateFuncCB(fswtchFunc
[selectedFunction
], functions
[selectedFunction
].func
);
585 refreshCustomFunction(selectedFunction
);
590 void CustomFunctionsPanel::fswCopy()
593 fswData
.append((char*)&functions
[selectedFunction
], sizeof(CustomFunctionData
));
594 QMimeData
*mimeData
= new QMimeData
;
595 mimeData
->setData("application/x-companion-fsw", fswData
);
596 QApplication::clipboard()->setMimeData(mimeData
, QClipboard::Clipboard
);
599 void CustomFunctionsPanel::fswCut()
605 void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos
)
607 QLabel
*label
= (QLabel
*)sender();
608 selectedFunction
= label
->property("index").toInt();
610 QPoint globalPos
= label
->mapToGlobal(pos
);
612 const QClipboard
*clipboard
= QApplication::clipboard();
613 const QMimeData
*mimeData
= clipboard
->mimeData();
614 bool hasData
= mimeData
->hasFormat("application/x-companion-fsw");
617 contextMenu
.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(fswCopy()),tr("Ctrl+C"));
618 contextMenu
.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(fswCut()),tr("Ctrl+X"));
619 contextMenu
.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(fswPaste()),tr("Ctrl+V"))->setEnabled(hasData
);
620 contextMenu
.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(fswDelete()),tr("Delete"));
622 contextMenu
.exec(globalPos
);
625 void CustomFunctionsPanel::populateFuncCB(QComboBox
*b
, unsigned int value
)
628 for (unsigned int i
=0; i
<FuncCount
; i
++) {
629 if (((i
>=FuncOverrideCH1
&& i
<=FuncOverrideCH32
) && (!model
|| !firmware
->getCapability(SafetyChannelCustomFunction
))) ||
630 ((i
==FuncVolume
|| i
==FuncBackgroundMusic
|| i
==FuncBackgroundMusicPause
) && !firmware
->getCapability(HasVolume
)) ||
631 ((i
==FuncPlayScript
&& !IS_HORUS_OR_TARANIS(firmware
->getBoard()))) ||
632 ((i
==FuncPlayHaptic
) && !firmware
->getCapability(Haptic
)) ||
633 ((i
==FuncPlayBoth
) && !firmware
->getCapability(HasBeeper
)) ||
634 ((i
==FuncLogs
) && !firmware
->getCapability(HasSDLogs
)) ||
635 ((i
==FuncSetTimer3
) && firmware
->getCapability(Timers
) < 3) ||
636 ((i
==FuncScreenshot
) && IS_HORUS(firmware
->getBoard())) ||
637 ((i
>=FuncRangeCheckInternalModule
&& i
<=FuncBindExternalModule
) && (!model
|| !firmware
->getCapability(DangerousFunctions
))) ||
638 ((i
>=FuncAdjustGV1
&& i
<=FuncAdjustGVLast
) && !firmware
->getCapability(Gvars
))
641 // b->addItem(CustomFunctionData(AssignFunc(i)).funcToString(), i);
642 // QModelIndex index = b->model()->index(i, 0);
644 // b->model()->setData(index, v, Qt::UserRole - 1);
647 b
->addItem(CustomFunctionData(AssignFunc(i
)).funcToString(), i
);
649 b
->setCurrentIndex(b
->count()-1);
655 void CustomFunctionsPanel::populateGVmodeCB(QComboBox
*b
, unsigned int value
)
658 b
->addItem(QObject::tr("Value"));
659 b
->addItem(QObject::tr("Source"));
660 b
->addItem(QObject::tr("GVAR"));
661 b
->addItem(QObject::tr("Increment"));
662 b
->setCurrentIndex(value
);
665 void CustomFunctionsPanel::populateFuncParamCB(QComboBox
*b
, uint function
, unsigned int value
, unsigned int adjustmode
)
669 if (function
==FuncPlaySound
) {
670 CustomFunctionData::populatePlaySoundParams(qs
);
672 b
->setCurrentIndex(value
);
674 else if (function
==FuncPlayHaptic
) {
675 CustomFunctionData::populateHapticParams(qs
);
677 b
->setCurrentIndex(value
);
679 else if (function
==FuncReset
) {
680 CustomFunctionData::populateResetParams(model
, b
, value
);
682 else if (function
==FuncVolume
) {
683 populateSourceCB(b
, RawSource(value
), generalSettings
, model
, POPULATE_NONE
|POPULATE_SOURCES
|POPULATE_VIRTUAL_INPUTS
|POPULATE_TRIMS
|POPULATE_SWITCHES
);
685 else if (function
==FuncPlayValue
) {
686 populateSourceCB(b
, RawSource(value
), generalSettings
, model
, POPULATE_NONE
|POPULATE_SOURCES
|POPULATE_VIRTUAL_INPUTS
|POPULATE_SWITCHES
|POPULATE_GVARS
|POPULATE_TRIMS
|POPULATE_TELEMETRY
|POPULATE_TELEMETRYEXT
|POPULATE_SCRIPT_OUTPUTS
);
688 else if (function
>=FuncAdjustGV1
&& function
<=FuncAdjustGVLast
) {
689 switch (adjustmode
) {
691 populateSourceCB(b
, RawSource(value
), generalSettings
, model
, POPULATE_NONE
|POPULATE_SOURCES
|POPULATE_VIRTUAL_INPUTS
|POPULATE_TRIMS
|POPULATE_SWITCHES
);
694 populateSourceCB(b
, RawSource(value
), generalSettings
, model
, POPULATE_GVARS
);