Projectkk2glider/issue 4086 usb and serial (#4097)
[opentx.git] / companion / src / apppreferencesdialog.cpp
blob83d4c52eee1febbffd1794619f670280800a9709
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 "apppreferencesdialog.h"
22 #include "ui_apppreferencesdialog.h"
23 #include "mainwindow.h"
24 #include "appdata.h"
25 #include "helpers.h"
26 #include "firmwareinterface.h"
27 #ifdef JOYSTICKS
28 #include "joystick.h"
29 #include "joystickdialog.h"
30 #endif
31 #include <QDesktopServices>
32 #include <QtGui>
34 AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
35 QDialog(parent),
36 ui(new Ui::AppPreferencesDialog)
38 ui->setupUi(this);
39 updateLock=false;
40 setWindowIcon(CompanionIcon("apppreferences.png"));
42 initSettings();
43 connect(ui->downloadVerCB, SIGNAL(currentIndexChanged(int)), this, SLOT(baseFirmwareChanged()));
44 connect(this, SIGNAL(accepted()), this, SLOT(writeValues()));
46 #if !defined(JOYSTICKS)
47 ui->joystickCB->hide();
48 ui->joystickCB->setDisabled(true);
49 ui->joystickcalButton->hide();
50 ui->joystickChkB->hide();
51 ui->label_11->hide();
52 #endif
54 shrink();
57 AppPreferencesDialog::~AppPreferencesDialog()
59 delete ui;
62 void AppPreferencesDialog::writeValues()
64 g.useCompanionNightlyBuilds(ui->useCompanionNightlyBuilds->isChecked());
65 g.autoCheckApp(ui->autoCheckCompanion->isChecked());
66 g.useFirmwareNightlyBuilds(ui->useFirmwareNightlyBuilds->isChecked());
67 g.autoCheckFw(ui->autoCheckFirmware->isChecked());
68 g.showSplash(ui->showSplash->isChecked());
69 g.simuSW(ui->simuSW->isChecked());
70 g.useWizard(ui->modelWizard_CB->isChecked());
71 g.historySize(ui->historySize->value());
72 g.backLight(ui->backLightColor->currentIndex());
73 g.profile[g.id()].volumeGain(round(ui->volumeGain->value() * 10.0));
74 g.libDir(ui->libraryPath->text());
75 g.gePath(ui->ge_lineedit->text());
76 g.embedSplashes(ui->splashincludeCB->currentIndex());
77 g.enableBackup(ui->backupEnable->isChecked());
79 if (ui->joystickChkB ->isChecked() && ui->joystickCB->isEnabled()) {
80 g.jsSupport(ui->joystickChkB ->isChecked());
81 g.jsCtrl(ui->joystickCB ->currentIndex());
83 else {
84 g.jsSupport(false);
85 g.jsCtrl(0);
87 g.profile[g.id()].channelOrder(ui->channelorderCB->currentIndex());
88 g.profile[g.id()].defaultMode(ui->stickmodeCB->currentIndex());
89 g.profile[g.id()].renameFwFiles(ui->renameFirmware->isChecked());
90 g.profile[g.id()].burnFirmware(ui->burnFirmware->isChecked());
91 g.profile[g.id()].sdPath(ui->sdPath->text());
92 g.profile[g.id()].pBackupDir(ui->profilebackupPath->text());
93 g.profile[g.id()].penableBackup(ui->pbackupEnable->isChecked());
94 g.profile[g.id()].splashFile(ui->SplashFileName->text());
96 // The profile name may NEVER be empty
97 if (ui->profileNameLE->text().isEmpty())
98 g.profile[g.id()].name(tr("My Radio"));
99 else
100 g.profile[g.id()].name(ui->profileNameLE->text());
102 // If a new fw type has been choosen, several things need to reset
103 current_firmware_variant = getFirmwareVariant();
104 QString id = current_firmware_variant->getId();
105 if (g.profile[g.id()].fwType() != id) {
106 g.profile[g.id()].fwName("");
107 g.profile[g.id()].initFwVariables();
108 g.profile[g.id()].fwType(id);
112 void AppPreferencesDialog::on_snapshotPathButton_clicked()
114 QString fileName = QFileDialog::getExistingDirectory(this, tr("Select your snapshot folder"), g.snapshotDir());
115 if (!fileName.isEmpty()) {
116 g.snapshotDir(fileName);
117 g.snapToClpbrd(false);
118 ui->snapshotPath->setText(fileName);
122 void AppPreferencesDialog::initSettings()
124 ui->snapshotClipboardCKB->setChecked(g.snapToClpbrd());
125 ui->burnFirmware->setChecked(g.profile[g.id()].burnFirmware());
126 ui->snapshotPath->setText(g.snapshotDir());
127 ui->snapshotPath->setReadOnly(true);
128 if (ui->snapshotClipboardCKB->isChecked()) {
129 ui->snapshotPath->setDisabled(true);
130 ui->snapshotPathButton->setDisabled(true);
132 #if defined(ALLOW_NIGHTLY_BUILDS)
133 ui->useCompanionNightlyBuilds->setChecked(g.useCompanionNightlyBuilds());
134 ui->useFirmwareNightlyBuilds->setChecked(g.useFirmwareNightlyBuilds());
135 #else
136 ui->useCompanionNightlyBuilds->hide();
137 ui->useFirmwareNightlyBuilds->hide();
138 #endif
139 ui->autoCheckCompanion->setChecked(g.autoCheckApp());
140 ui->autoCheckFirmware->setChecked(g.autoCheckFw());
141 ui->showSplash->setChecked(g.showSplash());
142 ui->historySize->setValue(g.historySize());
143 ui->backLightColor->setCurrentIndex(g.backLight());
144 ui->volumeGain->setValue(g.profile[g.id()].volumeGain() / 10.0);
146 if (IS_TARANIS(GetCurrentFirmware()->getBoard())) {
147 ui->backLightColor->setEnabled(false);
150 ui->simuSW->setChecked(g.simuSW());
151 ui->modelWizard_CB->setChecked(g.useWizard());
152 ui->libraryPath->setText(g.libDir());
153 ui->ge_lineedit->setText(g.gePath());
155 if (!g.backupDir().isEmpty()) {
156 if (QDir(g.backupDir()).exists()) {
157 ui->backupPath->setText(g.backupDir());
158 ui->backupEnable->setEnabled(true);
159 ui->backupEnable->setChecked(g.enableBackup());
161 else {
162 ui->backupEnable->setDisabled(true);
165 else {
166 ui->backupEnable->setDisabled(true);
168 ui->splashincludeCB->setCurrentIndex(g.embedSplashes());
170 #if defined(JOYSTICKS)
171 ui->joystickChkB->setChecked(g.jsSupport());
172 if (ui->joystickChkB->isChecked()) {
173 QStringList joystickNames;
174 joystickNames << tr("No joysticks found");
175 joystick = new Joystick(0,false,0,0);
176 ui->joystickcalButton->setDisabled(true);
177 ui->joystickCB->setDisabled(true);
179 if ( joystick ) {
180 if ( joystick->joystickNames.count() > 0 ) {
181 joystickNames = joystick->joystickNames;
182 ui->joystickCB->setEnabled(true);
183 ui->joystickcalButton->setEnabled(true);
185 joystick->close();
187 ui->joystickCB->clear();
188 ui->joystickCB->insertItems(0, joystickNames);
189 ui->joystickCB->setCurrentIndex(g.jsCtrl());
191 else {
192 ui->joystickCB->clear();
193 ui->joystickCB->setDisabled(true);
194 ui->joystickcalButton->setDisabled(true);
196 #endif
197 // Profile Tab Inits
198 ui->channelorderCB->setCurrentIndex(g.profile[g.id()].channelOrder());
199 ui->stickmodeCB->setCurrentIndex(g.profile[g.id()].defaultMode());
200 ui->renameFirmware->setChecked(g.profile[g.id()].renameFwFiles());
201 ui->sdPath->setText(g.profile[g.id()].sdPath());
202 if (!g.profile[g.id()].pBackupDir().isEmpty()) {
203 if (QDir(g.profile[g.id()].pBackupDir()).exists()) {
204 ui->profilebackupPath->setText(g.profile[g.id()].pBackupDir());
205 ui->pbackupEnable->setEnabled(true);
206 ui->pbackupEnable->setChecked(g.profile[g.id()].penableBackup());
207 } else {
208 ui->pbackupEnable->setDisabled(true);
211 else {
212 ui->pbackupEnable->setDisabled(true);
215 ui->profileNameLE->setText(g.profile[g.id()].name());
216 ui->SplashFileName->setText(g.profile[g.id()].splashFile());
218 displayImage( g.profile[g.id()].splashFile() );
220 QString hwSettings;
221 if (g.profile[g.id()].stickPotCalib() == "" ) {
222 hwSettings = tr("EMPTY: No radio settings stored in profile");
224 else {
225 QString str = g.profile[g.id()].timeStamp();
226 if (str.isEmpty())
227 hwSettings = tr("AVAILABLE: Radio settings of unknown age");
228 else
229 hwSettings = tr("AVAILABLE: Radio settings stored %1").arg(str);
231 ui->lblGeneralSettings->setText(hwSettings);
233 Firmware * current_firmware = GetCurrentFirmware();
235 foreach(Firmware * firmware, firmwares) {
236 ui->downloadVerCB->addItem(firmware->getName(), firmware->getId());
237 if (current_firmware->getFirmwareBase() == firmware) {
238 ui->downloadVerCB->setCurrentIndex(ui->downloadVerCB->count() - 1);
242 baseFirmwareChanged();
245 void AppPreferencesDialog::on_libraryPathButton_clicked()
247 QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your library folder"), g.libDir());
248 if (!fileName.isEmpty()) {
249 g.libDir(fileName);
250 ui->libraryPath->setText(fileName);
254 void AppPreferencesDialog::on_snapshotClipboardCKB_clicked()
256 if (ui->snapshotClipboardCKB->isChecked()) {
257 ui->snapshotPath->setDisabled(true);
258 ui->snapshotPathButton->setDisabled(true);
259 g.snapToClpbrd(true);
261 else {
262 ui->snapshotPath->setEnabled(true);
263 ui->snapshotPath->setReadOnly(true);
264 ui->snapshotPathButton->setEnabled(true);
265 g.snapToClpbrd(false);
269 void AppPreferencesDialog::on_backupPathButton_clicked()
271 QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your Models and Settings backup folder"), g.backupDir());
272 if (!fileName.isEmpty()) {
273 g.backupDir(fileName);
274 ui->backupPath->setText(fileName);
275 ui->backupEnable->setEnabled(true);
279 void AppPreferencesDialog::on_ProfilebackupPathButton_clicked()
281 QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your Models and Settings backup folder"), g.backupDir());
282 if (!fileName.isEmpty()) {
283 ui->profilebackupPath->setText(fileName);
284 ui->pbackupEnable->setEnabled(true);
288 void AppPreferencesDialog::on_ge_pathButton_clicked()
290 QString fileName = QFileDialog::getOpenFileName(this, tr("Select Google Earth executable"),ui->ge_lineedit->text());
291 if (!fileName.isEmpty()) {
292 ui->ge_lineedit->setText(fileName);
296 #if defined(JOYSTICKS)
297 void AppPreferencesDialog::on_joystickChkB_clicked() {
298 if (ui->joystickChkB->isChecked()) {
299 QStringList joystickNames;
300 joystickNames << tr("No joysticks found");
301 joystick = new Joystick(0,false,0,0);
302 ui->joystickcalButton->setDisabled(true);
303 ui->joystickCB->setDisabled(true);
305 if ( joystick ) {
306 if ( joystick->joystickNames.count() > 0 ) {
307 joystickNames = joystick->joystickNames;
308 ui->joystickCB->setEnabled(true);
309 ui->joystickcalButton->setEnabled(true);
311 joystick->close();
313 ui->joystickCB->clear();
314 ui->joystickCB->insertItems(0, joystickNames);
316 else {
317 ui->joystickCB->clear();
318 ui->joystickCB->setDisabled(true);
319 ui->joystickcalButton->setDisabled(true);
323 void AppPreferencesDialog::on_joystickcalButton_clicked() {
324 joystickDialog * jd=new joystickDialog(this, ui->joystickCB->currentIndex());
325 jd->exec();
327 #endif
329 // ******** Profile tab functions
331 void AppPreferencesDialog::on_sdPathButton_clicked()
333 QString fileName = QFileDialog::getExistingDirectory(this,tr("Select the folder replicating your SD structure"), g.profile[g.id()].sdPath());
334 if (!fileName.isEmpty()) {
335 ui->sdPath->setText(fileName);
339 void AppPreferencesDialog::on_removeProfileButton_clicked()
341 if ( g.id() == 0 ) {
342 QMessageBox::information(this, tr("Not possible to remove profile"), tr("The default profile can not be removed."));
344 else {
345 g.profile[g.id()].remove();
346 g.id( 0 );
347 initSettings();
351 bool AppPreferencesDialog::displayImage(const QString & fileName)
353 // Start by clearing the label
354 ui->imageLabel->clear();
356 QImage image(fileName);
357 if (image.isNull())
358 return false;
360 ui->imageLabel->setPixmap(makePixMap(image));
361 ui->imageLabel->setFixedSize(GetCurrentFirmware()->getCapability(LcdWidth), GetCurrentFirmware()->getCapability(LcdHeight));
362 return true;
365 void AppPreferencesDialog::on_SplashSelect_clicked()
367 QString supportedImageFormats;
368 for (int formatIndex = 0; formatIndex < QImageReader::supportedImageFormats().count(); formatIndex++) {
369 supportedImageFormats += QLatin1String(" *.") + QImageReader::supportedImageFormats()[formatIndex];
372 QString fileName = QFileDialog::getOpenFileName(this,
373 tr("Open Image to load"), g.imagesDir(), tr("Images (%1)").arg(supportedImageFormats));
375 if (!fileName.isEmpty()){
376 g.imagesDir(QFileInfo(fileName).dir().absolutePath());
378 displayImage(fileName);
379 ui->SplashFileName->setText(fileName);
383 void AppPreferencesDialog::on_clearImageButton_clicked()
385 ui->imageLabel->clear();
386 ui->SplashFileName->clear();
390 void AppPreferencesDialog::showVoice(bool show)
392 ui->voiceLabel->setVisible(show);
393 ui->voiceCombo->setVisible(show);
394 QTimer::singleShot(0, this, SLOT(shrink()));
397 void AppPreferencesDialog::baseFirmwareChanged()
399 QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
401 foreach(Firmware * firmware, firmwares) {
402 if (firmware->getId() == selected_firmware) {
403 populateFirmwareOptions(firmware);
404 break;
409 Firmware * AppPreferencesDialog::getFirmwareVariant()
411 QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
413 foreach(Firmware * firmware, firmwares) {
414 QString id = firmware->getId();
415 if (id == selected_firmware) {
416 foreach(QCheckBox *cb, optionsCheckBoxes) {
417 if (cb->isChecked()) {
418 id += QString("-") + cb->text();
422 if (voice && voice->isChecked()) {
423 id += QString("-tts") + ui->voiceCombo->currentText();
426 if (ui->langCombo->count()) {
427 id += QString("-") + ui->langCombo->currentText();
430 return GetFirmware(id);
434 // Should never occur...
435 return default_firmware_variant;
438 void AppPreferencesDialog::firmwareOptionChanged(bool state)
440 QCheckBox *cb = qobject_cast<QCheckBox*>(sender());
441 if (cb == voice) {
442 showVoice(voice->isChecked());
444 Firmware * firmware=NULL;
445 if (cb && state) {
446 QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
447 foreach(firmware, firmwares) {
448 if (firmware->getId() == selected_firmware) {
449 foreach(QList<Option> opts, firmware->opts) {
450 foreach(Option opt, opts) {
451 if (cb->text() == opt.name) {
452 foreach(Option other, opts) {
453 if (other.name != opt.name) {
454 foreach(QCheckBox *ocb, optionsCheckBoxes) {
455 if (ocb->text() == other.name) {
456 ocb->setChecked(false);
461 return;
470 void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware)
472 const Firmware * parent = firmware->getFirmwareBase();
474 updateLock = true;
476 QString id = current_firmware_variant->getId();
477 ui->langCombo->clear();
478 foreach(const char *lang, parent->languages) {
479 ui->langCombo->addItem(lang);
480 if (id.endsWith(lang)) {
481 ui->langCombo->setCurrentIndex(ui->langCombo->count() - 1);
485 voice = NULL; // we will search for a voice checkbox
487 int index = 0;
488 QWidget * prevFocus = ui->voiceCombo;
489 foreach(QList<Option> opts, parent->opts) {
490 foreach(Option opt, opts) {
491 if (index >= optionsCheckBoxes.size()) {
492 QCheckBox * checkbox = new QCheckBox(ui->profileTab);
493 ui->optionsLayout->addWidget(checkbox, optionsCheckBoxes.count()/4, optionsCheckBoxes.count()%4, 1, 1);
494 optionsCheckBoxes.push_back(checkbox);
495 connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(firmwareOptionChanged(bool)));
496 if (prevFocus) {
497 QWidget::setTabOrder(prevFocus, checkbox);
501 QCheckBox *cb = optionsCheckBoxes.at(index++);
502 if (cb) {
503 cb->show();
504 cb->setText(opt.name);
505 cb->setToolTip(opt.tooltip);
506 cb->setCheckState(id.contains(opt.name) ? Qt::Checked : Qt::Unchecked);
507 if (opt.name == QString("voice")) {
508 voice = cb;
510 prevFocus = cb;
515 for (; index<optionsCheckBoxes.size(); index++) {
516 QCheckBox *cb = optionsCheckBoxes.at(index);
517 cb->hide();
518 cb->setCheckState(Qt::Unchecked);
521 ui->voiceCombo->clear();
522 foreach(const char *lang, parent->ttslanguages) {
523 ui->voiceCombo->addItem(lang);
524 if (id.contains(QString("-tts%1").arg(lang))) {
525 ui->voiceCombo->setCurrentIndex(ui->voiceCombo->count() - 1);
529 showVoice(voice && voice->isChecked());
531 updateLock = false;
532 QTimer::singleShot(0, this, SLOT(shrink()));
535 void AppPreferencesDialog::shrink()
537 resize(0,0);