diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 5d1d71535..2adcd05ec 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -159,9 +159,10 @@ set(companion_SRCS splashlibrary.cpp mainwindow.cpp companion.cpp - modelconfigdialog.cpp taranisnotfound.cpp qcustomplot.cpp + wizarddata.cpp + wizarddialog.cpp ) set(companion_MOC_HDRS @@ -183,10 +184,10 @@ set(companion_MOC_HDRS modelslist.h mdichild.h mainwindow.h - modelconfigdialog.h taranisnotfound.h qcustomplot.h helpers.h + wizarddialog.h ) set(companion_UIS @@ -205,7 +206,6 @@ set(companion_UIS customizesplashdialog.ui splashlibrary.ui burndialog.ui - modelconfigdialog.ui taranisnotfound.ui ) diff --git a/companion/src/appdata.cpp b/companion/src/appdata.cpp index c54ff6634..c76cf1559 100644 --- a/companion/src/appdata.cpp +++ b/companion/src/appdata.cpp @@ -1,5 +1,16 @@ -// Companion Application Data Class Definition. -// Author Kjell Kernen +/* + * Author - Kjell Kernen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ #include "appdata.h" @@ -499,7 +510,6 @@ bool AppData::snapToClpbrd() { return _snapToClpbrd; } bool AppData::autoCheckApp() { return _autoCheckApp; } bool AppData::autoCheckFw() { return _autoCheckFw; } bool AppData::simuSW() { return _simuSW; } -bool AppData::enableWizard() { return _enableWizard; } int AppData::backLight() { return _backLight; } int AppData::embedSplashes() { return _embedSplashes; } @@ -508,7 +518,6 @@ int AppData::generalEditTab() { return _generalEditTab; } int AppData::iconSize() { return _iconSize; } int AppData::historySize() { return _historySize; } int AppData::jsCtrl() { return _jsCtrl; } -int AppData::modelEditTab() { return _modelEditTab; } int AppData::id() { return _id; } int AppData::theme() { return _theme; } int AppData::warningId() { return _warningId; } @@ -553,7 +562,6 @@ void AppData::snapToClpbrd (const bool x) { store(x, _snapToClpbrd, void AppData::autoCheckApp (const bool x) { store(x, _autoCheckApp, "startup_check_companion" );} void AppData::autoCheckFw (const bool x) { store(x, _autoCheckFw, "startup_check_fw" );} void AppData::simuSW (const bool x) { store(x, _simuSW, "simuSW" );} -void AppData::enableWizard (const bool x) { store(x, _enableWizard, "wizardEnable" );} void AppData::backLight (const int x) { store(x, _backLight, "backLight" );} void AppData::embedSplashes (const int x) { store(x, _embedSplashes, "embedded_splashes" );} @@ -562,7 +570,6 @@ void AppData::generalEditTab (const int x) { store(x, _generalEditTab, void AppData::iconSize (const int x) { store(x, _iconSize, "icon_size" );} void AppData::historySize (const int x) { store(x, _historySize, "history_size" );} void AppData::jsCtrl (const int x) { store(x, _jsCtrl, "js_ctrl" );} -void AppData::modelEditTab (const int x) { store(x, _modelEditTab, "modelEditTab" );} void AppData::id (const int x) { store(x, _id, "profileId" );} void AppData::theme (const int x) { store(x, _theme, "theme" );} void AppData::warningId (const int x) { store(x, _warningId, "warningId" );} @@ -620,12 +627,14 @@ AppData::AppData() settings.remove("default_mode"); settings.remove("firmware"); settings.remove("lastFw"); + settings.remove("modelEditTab"); settings.remove("Name"); settings.remove("patchImage"); settings.remove("rename_firmware_files"); settings.remove("sdPath"); settings.remove("SplashFileName"); settings.remove("startup_check_companion9x"); + settings.remove("wizardEnable"); // Select the new default profile as current profile id( 0 ); @@ -671,7 +680,6 @@ AppData::AppData() getset( _autoCheckApp, "startup_check_companion" ,true ); getset( _autoCheckFw, "startup_check_fw" ,true ); getset( _simuSW, "simuSW" ,false ); - getset( _enableWizard, "wizardEnable" ,true ); getset( _backLight, "backLight" ,0 ); getset( _embedSplashes, "embedded_splashes" ,0 ); @@ -680,7 +688,6 @@ AppData::AppData() getset( _iconSize, "icon_size" ,2 ); getset( _jsCtrl, "js_ctrl" ,0 ); getset( _historySize, "history_size" ,10 ); - getset( _modelEditTab, "modelEditTab" ,0 ); getset( _id, "profileId" ,0 ); getset( _theme, "theme" ,1 ); getset( _warningId, "warningId" ,0 ); diff --git a/companion/src/appdata.h b/companion/src/appdata.h index bad1a1c7a..f3e0e9922 100644 --- a/companion/src/appdata.h +++ b/companion/src/appdata.h @@ -1,5 +1,16 @@ -// Companion Application Data Class Declaration. -// Author Kjell Kernen +/* + * Author - Kjell Kernen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ // All temporary and permanent global variables are defined here to make // initialization and storage safe and visible. @@ -225,7 +236,6 @@ class AppData: protected CompStoreObj bool _autoCheckApp; bool _autoCheckFw; bool _simuSW; - bool _enableWizard; int _backLight; int _embedSplashes; @@ -234,7 +244,6 @@ class AppData: protected CompStoreObj int _iconSize; int _jsCtrl; int _historySize; - int _modelEditTab; int _id; int _theme; int _warningId; @@ -281,7 +290,6 @@ class AppData: protected CompStoreObj bool autoCheckApp(); bool autoCheckFw(); bool simuSW(); - bool enableWizard(); int backLight(); int embedSplashes(); @@ -290,7 +298,6 @@ class AppData: protected CompStoreObj int iconSize(); int historySize(); int jsCtrl(); - int modelEditTab(); // This variable is unused an can be removed int id(); int theme(); int warningId(); diff --git a/companion/src/apppreferencesdialog.cpp b/companion/src/apppreferencesdialog.cpp index d00e7b08a..3281c7400 100644 --- a/companion/src/apppreferencesdialog.cpp +++ b/companion/src/apppreferencesdialog.cpp @@ -38,7 +38,6 @@ void appPreferencesDialog::writeValues() { g.autoCheckApp(ui->startupCheck_companion9x->isChecked()); g.autoCheckFw(ui->startupCheck_fw->isChecked()); - g.enableWizard(ui->wizardEnable_ChkB->isChecked()); g.showSplash(ui->showSplash->isChecked()); g.simuSW(ui->simuSW->isChecked()); g.historySize(ui->historySize->value()); @@ -102,10 +101,11 @@ void appPreferencesDialog::initSettings() } ui->startupCheck_companion9x->setChecked(g.autoCheckApp()); ui->startupCheck_fw->setChecked(g.autoCheckFw()); - ui->wizardEnable_ChkB->setChecked(g.enableWizard()); ui->showSplash->setChecked(g.showSplash()); ui->historySize->setValue(g.historySize()); ui->backLightColor->setCurrentIndex(g.backLight()); + if (getRadioType(g.profile[g.id()].fwType())==6) // TODO - NOT AT ALL OK. THERE SHOULD BE A COMMON RADIO DEFINITION. + ui->backLightColor->setEnabled(false); ui->simuSW->setChecked(g.simuSW()); ui->libraryPath->setText(g.libDir()); ui->ge_lineedit->setText(g.gePath()); diff --git a/companion/src/apppreferencesdialog.ui b/companion/src/apppreferencesdialog.ui index cb053f298..d883095fc 100644 --- a/companion/src/apppreferencesdialog.ui +++ b/companion/src/apppreferencesdialog.ui @@ -6,8 +6,8 @@ 0 0 - 640 - 499 + 685 + 514 @@ -18,7 +18,7 @@ - 0 + 685 0 @@ -26,21 +26,22 @@ Edit Settings - - 6 - - - 6 - - - 6 - - - 6 - 2 + + 6 + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + @@ -51,20 +52,14 @@ Radio Profile - - + + - Qt::Vertical + Qt::Horizontal - - - 20 - 40 - - - + - + @@ -118,7 +113,7 @@ Mode 4: - + @@ -268,7 +263,7 @@ This is used by the templated to determine which channel goes to what number out - + @@ -288,7 +283,20 @@ This is used by the templated to determine which channel goes to what number out - + + + + Qt::Vertical + + + + 20 + 40 + + + + + @@ -301,7 +309,7 @@ This is used by the templated to determine which channel goes to what number out - + @@ -317,14 +325,14 @@ This is used by the templated to determine which channel goes to what number out - + Append version number to FW file name - + @@ -340,7 +348,7 @@ This is used by the templated to determine which channel goes to what number out - + true @@ -362,28 +370,41 @@ This is used by the templated to determine which channel goes to what number out - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + Offer to write FW to Tx after download - + + + + Remove Profile + + + + Open Folder - - - - Qt::Horizontal - - - - + true @@ -405,14 +426,7 @@ This is used by the templated to determine which channel goes to what number out - - - - Clear Image - - - - + Select Image @@ -426,7 +440,14 @@ This is used by the templated to determine which channel goes to what number out - + + + + Clear Image + + + + Qt::Horizontal @@ -449,7 +470,7 @@ This is used by the templated to determine which channel goes to what number out - + @@ -476,7 +497,7 @@ This is used by the templated to determine which channel goes to what number out QFrame::Plain - 0 + 1 @@ -525,8 +546,52 @@ This is used by the templated to determine which channel goes to what number out - - + + + + General Settings + + + + + + + true + + + General Settings Label + + + + + + + + Application Settings + + + + + + + 350 + 0 + + + + true + + + + + + + Qt::Horizontal + + + + + Qt::Horizontal @@ -538,68 +603,7 @@ This is used by the templated to determine which channel goes to what number out - - - - Remove Profile - - - - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - General Settings - - - - - - - - 0 - 18 - - - - TextLabel - - - - - - - - Application Settings - - - - - - Open Folder - - - - - - - Qt::Horizontal - - - - + Automatic Backup Folder @@ -628,7 +632,7 @@ This is used by the templated to determine which channel goes to what number out - + @@ -641,7 +645,7 @@ This is used by the templated to determine which channel goes to what number out - + @@ -678,7 +682,7 @@ This is used by the templated to determine which channel goes to what number out - + @@ -691,34 +695,21 @@ This is used by the templated to determine which channel goes to what number out - + Open Folder - + Qt::Horizontal - - - - - 350 - 0 - - - - true - - - - + Find Executable @@ -738,7 +729,7 @@ This is used by the templated to determine which channel goes to what number out - + @@ -751,14 +742,34 @@ This is used by the templated to determine which channel goes to what number out - + Enable automatic backup before writing firmware - + + + + Open Folder + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + Qt::Horizontal @@ -775,23 +786,13 @@ This is used by the templated to determine which channel goes to what number out - + Qt::Horizontal - - - - Offer to use wizard for new models - - - true - - - @@ -802,7 +803,20 @@ This is used by the templated to determine which channel goes to what number out - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + true @@ -812,19 +826,6 @@ This is used by the templated to determine which channel goes to what number out - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -865,6 +866,19 @@ This is used by the templated to determine which channel goes to what number out + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -980,33 +994,10 @@ This is used by the templated to determine which channel goes to what number out - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - @@ -1017,7 +1008,6 @@ This is used by the templated to determine which channel goes to what number out showSplash startupCheck_fw startupCheck_companion9x - wizardEnable_ChkB backupPath backupPathButton backupEnable diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc index 733b12a67..9fb054ce9 100644 --- a/companion/src/companion.qrc +++ b/companion/src/companion.qrc @@ -57,107 +57,26 @@ images/x9r3.png images/x9s0.png images/x9t0.png - images/taranison.png - images/mcw/aicon.png - images/mcw/dicon.png - images/mcw/gicon.png - images/mcw/hicon.png - images/mcw/at1e1r.png - images/mcw/at2e1r.png - images/mcw/atailv.png - images/mcw/aw0a0f.png - images/mcw/aw1a0f.png - images/mcw/aw1a1f.png - images/mcw/aw1a2f.png - images/mcw/aw2a0f.png - images/mcw/aw2a1f.png - images/mcw/aw2a2f.png - images/mcw/h90.png - images/mcw/h120.png - images/mcw/h120x.png - images/mcw/h140.png - images/mcw/hfbl.png - images/mcw/htailg.png - images/mcw/htailng.png - images/mcw/htailfblg.png - images/mcw/htailfblng.png - images/mcw/gt1e1r.png - images/mcw/gt2e1r.png - images/mcw/gtailv.png - images/mcw/gw0t0a0f0s.png - images/mcw/gw0t1a0f0s.png - images/mcw/gw0t1a0f1s.png - images/mcw/gw0t1a0f2s.png - images/mcw/gw0t1a1f0s.png - images/mcw/gw0t1a1f1s.png - images/mcw/gw0t1a1f2s.png - images/mcw/gw0t1a2f0s.png - images/mcw/gw0t1a2f1s.png - images/mcw/gw0t1a2f2s.png - images/mcw/gw0t2a0f0s.png - images/mcw/gw0t2a0f1s.png - images/mcw/gw0t2a0f2s.png - images/mcw/gw0t2a1f0s.png - images/mcw/gw0t2a1f1s.png - images/mcw/gw0t2a1f2s.png - images/mcw/gw0t2a2f0s.png - images/mcw/gw0t2a2f1s.png - images/mcw/gw0t2a2f2s.png - images/mcw/gw1t0a0f0s.png - images/mcw/gw1t1a0f0s.png - images/mcw/gw1t1a0f1s.png - images/mcw/gw1t1a0f2s.png - images/mcw/gw1t1a1f0s.png - images/mcw/gw1t1a1f1s.png - images/mcw/gw1t1a1f2s.png - images/mcw/gw1t1a2f0s.png - images/mcw/gw1t1a2f1s.png - images/mcw/gw1t1a2f2s.png - images/mcw/gw1t2a0f0s.png - images/mcw/gw1t2a0f1s.png - images/mcw/gw1t2a0f2s.png - images/mcw/gw1t2a1f0s.png - images/mcw/gw1t2a1f1s.png - images/mcw/gw1t2a1f2s.png - images/mcw/gw1t2a2f0s.png - images/mcw/gw1t2a2f1s.png - images/mcw/gw1t2a2f2s.png - images/mcw/db0t2e0f0r.png - images/mcw/db0t2e0f1r.png - images/mcw/db0t2e0f2r.png - images/mcw/db0t2e1f0r.png - images/mcw/db0t2e1f1r.png - images/mcw/db0t2e1f2r.png - images/mcw/db0t2e2f0r.png - images/mcw/db0t2e2f1r.png - images/mcw/db0t2e2f2r.png - images/mcw/db1t2e0f0r.png - images/mcw/db1t2e0f1r.png - images/mcw/db1t2e0f2r.png - images/mcw/db1t2e1f0r.png - images/mcw/db1t2e1f1r.png - images/mcw/db1t2e1f2r.png - images/mcw/db1t2e2f0r.png - images/mcw/db1t2e2f1r.png - images/mcw/db1t2e2f2r.png - images/mcw/dt0t2e0f0r.png - images/mcw/dt0t2e0f1r.png - images/mcw/dt0t2e0f2r.png - images/mcw/dt0t2e1f0r.png - images/mcw/dt0t2e1f1r.png - images/mcw/dt0t2e1f2r.png - images/mcw/dt0t2e2f0r.png - images/mcw/dt0t2e2f1r.png - images/mcw/dt0t2e2f2r.png - images/mcw/dt1t2e0f0r.png - images/mcw/dt1t2e0f1r.png - images/mcw/dt1t2e0f2r.png - images/mcw/dt1t2e1f0r.png - images/mcw/dt1t2e1f1r.png - images/mcw/dt1t2e1f2r.png - images/mcw/dt1t2e2f0r.png - images/mcw/dt1t2e2f1r.png - images/mcw/dt1t2e2f2r.png + images/taranison.png + images/wizard/ailerons.png + images/wizard/airbrakes.png + images/wizard/bank.png + images/wizard/conclusion.png + images/wizard/cyclic.png + images/wizard/fblheli.png + images/wizard/flaps.png + images/wizard/flybar.png + images/wizard/gyro.png + images/wizard/helictrl.png + images/wizard/models.png + images/wizard/multirotor.png + images/wizard/rudder.png + images/wizard/simpletail.png + images/wizard/tail.png + images/wizard/tails.png + images/wizard/throttle.png + images/wizard/vtail.png + images/wizard/wingtype.png images/library/00001.png images/library/00002.png images/library/00003.png diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index bba2540d8..91964ec18 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -8,6 +8,7 @@ #include "firmwares/ersky9x/ersky9xinterface.h" #include "appdata.h" #include "helpers.h" +#include "wizarddata.h" QString EEPROMWarnings; @@ -909,7 +910,7 @@ GeneralSettings::GeneralSettings() } } -RawSource GeneralSettings::getDefaultSource(unsigned int channel) +RawSource GeneralSettings::getDefaultSource(unsigned int channel) const { unsigned int stick_index = chout_ar[4*templateSetup + channel] - 1; return RawSource(SOURCE_TYPE_STICK, stick_index); @@ -929,6 +930,24 @@ ModelData::ModelData() clear(); } +ModelData::ModelData(const ModelData & src) +{ + *this = src; +} + +ModelData & ModelData::operator = (const ModelData & src) +{ + memcpy(this, &src, sizeof(ModelData)); + + for (int i=0; igetBoard())) { for (int i=0; isrcRaw = settings.getDefaultSource(i); expo->weight = 100; strncpy(inputNames[i], expo->srcRaw.toString().toLatin1().constData(), sizeof(inputNames[i])-1); - MixData * mix = &mixData[i]; - mix->destCh = i+1; - mix->weight = 100; - mix->srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i, this); } } - else { - for (int i=0; igetBoard())) { + setDefaultInputs(settings); + } + + for (int i=0; idestCh = i+1; + mix->weight = 100; + if (IS_TARANIS(GetEepromInterface()->getBoard())) { + mix->srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i, this); + } + else { + mix->srcRaw = RawSource(SOURCE_TYPE_STICK, i); + } + } +} + +void ModelData::setDefaultValues(unsigned int id, const GeneralSettings & settings) { clear(); used = true; diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index e9539db00..15ee10c48 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -416,7 +416,7 @@ class GeneralSettings { public: GeneralSettings(); - RawSource getDefaultSource(unsigned int channel); + RawSource getDefaultSource(unsigned int channel) const; unsigned int version; unsigned int variant; @@ -904,6 +904,8 @@ class ScriptData { class ModelData { public: ModelData(); + ModelData(const ModelData & src); + ModelData & operator = (const ModelData & src); ExpoData * insertInput(const int idx); void removeInput(const int idx); @@ -963,8 +965,9 @@ class ModelData { void clear(); bool isempty(); - void setDefaultMixes(GeneralSettings & settings); - void setDefaultValues(unsigned int id, GeneralSettings & settings); + void setDefaultInputs(const GeneralSettings & settings); + void setDefaultMixes(const GeneralSettings & settings); + void setDefaultValues(unsigned int id, const GeneralSettings & settings); int getTrimValue(int phaseIdx, int trimIdx); void setTrimValue(int phaseIdx, int trimIdx, int value); diff --git a/companion/src/images/mcw/aicon.png b/companion/src/images/mcw/aicon.png deleted file mode 100644 index f593b6de0..000000000 Binary files a/companion/src/images/mcw/aicon.png and /dev/null differ diff --git a/companion/src/images/mcw/at1e1r.png b/companion/src/images/mcw/at1e1r.png deleted file mode 100644 index 1b60bb3fa..000000000 Binary files a/companion/src/images/mcw/at1e1r.png and /dev/null differ diff --git a/companion/src/images/mcw/at2e1r.png b/companion/src/images/mcw/at2e1r.png deleted file mode 100644 index 1a3507886..000000000 Binary files a/companion/src/images/mcw/at2e1r.png and /dev/null differ diff --git a/companion/src/images/mcw/atailv.png b/companion/src/images/mcw/atailv.png deleted file mode 100644 index 31eadc6ba..000000000 Binary files a/companion/src/images/mcw/atailv.png and /dev/null differ diff --git a/companion/src/images/mcw/aw0a0f.png b/companion/src/images/mcw/aw0a0f.png deleted file mode 100644 index 1cea2b7ac..000000000 Binary files a/companion/src/images/mcw/aw0a0f.png and /dev/null differ diff --git a/companion/src/images/mcw/aw1a0f.png b/companion/src/images/mcw/aw1a0f.png deleted file mode 100644 index 41cf475bc..000000000 Binary files a/companion/src/images/mcw/aw1a0f.png and /dev/null differ diff --git a/companion/src/images/mcw/aw1a1f.png b/companion/src/images/mcw/aw1a1f.png deleted file mode 100644 index e5662f22e..000000000 Binary files a/companion/src/images/mcw/aw1a1f.png and /dev/null differ diff --git a/companion/src/images/mcw/aw1a2f.png b/companion/src/images/mcw/aw1a2f.png deleted file mode 100644 index 64e7c56dd..000000000 Binary files a/companion/src/images/mcw/aw1a2f.png and /dev/null differ diff --git a/companion/src/images/mcw/aw2a0f.png b/companion/src/images/mcw/aw2a0f.png deleted file mode 100644 index a19ca05c5..000000000 Binary files a/companion/src/images/mcw/aw2a0f.png and /dev/null differ diff --git a/companion/src/images/mcw/aw2a1f.png b/companion/src/images/mcw/aw2a1f.png deleted file mode 100644 index 97a52a90c..000000000 Binary files a/companion/src/images/mcw/aw2a1f.png and /dev/null differ diff --git a/companion/src/images/mcw/aw2a2f.png b/companion/src/images/mcw/aw2a2f.png deleted file mode 100644 index cb1819f80..000000000 Binary files a/companion/src/images/mcw/aw2a2f.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e0f0r.png b/companion/src/images/mcw/db0t2e0f0r.png deleted file mode 100644 index a73bbcbbc..000000000 Binary files a/companion/src/images/mcw/db0t2e0f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e0f1r.png b/companion/src/images/mcw/db0t2e0f1r.png deleted file mode 100644 index 07339cc83..000000000 Binary files a/companion/src/images/mcw/db0t2e0f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e0f2r.png b/companion/src/images/mcw/db0t2e0f2r.png deleted file mode 100644 index a824ca1a9..000000000 Binary files a/companion/src/images/mcw/db0t2e0f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e1f0r.png b/companion/src/images/mcw/db0t2e1f0r.png deleted file mode 100644 index efeae963d..000000000 Binary files a/companion/src/images/mcw/db0t2e1f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e1f1r.png b/companion/src/images/mcw/db0t2e1f1r.png deleted file mode 100644 index 9930dab84..000000000 Binary files a/companion/src/images/mcw/db0t2e1f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e1f2r.png b/companion/src/images/mcw/db0t2e1f2r.png deleted file mode 100644 index 12641edb4..000000000 Binary files a/companion/src/images/mcw/db0t2e1f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e2f0r.png b/companion/src/images/mcw/db0t2e2f0r.png deleted file mode 100644 index becb783f2..000000000 Binary files a/companion/src/images/mcw/db0t2e2f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e2f1r.png b/companion/src/images/mcw/db0t2e2f1r.png deleted file mode 100644 index 16714038d..000000000 Binary files a/companion/src/images/mcw/db0t2e2f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/db0t2e2f2r.png b/companion/src/images/mcw/db0t2e2f2r.png deleted file mode 100644 index e444189cd..000000000 Binary files a/companion/src/images/mcw/db0t2e2f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e0f0r.png b/companion/src/images/mcw/db1t2e0f0r.png deleted file mode 100644 index 902c5999f..000000000 Binary files a/companion/src/images/mcw/db1t2e0f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e0f1r.png b/companion/src/images/mcw/db1t2e0f1r.png deleted file mode 100644 index 16a2132a0..000000000 Binary files a/companion/src/images/mcw/db1t2e0f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e0f2r.png b/companion/src/images/mcw/db1t2e0f2r.png deleted file mode 100644 index fbc1ef005..000000000 Binary files a/companion/src/images/mcw/db1t2e0f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e1f0r.png b/companion/src/images/mcw/db1t2e1f0r.png deleted file mode 100644 index 0dc293d93..000000000 Binary files a/companion/src/images/mcw/db1t2e1f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e1f1r.png b/companion/src/images/mcw/db1t2e1f1r.png deleted file mode 100644 index 4a76499f4..000000000 Binary files a/companion/src/images/mcw/db1t2e1f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e1f2r.png b/companion/src/images/mcw/db1t2e1f2r.png deleted file mode 100644 index 87afdbdde..000000000 Binary files a/companion/src/images/mcw/db1t2e1f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e2f0r.png b/companion/src/images/mcw/db1t2e2f0r.png deleted file mode 100644 index 2053df985..000000000 Binary files a/companion/src/images/mcw/db1t2e2f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e2f1r.png b/companion/src/images/mcw/db1t2e2f1r.png deleted file mode 100644 index 4a91ef4e9..000000000 Binary files a/companion/src/images/mcw/db1t2e2f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/db1t2e2f2r.png b/companion/src/images/mcw/db1t2e2f2r.png deleted file mode 100644 index be4af6587..000000000 Binary files a/companion/src/images/mcw/db1t2e2f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/dicon.png b/companion/src/images/mcw/dicon.png deleted file mode 100644 index ba7a630ce..000000000 Binary files a/companion/src/images/mcw/dicon.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e0f0r.png b/companion/src/images/mcw/dt0t2e0f0r.png deleted file mode 100644 index 7590cea97..000000000 Binary files a/companion/src/images/mcw/dt0t2e0f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e0f1r.png b/companion/src/images/mcw/dt0t2e0f1r.png deleted file mode 100644 index 8e8a90e3a..000000000 Binary files a/companion/src/images/mcw/dt0t2e0f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e0f2r.png b/companion/src/images/mcw/dt0t2e0f2r.png deleted file mode 100644 index b80bf5ae6..000000000 Binary files a/companion/src/images/mcw/dt0t2e0f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e1f0r.png b/companion/src/images/mcw/dt0t2e1f0r.png deleted file mode 100644 index 6ae2c6f49..000000000 Binary files a/companion/src/images/mcw/dt0t2e1f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e1f1r.png b/companion/src/images/mcw/dt0t2e1f1r.png deleted file mode 100644 index ffccb518a..000000000 Binary files a/companion/src/images/mcw/dt0t2e1f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e1f2r.png b/companion/src/images/mcw/dt0t2e1f2r.png deleted file mode 100644 index 9f0c34621..000000000 Binary files a/companion/src/images/mcw/dt0t2e1f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e2f0r.png b/companion/src/images/mcw/dt0t2e2f0r.png deleted file mode 100644 index 4aa7ad219..000000000 Binary files a/companion/src/images/mcw/dt0t2e2f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e2f1r.png b/companion/src/images/mcw/dt0t2e2f1r.png deleted file mode 100644 index cc0eee059..000000000 Binary files a/companion/src/images/mcw/dt0t2e2f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt0t2e2f2r.png b/companion/src/images/mcw/dt0t2e2f2r.png deleted file mode 100644 index 6e629c769..000000000 Binary files a/companion/src/images/mcw/dt0t2e2f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e0f0r.png b/companion/src/images/mcw/dt1t2e0f0r.png deleted file mode 100644 index a266c4eae..000000000 Binary files a/companion/src/images/mcw/dt1t2e0f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e0f1r.png b/companion/src/images/mcw/dt1t2e0f1r.png deleted file mode 100644 index eae7cdbed..000000000 Binary files a/companion/src/images/mcw/dt1t2e0f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e0f2r.png b/companion/src/images/mcw/dt1t2e0f2r.png deleted file mode 100644 index 45e900679..000000000 Binary files a/companion/src/images/mcw/dt1t2e0f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e1f0r.png b/companion/src/images/mcw/dt1t2e1f0r.png deleted file mode 100644 index 096f24c5b..000000000 Binary files a/companion/src/images/mcw/dt1t2e1f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e1f1r.png b/companion/src/images/mcw/dt1t2e1f1r.png deleted file mode 100644 index 2c8ecb604..000000000 Binary files a/companion/src/images/mcw/dt1t2e1f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e1f2r.png b/companion/src/images/mcw/dt1t2e1f2r.png deleted file mode 100644 index c92f8f02f..000000000 Binary files a/companion/src/images/mcw/dt1t2e1f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e2f0r.png b/companion/src/images/mcw/dt1t2e2f0r.png deleted file mode 100644 index b3fff09e7..000000000 Binary files a/companion/src/images/mcw/dt1t2e2f0r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e2f1r.png b/companion/src/images/mcw/dt1t2e2f1r.png deleted file mode 100644 index 025efe33c..000000000 Binary files a/companion/src/images/mcw/dt1t2e2f1r.png and /dev/null differ diff --git a/companion/src/images/mcw/dt1t2e2f2r.png b/companion/src/images/mcw/dt1t2e2f2r.png deleted file mode 100644 index 22e138ac0..000000000 Binary files a/companion/src/images/mcw/dt1t2e2f2r.png and /dev/null differ diff --git a/companion/src/images/mcw/gicon.png b/companion/src/images/mcw/gicon.png deleted file mode 100644 index 035dd642e..000000000 Binary files a/companion/src/images/mcw/gicon.png and /dev/null differ diff --git a/companion/src/images/mcw/gt1e1r.png b/companion/src/images/mcw/gt1e1r.png deleted file mode 100644 index 20b55ae8e..000000000 Binary files a/companion/src/images/mcw/gt1e1r.png and /dev/null differ diff --git a/companion/src/images/mcw/gt2e1r.png b/companion/src/images/mcw/gt2e1r.png deleted file mode 100644 index ebde7ca17..000000000 Binary files a/companion/src/images/mcw/gt2e1r.png and /dev/null differ diff --git a/companion/src/images/mcw/gtailv.png b/companion/src/images/mcw/gtailv.png deleted file mode 100644 index d14df9f8b..000000000 Binary files a/companion/src/images/mcw/gtailv.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t0a0f0s.png b/companion/src/images/mcw/gw0t0a0f0s.png deleted file mode 100644 index 6604948b3..000000000 Binary files a/companion/src/images/mcw/gw0t0a0f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a0f0s.png b/companion/src/images/mcw/gw0t1a0f0s.png deleted file mode 100644 index d9755ba82..000000000 Binary files a/companion/src/images/mcw/gw0t1a0f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a0f1s.png b/companion/src/images/mcw/gw0t1a0f1s.png deleted file mode 100644 index fc77a33ea..000000000 Binary files a/companion/src/images/mcw/gw0t1a0f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a0f2s.png b/companion/src/images/mcw/gw0t1a0f2s.png deleted file mode 100644 index a2af45705..000000000 Binary files a/companion/src/images/mcw/gw0t1a0f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a1f0s.png b/companion/src/images/mcw/gw0t1a1f0s.png deleted file mode 100644 index 668ac0593..000000000 Binary files a/companion/src/images/mcw/gw0t1a1f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a1f1s.png b/companion/src/images/mcw/gw0t1a1f1s.png deleted file mode 100644 index 4b6e7f7ed..000000000 Binary files a/companion/src/images/mcw/gw0t1a1f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a1f2s.png b/companion/src/images/mcw/gw0t1a1f2s.png deleted file mode 100644 index 475a5d60b..000000000 Binary files a/companion/src/images/mcw/gw0t1a1f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a2f0s.png b/companion/src/images/mcw/gw0t1a2f0s.png deleted file mode 100644 index 5e1bd0be6..000000000 Binary files a/companion/src/images/mcw/gw0t1a2f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a2f1s.png b/companion/src/images/mcw/gw0t1a2f1s.png deleted file mode 100644 index 66cc21144..000000000 Binary files a/companion/src/images/mcw/gw0t1a2f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t1a2f2s.png b/companion/src/images/mcw/gw0t1a2f2s.png deleted file mode 100644 index 535b08f0d..000000000 Binary files a/companion/src/images/mcw/gw0t1a2f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a0f0s.png b/companion/src/images/mcw/gw0t2a0f0s.png deleted file mode 100644 index f2acb1189..000000000 Binary files a/companion/src/images/mcw/gw0t2a0f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a0f1s.png b/companion/src/images/mcw/gw0t2a0f1s.png deleted file mode 100644 index c4ec3e332..000000000 Binary files a/companion/src/images/mcw/gw0t2a0f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a0f2s.png b/companion/src/images/mcw/gw0t2a0f2s.png deleted file mode 100644 index 2e116cbb2..000000000 Binary files a/companion/src/images/mcw/gw0t2a0f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a1f0s.png b/companion/src/images/mcw/gw0t2a1f0s.png deleted file mode 100644 index 067f47949..000000000 Binary files a/companion/src/images/mcw/gw0t2a1f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a1f1s.png b/companion/src/images/mcw/gw0t2a1f1s.png deleted file mode 100644 index fa7cedfd3..000000000 Binary files a/companion/src/images/mcw/gw0t2a1f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a1f2s.png b/companion/src/images/mcw/gw0t2a1f2s.png deleted file mode 100644 index 16e2e75ad..000000000 Binary files a/companion/src/images/mcw/gw0t2a1f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a2f0s.png b/companion/src/images/mcw/gw0t2a2f0s.png deleted file mode 100644 index a7c9e96e9..000000000 Binary files a/companion/src/images/mcw/gw0t2a2f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a2f1s.png b/companion/src/images/mcw/gw0t2a2f1s.png deleted file mode 100644 index 3e95b67e2..000000000 Binary files a/companion/src/images/mcw/gw0t2a2f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw0t2a2f2s.png b/companion/src/images/mcw/gw0t2a2f2s.png deleted file mode 100644 index 5dbc36f1c..000000000 Binary files a/companion/src/images/mcw/gw0t2a2f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t0a0f0s.png b/companion/src/images/mcw/gw1t0a0f0s.png deleted file mode 100644 index 1cc9964f5..000000000 Binary files a/companion/src/images/mcw/gw1t0a0f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a0f0s.png b/companion/src/images/mcw/gw1t1a0f0s.png deleted file mode 100644 index 002927aad..000000000 Binary files a/companion/src/images/mcw/gw1t1a0f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a0f1s.png b/companion/src/images/mcw/gw1t1a0f1s.png deleted file mode 100644 index 687aa3d77..000000000 Binary files a/companion/src/images/mcw/gw1t1a0f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a0f2s.png b/companion/src/images/mcw/gw1t1a0f2s.png deleted file mode 100644 index 8da28c64c..000000000 Binary files a/companion/src/images/mcw/gw1t1a0f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a1f0s.png b/companion/src/images/mcw/gw1t1a1f0s.png deleted file mode 100644 index 7fa51b589..000000000 Binary files a/companion/src/images/mcw/gw1t1a1f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a1f1s.png b/companion/src/images/mcw/gw1t1a1f1s.png deleted file mode 100644 index 43306d05d..000000000 Binary files a/companion/src/images/mcw/gw1t1a1f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a1f2s.png b/companion/src/images/mcw/gw1t1a1f2s.png deleted file mode 100644 index e10d75ae7..000000000 Binary files a/companion/src/images/mcw/gw1t1a1f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a2f0s.png b/companion/src/images/mcw/gw1t1a2f0s.png deleted file mode 100644 index 6eb1e395e..000000000 Binary files a/companion/src/images/mcw/gw1t1a2f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a2f1s.png b/companion/src/images/mcw/gw1t1a2f1s.png deleted file mode 100644 index c1ad61c7d..000000000 Binary files a/companion/src/images/mcw/gw1t1a2f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t1a2f2s.png b/companion/src/images/mcw/gw1t1a2f2s.png deleted file mode 100644 index d4658221a..000000000 Binary files a/companion/src/images/mcw/gw1t1a2f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a0f0s.png b/companion/src/images/mcw/gw1t2a0f0s.png deleted file mode 100644 index 927caea69..000000000 Binary files a/companion/src/images/mcw/gw1t2a0f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a0f1s.png b/companion/src/images/mcw/gw1t2a0f1s.png deleted file mode 100644 index 92caadaed..000000000 Binary files a/companion/src/images/mcw/gw1t2a0f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a0f2s.png b/companion/src/images/mcw/gw1t2a0f2s.png deleted file mode 100644 index 7a658fd19..000000000 Binary files a/companion/src/images/mcw/gw1t2a0f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a1f0s.png b/companion/src/images/mcw/gw1t2a1f0s.png deleted file mode 100644 index 865ece280..000000000 Binary files a/companion/src/images/mcw/gw1t2a1f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a1f1s.png b/companion/src/images/mcw/gw1t2a1f1s.png deleted file mode 100644 index 897a7f8ae..000000000 Binary files a/companion/src/images/mcw/gw1t2a1f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a1f2s.png b/companion/src/images/mcw/gw1t2a1f2s.png deleted file mode 100644 index 99466bc25..000000000 Binary files a/companion/src/images/mcw/gw1t2a1f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a2f0s.png b/companion/src/images/mcw/gw1t2a2f0s.png deleted file mode 100644 index ebaf6a19c..000000000 Binary files a/companion/src/images/mcw/gw1t2a2f0s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a2f1s.png b/companion/src/images/mcw/gw1t2a2f1s.png deleted file mode 100644 index 5fd800df7..000000000 Binary files a/companion/src/images/mcw/gw1t2a2f1s.png and /dev/null differ diff --git a/companion/src/images/mcw/gw1t2a2f2s.png b/companion/src/images/mcw/gw1t2a2f2s.png deleted file mode 100644 index 915771f83..000000000 Binary files a/companion/src/images/mcw/gw1t2a2f2s.png and /dev/null differ diff --git a/companion/src/images/mcw/h120.png b/companion/src/images/mcw/h120.png deleted file mode 100644 index 0827df6b6..000000000 Binary files a/companion/src/images/mcw/h120.png and /dev/null differ diff --git a/companion/src/images/mcw/h120x.png b/companion/src/images/mcw/h120x.png deleted file mode 100644 index d43f70e12..000000000 Binary files a/companion/src/images/mcw/h120x.png and /dev/null differ diff --git a/companion/src/images/mcw/h140.png b/companion/src/images/mcw/h140.png deleted file mode 100644 index 04562ab9a..000000000 Binary files a/companion/src/images/mcw/h140.png and /dev/null differ diff --git a/companion/src/images/mcw/h90.png b/companion/src/images/mcw/h90.png deleted file mode 100644 index 935e3d390..000000000 Binary files a/companion/src/images/mcw/h90.png and /dev/null differ diff --git a/companion/src/images/mcw/hfbl.png b/companion/src/images/mcw/hfbl.png deleted file mode 100644 index 9f344adff..000000000 Binary files a/companion/src/images/mcw/hfbl.png and /dev/null differ diff --git a/companion/src/images/mcw/hicon.png b/companion/src/images/mcw/hicon.png deleted file mode 100644 index 270da8365..000000000 Binary files a/companion/src/images/mcw/hicon.png and /dev/null differ diff --git a/companion/src/images/mcw/htailfblg.png b/companion/src/images/mcw/htailfblg.png deleted file mode 100644 index c0220ab6f..000000000 Binary files a/companion/src/images/mcw/htailfblg.png and /dev/null differ diff --git a/companion/src/images/mcw/htailfblng.png b/companion/src/images/mcw/htailfblng.png deleted file mode 100644 index 8f9db5d70..000000000 Binary files a/companion/src/images/mcw/htailfblng.png and /dev/null differ diff --git a/companion/src/images/mcw/htailg.png b/companion/src/images/mcw/htailg.png deleted file mode 100644 index 225ab38d2..000000000 Binary files a/companion/src/images/mcw/htailg.png and /dev/null differ diff --git a/companion/src/images/mcw/htailng.png b/companion/src/images/mcw/htailng.png deleted file mode 100644 index 6752fd6f2..000000000 Binary files a/companion/src/images/mcw/htailng.png and /dev/null differ diff --git a/companion/src/images/wizard/ailerons.png b/companion/src/images/wizard/ailerons.png new file mode 100644 index 000000000..26ef75eb7 Binary files /dev/null and b/companion/src/images/wizard/ailerons.png differ diff --git a/companion/src/images/wizard/airbrakes.png b/companion/src/images/wizard/airbrakes.png new file mode 100644 index 000000000..1802e1479 Binary files /dev/null and b/companion/src/images/wizard/airbrakes.png differ diff --git a/companion/src/images/wizard/bank.png b/companion/src/images/wizard/bank.png new file mode 100644 index 000000000..5697f3eed Binary files /dev/null and b/companion/src/images/wizard/bank.png differ diff --git a/companion/src/images/wizard/conclusion.png b/companion/src/images/wizard/conclusion.png new file mode 100644 index 000000000..8b188491d Binary files /dev/null and b/companion/src/images/wizard/conclusion.png differ diff --git a/companion/src/images/wizard/cyclic.png b/companion/src/images/wizard/cyclic.png new file mode 100644 index 000000000..1d5a5cdc4 Binary files /dev/null and b/companion/src/images/wizard/cyclic.png differ diff --git a/companion/src/images/wizard/fblheli.png b/companion/src/images/wizard/fblheli.png new file mode 100644 index 000000000..6ff59f70e Binary files /dev/null and b/companion/src/images/wizard/fblheli.png differ diff --git a/companion/src/images/wizard/flaps.png b/companion/src/images/wizard/flaps.png new file mode 100644 index 000000000..629e6d569 Binary files /dev/null and b/companion/src/images/wizard/flaps.png differ diff --git a/companion/src/images/wizard/flybar.png b/companion/src/images/wizard/flybar.png new file mode 100644 index 000000000..a90f242b1 Binary files /dev/null and b/companion/src/images/wizard/flybar.png differ diff --git a/companion/src/images/wizard/gyro.png b/companion/src/images/wizard/gyro.png new file mode 100644 index 000000000..1fef2d933 Binary files /dev/null and b/companion/src/images/wizard/gyro.png differ diff --git a/companion/src/images/wizard/helictrl.png b/companion/src/images/wizard/helictrl.png new file mode 100644 index 000000000..4f12808f8 Binary files /dev/null and b/companion/src/images/wizard/helictrl.png differ diff --git a/companion/src/images/wizard/models.png b/companion/src/images/wizard/models.png new file mode 100644 index 000000000..ab1fe8bca Binary files /dev/null and b/companion/src/images/wizard/models.png differ diff --git a/companion/src/images/wizard/multirotor.png b/companion/src/images/wizard/multirotor.png new file mode 100644 index 000000000..c99203dbd Binary files /dev/null and b/companion/src/images/wizard/multirotor.png differ diff --git a/companion/src/images/wizard/rudder.png b/companion/src/images/wizard/rudder.png new file mode 100644 index 000000000..6c4618c62 Binary files /dev/null and b/companion/src/images/wizard/rudder.png differ diff --git a/companion/src/images/wizard/simpletail.png b/companion/src/images/wizard/simpletail.png new file mode 100644 index 000000000..710681292 Binary files /dev/null and b/companion/src/images/wizard/simpletail.png differ diff --git a/companion/src/images/wizard/tail.png b/companion/src/images/wizard/tail.png new file mode 100644 index 000000000..7419c97ad Binary files /dev/null and b/companion/src/images/wizard/tail.png differ diff --git a/companion/src/images/wizard/tails.png b/companion/src/images/wizard/tails.png new file mode 100644 index 000000000..00320c0e1 Binary files /dev/null and b/companion/src/images/wizard/tails.png differ diff --git a/companion/src/images/wizard/throttle.png b/companion/src/images/wizard/throttle.png new file mode 100644 index 000000000..bf46fcdea Binary files /dev/null and b/companion/src/images/wizard/throttle.png differ diff --git a/companion/src/images/wizard/vtail.png b/companion/src/images/wizard/vtail.png new file mode 100644 index 000000000..d804b7591 Binary files /dev/null and b/companion/src/images/wizard/vtail.png differ diff --git a/companion/src/images/wizard/wingtype.png b/companion/src/images/wizard/wingtype.png new file mode 100644 index 000000000..a9481470d Binary files /dev/null and b/companion/src/images/wizard/wingtype.png differ diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 9d8f62c2c..0be3b9442 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -1759,7 +1759,7 @@ QMenu *MainWindow::createRecentFileMenu() QMenu *MainWindow::createProfilesMenu() { - QMenu *profilesMenu=new QMenu(tr("Radio Settings Profile")); + QMenu *profilesMenu=new QMenu(tr("Radio Profile")); int i; for ( i = 0; i < MAX_PROFILES; ++i) { profilesMenu->addAction(profileActs[i]); @@ -1818,8 +1818,8 @@ void MainWindow::createToolBars() profileButton->setFocusPolicy(Qt::NoFocus); profileButton->setMenu(createProfilesMenu()); profileButton->setIcon(CompanionIcon("profiles.png")); - profileButton->setToolTip(tr("Radio Settings Profile")); - profileButton->setStatusTip(tr("Show a selection list of radio settings profiles")); + profileButton->setToolTip(tr("Radio Profile")); + profileButton->setStatusTip(tr("Show a selection list of radio profiles")); fileToolBar->addWidget(profileButton); fileToolBar->addAction(editSplashAct); diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 2da871fd7..6b20bcc61 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -1,708 +1,729 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mdichild.h" -#include "ui_mdichild.h" -#include "xmlinterface.h" -#include "hexinterface.h" -#include "mainwindow.h" -#include "modeledit/modeledit.h" -#include "generaledit.h" -#include "avroutputdialog.h" -#include "burnconfigdialog.h" -#include "printdialog.h" -#include "burndialog.h" -#include "helpers.h" -#include "appdata.h" -#include "taranisnotfound.h" -#include - -#if defined WIN32 || !defined __GNUC__ -#include -#define sleep(x) Sleep(x*1000) -#else -#include -#endif - -MdiChild::MdiChild(): - QWidget(), - ui(new Ui::mdiChild), - isUntitled(true), - fileChanged(false) -{ - ui->setupUi(this); - - this->setWindowIcon(CompanionIcon("open.png")); - ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png")); - setAttribute(Qt::WA_DeleteOnClose); - - eepromInterfaceChanged(); - - if(!(this->isMaximized() || this->isMinimized())) { - adjustSize(); - } -} - -void MdiChild::qSleep(int ms) -{ - if (ms<0) - return; - -#if defined WIN32 || !defined __GNUC__ - Sleep(uint(ms)); -#else - struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; - nanosleep(&ts, NULL); -#endif -} - -void MdiChild::eepromInterfaceChanged() -{ - ui->modelsList->refreshList(); - ui->SimulateTxButton->setEnabled(GetEepromInterface()->getCapability(Simulation)); - updateTitle(); -} - -void MdiChild::cut() -{ - ui->modelsList->cut(); -} - -void MdiChild::copy() -{ - ui->modelsList->copy(); -} - -void MdiChild::paste() -{ - ui->modelsList->paste(); -} - -bool MdiChild::hasPasteData() -{ - return ui->modelsList->hasPasteData(); -} - -bool MdiChild::hasSelection() -{ - return ui->modelsList->hasSelection(); -} - -void MdiChild::updateTitle() -{ - QString title = userFriendlyCurrentFile() + "[*]"+" ("+GetEepromInterface()->getName()+QString(")"); - if (GetEepromInterface()->getBoard() != BOARD_SKY9X) - title += QString(" - %1 ").arg(EEPromAvail) + tr("free bytes"); - setWindowTitle(title); -} - -void MdiChild::setModified() -{ - ui->modelsList->refreshList(); - fileChanged = true; - updateTitle(); - documentWasModified(); -} - -void MdiChild::on_SimulateTxButton_clicked() -{ - startSimulation(this, radioData, -1); -} - -void MdiChild::OpenEditWindow(bool wizard=false) -{ - int row = ui->modelsList->currentRow(); - - if (row) { - //TODO error checking - bool isNew = false; - ModelData &model = radioData.models[row - 1]; - - if (model.isempty()) { - model.setDefaultValues(row - 1, radioData.generalSettings); - isNew = true; //modeledit - clear mixes, apply first template - setModified(); - } - if (isNew && !wizard) { - int ret; - bool wizardEnable=g.enableWizard(); - if (wizardEnable) { - ret = QMessageBox::question(this, tr("Companion"), tr("Do you want to use model wizard? "), QMessageBox::Yes | QMessageBox::No); - if (ret == QMessageBox::Yes) { - wizard=true; - } - else { - qSleep(500); - ret = QMessageBox::question(this, tr("Companion"), tr("Ask this question again ? "), QMessageBox::Yes | QMessageBox::No); - if (ret == QMessageBox::No) { - g.enableWizard( false ); - } - } - } - } - QApplication::setOverrideCursor(Qt::WaitCursor); - ModelEdit *t = new ModelEdit(radioData, (row - 1), wizard, this); - // TODO if (isNew && !wizard) t->applyBaseTemplate(); - t->setWindowTitle(tr("Editing model %1: ").arg(row) + model.name); - connect(t, SIGNAL(modified()), this, SLOT(setModified())); - //t->exec(); - t->show(); - } - else { - QApplication::setOverrideCursor(Qt::WaitCursor); - GeneralEdit *t = new GeneralEdit(radioData, this); - connect(t, SIGNAL(modelValuesChanged()), this, SLOT(setModified())); - t->show(); - } - QApplication::restoreOverrideCursor(); -} - -void MdiChild::newFile() -{ - static int sequenceNumber = 1; - - isUntitled = true; - curFile = QString("document%1.eepe").arg(sequenceNumber++); - updateTitle(); -} - -bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile) -{ - QFile file(fileName); - - if (!file.exists()) { - QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); - return false; - } - - int fileType = getFileType(fileName); - - if (fileType==FILE_TYPE_XML) { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } - QTextStream inputStream(&file); - XmlInterface(inputStream).load(radioData); - } - else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } - - QDomDocument doc(ER9X_EEPROM_FILE_TYPE); - bool xmlOK = doc.setContent(&file); - if(xmlOK) { - if (LoadEepromXml(radioData, doc)){ - ui->modelsList->refreshList(); - if(resetCurrentFile) setCurrentFile(fileName); - return true; - } - } - file.reset(); - - QTextStream inputStream(&file); - - if (fileType==FILE_TYPE_EEPE) { // read EEPE file header - QString hline = inputStream.readLine(); - if (hline!=EEPE_EEPROM_FILE_HEADER) { - file.close(); - return false; - } - } - - uint8_t eeprom[EESIZE_RLC_MAX]; - int eeprom_size = HexInterface(inputStream).load(eeprom, EESIZE_RLC_MAX); - if (!eeprom_size) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid EEPROM File %1") - .arg(fileName)); - file.close(); - return false; - } - - file.close(); - - if (!LoadEeprom(radioData, eeprom, eeprom_size)) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid EEPROM File %1") - .arg(fileName)); - return false; - } - - ui->modelsList->refreshList(); - if(resetCurrentFile) setCurrentFile(fileName); - - return true; - } - else if (fileType==FILE_TYPE_BIN) { //read binary - int eeprom_size = file.size(); - - if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } - uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); - memset(eeprom, 0, eeprom_size); - long result = file.read((char*)eeprom, eeprom_size); - file.close(); - - if (result != eeprom_size) { - QMessageBox::critical(this, tr("Error"), - tr("Error reading file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - - return false; - } - - if (!LoadEeprom(radioData, eeprom, eeprom_size) && !LoadBackup(radioData, eeprom, eeprom_size, 0)) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid binary EEPROM File %1") - .arg(fileName)); - return false; - } - - ui->modelsList->refreshList(); - if(resetCurrentFile) setCurrentFile(fileName); - - free(eeprom); - return true; - } - - return false; -} - -bool MdiChild::save() -{ - if (isUntitled) { - return saveAs(true); - } - else { - return saveFile(curFile); - } -} - -bool MdiChild::saveAs(bool isNew) -{ - QString fileName; - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { - curFile.replace(".eepe", ".bin"); - QFileInfo fi(curFile); -#ifdef __APPLE__ - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); -#else - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(BIN_FILES_FILTER)); -#endif - } - else { - QFileInfo fi(curFile); -#ifdef __APPLE__ - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); -#else - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(EEPROM_FILES_FILTER)); -#endif - } - if (fileName.isEmpty()) - return false; - if (fileName.contains("rev4a")) { - g.rev4aSupport( true ); - } - if (fileName.contains("norev4a")) { - g.rev4aSupport( false ); - } - g.eepromDir( QFileInfo(fileName).dir().absolutePath() ); - if (isNew) - return saveFile(fileName); - else - return saveFile(fileName,true); -} - -bool MdiChild::saveFile(const QString &fileName, bool setCurrent) -{ - QString myFile; - myFile = fileName; - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { - myFile.replace(".eepe", ".bin"); - } - QFile file(myFile); - - int fileType = getFileType(myFile); - - uint8_t *eeprom = (uint8_t*)malloc(GetEepromInterface()->getEEpromSize()); - int eeprom_size = 0; - - if (fileType != FILE_TYPE_XML) { - eeprom_size = GetEepromInterface()->save(eeprom, radioData, GetCurrentFirmwareVariant(), 0/*last version*/); - if (!eeprom_size) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - return false; - } - } - - if (!file.open(fileType == FILE_TYPE_BIN ? QIODevice::WriteOnly : (QIODevice::WriteOnly | QIODevice::Text))) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - return false; - } - - QTextStream outputStream(&file); - - if (fileType==FILE_TYPE_XML) { - if (!XmlInterface(outputStream).save(radioData)) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - file.close(); - return false; - } - } - else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { // write hex - if (fileType==FILE_TYPE_EEPE) - outputStream << EEPE_EEPROM_FILE_HEADER << "\n"; - - if (!HexInterface(outputStream).save(eeprom, eeprom_size)) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - file.close(); - return false; - } - } - else if (fileType==FILE_TYPE_BIN) // write binary - { - long result = file.write((char*)eeprom, eeprom_size); - if(result!=eeprom_size) { - QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg(file.errorString())); - return false; - } - } - else { - QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg("Unknown format")); - return false; - } - - free(eeprom); // TODO free in all cases ... - file.close(); - if(setCurrent) setCurrentFile(myFile); - - return true; -} - -QString MdiChild::userFriendlyCurrentFile() -{ - return strippedName(curFile); -} - -void MdiChild::closeEvent(QCloseEvent *event) -{ - if (maybeSave()) { - event->accept(); - } - else { - event->ignore(); - } -} - -void MdiChild::documentWasModified() -{ - setWindowModified(fileChanged); -} - -bool MdiChild::maybeSave() -{ - if (fileChanged) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("Companion"), - tr("%1 has been modified.\n" - "Do you want to save your changes?").arg(userFriendlyCurrentFile()), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; - } - return true; -} - -void MdiChild::setCurrentFile(const QString &fileName) -{ - curFile = QFileInfo(fileName).canonicalFilePath(); - isUntitled = false; - fileChanged = false; - setWindowModified(false); - updateTitle(); - int MaxRecentFiles = g.historySize(); - QStringList files = g.recentFiles(); - files.removeAll(fileName); - files.prepend(fileName); - while (files.size() > MaxRecentFiles) - files.removeLast(); - - g.recentFiles( files ); -} - -QString MdiChild::strippedName(const QString &fullFileName) -{ - return QFileInfo(fullFileName).fileName(); -} - -void MdiChild::writeEeprom() // write to Tx -{ - bool backupEnable=g.enableBackup(); - QString backupPath=g.backupDir(); - if (!backupPath.isEmpty()) { - if (!QDir(backupPath).exists()) { - if (backupEnable) { - QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist")); - } - backupEnable=false; - } - } - else { - backupEnable=false; - } - QString stickCal=g.profile[g.id()].stickPotCalib(); - burnConfigDialog bcd; - QString tempDir = QDir::tempPath(); - QString tempFile = tempDir + "/temp.bin"; - saveFile(tempFile, false); - if(!QFileInfo(tempFile).exists()) { - QMessageBox::critical(this,tr("Error"), tr("Cannot write temporary file!")); - return; - } - EEPROMInterface *eepromInterface = GetEepromInterface(); - bool backup=false; - burnDialog *cd = new burnDialog(this, 1, &tempFile, &backup,strippedName(curFile)); - cd->exec(); - if (!tempFile.isEmpty()) { - if (backup) { - if (backupEnable) { - QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss")+".bin"; - if (IS_TARANIS(eepromInterface->getBoard())) { - QString path=((MainWindow *)this->parent())->FindTaranisPath(); - if (path.isEmpty()) { - taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); - tnfd->exec(); - return; - } - else { - QStringList str; - str << path << backupFile; - avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Backup EEPROM From Tx")); //, AVR_DIALOG_KEEP_OPEN); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - else { - QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); - avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx")); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - int oldrev=((MainWindow *)this->parent())->getEpromVersion(tempFile); - QString tempFlash=tempDir + "/flash.bin"; - QStringList str = ((MainWindow *)this->parent())->GetReceiveFlashCommand(tempFlash); - avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, "Read Flash From Tx"); - ad->setWindowIcon(CompanionIcon("read_flash.png")); - ad->exec(); - delete ad; - sleep(1); - QString restoreFile = tempDir + "/compat.bin"; - if (!((MainWindow *)this->parent())->convertEEPROM(tempFile, restoreFile, tempFlash)) { - int ret = QMessageBox::question(this, tr("Error"), tr("Cannot check eeprom compatibility! Continue anyway?"), QMessageBox::Yes | QMessageBox::No); - if (ret == QMessageBox::No) - return; - } - else { - int rev=((MainWindow *)this->parent())->getEpromVersion(restoreFile); - if ((rev/100)!=(oldrev/100)) { - QMessageBox::warning(this,tr("Warning"), tr("Firmware in radio is of a different family of eeprom written, check file and preferences!")); - } - if (revgetBoard())) { - QString path=((MainWindow *)this->parent())->FindTaranisPath(); - if (path.isEmpty()) { - taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); - tnfd->exec(); - return; - } - else { - QFile::copy(path,backupFile); - } - } - else { - QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); - avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx")); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - } - - if (IS_TARANIS(eepromInterface->getBoard())) { - QString path=((MainWindow *)this->parent())->FindTaranisPath(); - if (path.isEmpty()) { - taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); - tnfd->exec(); - return; - } - else { - QStringList str; - str << tempFile << path; - avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Write EEPROM To Tx"), AVR_DIALOG_SHOW_DONE); //, AVR_DIALOG_KEEP_OPEN); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - else { - QStringList str = ((MainWindow *)this->parent())->GetSendEEpromCommand(tempFile); - avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, "Write EEPROM To Tx", AVR_DIALOG_SHOW_DONE); - ad->setWindowIcon(CompanionIcon("write_eeprom.png")); - ad->exec(); - delete ad; - } - } -} - -void MdiChild::simulate() -{ - if (ui->modelsList->currentRow() >= 1) { - startSimulation(this, radioData, ui->modelsList->currentRow()-1); - } -} - -void MdiChild::print(int model, QString filename) -{ - if (model>=0 && !filename.isEmpty()) { - - printDialog *pd = new printDialog(this, &radioData.generalSettings, &radioData.models[model], filename); - pd->show(); - } - else { - if(ui->modelsList->currentRow()<1) return; - printDialog *pd = new printDialog(this, &radioData.generalSettings, &radioData.models[ui->modelsList->currentRow()-1]); - pd->show(); - } -} - -void MdiChild::viableModelSelected(bool viable) -{ - emit copyAvailable(viable); -} - -void MdiChild::setEEpromAvail(int eavail) -{ - EEPromAvail=eavail; -} - -bool MdiChild::loadBackup() -{ - QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(),tr(EEPROM_FILES_FILTER)); - if (fileName.isEmpty()) - return false; - QFile file(fileName); - - if (!file.exists()) { - QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); - return false; - } - if(ui->modelsList->currentRow()<1) return false; - int index=ui->modelsList->currentRow()-1; - - int eeprom_size = file.size(); - if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } - QByteArray eeprom(eeprom_size, 0); - long result = file.read((char*)eeprom.data(), eeprom_size); - file.close(); - - if (result != eeprom_size) { - QMessageBox::critical(this, tr("Error"), - tr("Error reading file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - - return false; - } - - if (!LoadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index)) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid binary backup File %1") - .arg(fileName)); - return false; - } - - ui->modelsList->refreshList(); - - return true; -} +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mdichild.h" +#include "ui_mdichild.h" +#include "xmlinterface.h" +#include "hexinterface.h" +#include "mainwindow.h" +#include "modeledit/modeledit.h" +#include "generaledit.h" +#include "avroutputdialog.h" +#include "burnconfigdialog.h" +#include "printdialog.h" +#include "burndialog.h" +#include "helpers.h" +#include "appdata.h" +#include "wizarddialog.h" +#include "taranisnotfound.h" +#include + +#if defined WIN32 || !defined __GNUC__ +#include +#define sleep(x) Sleep(x*1000) +#else +#include +#endif + +MdiChild::MdiChild(): + QWidget(), + ui(new Ui::mdiChild), + isUntitled(true), + fileChanged(false) +{ + ui->setupUi(this); + + this->setWindowIcon(CompanionIcon("open.png")); + ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png")); + setAttribute(Qt::WA_DeleteOnClose); + + eepromInterfaceChanged(); + + if(!(this->isMaximized() || this->isMinimized())) { + adjustSize(); + } +} + +void MdiChild::qSleep(int ms) +{ + if (ms<0) + return; + +#if defined WIN32 || !defined __GNUC__ + Sleep(uint(ms)); +#else + struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; + nanosleep(&ts, NULL); +#endif +} + +void MdiChild::eepromInterfaceChanged() +{ + ui->modelsList->refreshList(); + ui->SimulateTxButton->setEnabled(GetEepromInterface()->getCapability(Simulation)); + updateTitle(); +} + +void MdiChild::cut() +{ + ui->modelsList->cut(); +} + +void MdiChild::copy() +{ + ui->modelsList->copy(); +} + + +void MdiChild::paste() +{ + ui->modelsList->paste(); +} + +bool MdiChild::hasPasteData() +{ + return ui->modelsList->hasPasteData(); +} + +bool MdiChild::hasSelection() +{ + return ui->modelsList->hasSelection(); +} + +void MdiChild::updateTitle() +{ + QString title = userFriendlyCurrentFile() + "[*]"+" ("+GetEepromInterface()->getName()+QString(")"); + if (GetEepromInterface()->getBoard() != BOARD_SKY9X) + title += QString(" - %1 ").arg(EEPromAvail) + tr("free bytes"); + setWindowTitle(title); +} + +void MdiChild::setModified() +{ + ui->modelsList->refreshList(); + fileChanged = true; + updateTitle(); + documentWasModified(); +} + +void MdiChild::on_SimulateTxButton_clicked() +{ + startSimulation(this, radioData, -1); +} + +void MdiChild::checkAndInitModel( int row ) +{ + ModelData &model = radioData.models[row - 1]; + if (model.isempty()) { + model.setDefaultValues(row - 1, radioData.generalSettings); + setModified(); + } +} + +void MdiChild::generalEdit() +{ + GeneralEdit *t = new GeneralEdit(radioData, this); + connect(t, SIGNAL(modelValuesChanged()), this, SLOT(setModified())); + t->show(); +} + +void MdiChild::modelEdit() +{ + int row = ui->modelsList->currentRow(); + + if (row == 0){ + generalEdit(); + } + else { + QApplication::setOverrideCursor(Qt::WaitCursor); + checkAndInitModel( row ); + ModelData &model = radioData.models[row - 1]; + ModelEdit *t = new ModelEdit(radioData, (row - 1), false, this); + t->setWindowTitle(tr("Editing model %1: ").arg(row) + model.name); + connect(t, SIGNAL(modified()), this, SLOT(setModified())); + t->show(); + QApplication::restoreOverrideCursor(); + } +} + +void MdiChild::wizardEdit() +{ +return modelEdit(); // TODO FOR BERTRAND- REMOVE THIS LINE TO TURN THE WIZARD BACK ON + int row = ui->modelsList->currentRow(); + if (row > 0) { + checkAndInitModel(row); + WizardDialog * wizard = new WizardDialog(radioData.generalSettings, row, this); + wizard->exec(); + if (wizard->mix.complete /*TODO rather test the exec() result?*/) { + radioData.models[row - 1] = wizard->mix; + setModified(); + } + } +} + +void MdiChild::openEditWindow() +{ + int row = ui->modelsList->currentRow(); + if (row == 0){ + generalEdit(); + } + else{ + ModelData &model = radioData.models[row - 1]; + if (model.isempty()) { + wizardEdit(); + } + else { + modelEdit(); + } + } +} + +void MdiChild::newFile() +{ + static int sequenceNumber = 1; + + isUntitled = true; + curFile = QString("document%1.eepe").arg(sequenceNumber++); + updateTitle(); +} + +bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile) +{ + QFile file(fileName); + + if (!file.exists()) { + QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); + return false; + } + + int fileType = getFileType(fileName); + + if (fileType==FILE_TYPE_XML) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } + QTextStream inputStream(&file); + XmlInterface(inputStream).load(radioData); + } + else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } + + QDomDocument doc(ER9X_EEPROM_FILE_TYPE); + bool xmlOK = doc.setContent(&file); + if(xmlOK) { + if (LoadEepromXml(radioData, doc)){ + ui->modelsList->refreshList(); + if(resetCurrentFile) setCurrentFile(fileName); + return true; + } + } + file.reset(); + + QTextStream inputStream(&file); + + if (fileType==FILE_TYPE_EEPE) { // read EEPE file header + QString hline = inputStream.readLine(); + if (hline!=EEPE_EEPROM_FILE_HEADER) { + file.close(); + return false; + } + } + + uint8_t eeprom[EESIZE_RLC_MAX]; + int eeprom_size = HexInterface(inputStream).load(eeprom, EESIZE_RLC_MAX); + if (!eeprom_size) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid EEPROM File %1") + .arg(fileName)); + file.close(); + return false; + } + + file.close(); + + if (!LoadEeprom(radioData, eeprom, eeprom_size)) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid EEPROM File %1") + .arg(fileName)); + return false; + } + + ui->modelsList->refreshList(); + if(resetCurrentFile) setCurrentFile(fileName); + + return true; + } + else if (fileType==FILE_TYPE_BIN) { //read binary + int eeprom_size = file.size(); + + if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } + uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); + memset(eeprom, 0, eeprom_size); + long result = file.read((char*)eeprom, eeprom_size); + file.close(); + + if (result != eeprom_size) { + QMessageBox::critical(this, tr("Error"), + tr("Error reading file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + + return false; + } + + if (!LoadEeprom(radioData, eeprom, eeprom_size) && !LoadBackup(radioData, eeprom, eeprom_size, 0)) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid binary EEPROM File %1") + .arg(fileName)); + return false; + } + + ui->modelsList->refreshList(); + if(resetCurrentFile) setCurrentFile(fileName); + + free(eeprom); + return true; + } + + return false; +} + +bool MdiChild::save() +{ + if (isUntitled) { + return saveAs(true); + } + else { + return saveFile(curFile); + } +} + +bool MdiChild::saveAs(bool isNew) +{ + QString fileName; + if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { + curFile.replace(".eepe", ".bin"); + QFileInfo fi(curFile); +#ifdef __APPLE__ + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); +#else + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(BIN_FILES_FILTER)); +#endif + } + else { + QFileInfo fi(curFile); +#ifdef __APPLE__ + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); +#else + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(EEPROM_FILES_FILTER)); +#endif + } + if (fileName.isEmpty()) + return false; + if (fileName.contains("rev4a")) { + g.rev4aSupport( true ); + } + if (fileName.contains("norev4a")) { + g.rev4aSupport( false ); + } + g.eepromDir( QFileInfo(fileName).dir().absolutePath() ); + if (isNew) + return saveFile(fileName); + else + return saveFile(fileName,true); +} + +bool MdiChild::saveFile(const QString &fileName, bool setCurrent) +{ + QString myFile; + myFile = fileName; + if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { + myFile.replace(".eepe", ".bin"); + } + QFile file(myFile); + + int fileType = getFileType(myFile); + + uint8_t *eeprom = (uint8_t*)malloc(GetEepromInterface()->getEEpromSize()); + int eeprom_size = 0; + + if (fileType != FILE_TYPE_XML) { + eeprom_size = GetEepromInterface()->save(eeprom, radioData, GetCurrentFirmwareVariant(), 0/*last version*/); + if (!eeprom_size) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + return false; + } + } + + if (!file.open(fileType == FILE_TYPE_BIN ? QIODevice::WriteOnly : (QIODevice::WriteOnly | QIODevice::Text))) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + return false; + } + + QTextStream outputStream(&file); + + if (fileType==FILE_TYPE_XML) { + if (!XmlInterface(outputStream).save(radioData)) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + file.close(); + return false; + } + } + else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { // write hex + if (fileType==FILE_TYPE_EEPE) + outputStream << EEPE_EEPROM_FILE_HEADER << "\n"; + + if (!HexInterface(outputStream).save(eeprom, eeprom_size)) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + file.close(); + return false; + } + } + else if (fileType==FILE_TYPE_BIN) // write binary + { + long result = file.write((char*)eeprom, eeprom_size); + if(result!=eeprom_size) { + QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg(file.errorString())); + return false; + } + } + else { + QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg("Unknown format")); + return false; + } + + free(eeprom); // TODO free in all cases ... + file.close(); + if(setCurrent) setCurrentFile(myFile); + + return true; +} + +QString MdiChild::userFriendlyCurrentFile() +{ + return strippedName(curFile); +} + +void MdiChild::closeEvent(QCloseEvent *event) +{ + if (maybeSave()) { + event->accept(); + } + else { + event->ignore(); + } +} + +void MdiChild::documentWasModified() +{ + setWindowModified(fileChanged); +} + +bool MdiChild::maybeSave() +{ + if (fileChanged) { + QMessageBox::StandardButton ret; + ret = QMessageBox::warning(this, tr("Companion"), + tr("%1 has been modified.\n" + "Do you want to save your changes?").arg(userFriendlyCurrentFile()), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + + if (ret == QMessageBox::Save) + return save(); + else if (ret == QMessageBox::Cancel) + return false; + } + return true; +} + +void MdiChild::setCurrentFile(const QString &fileName) +{ + curFile = QFileInfo(fileName).canonicalFilePath(); + isUntitled = false; + fileChanged = false; + setWindowModified(false); + updateTitle(); + int MaxRecentFiles = g.historySize(); + QStringList files = g.recentFiles(); + files.removeAll(fileName); + files.prepend(fileName); + while (files.size() > MaxRecentFiles) + files.removeLast(); + + g.recentFiles( files ); +} + +QString MdiChild::strippedName(const QString &fullFileName) +{ + return QFileInfo(fullFileName).fileName(); +} + +void MdiChild::writeEeprom() // write to Tx +{ + bool backupEnable=g.enableBackup(); + QString backupPath=g.backupDir(); + if (!backupPath.isEmpty()) { + if (!QDir(backupPath).exists()) { + if (backupEnable) { + QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist")); + } + backupEnable=false; + } + } + else { + backupEnable=false; + } + QString stickCal=g.profile[g.id()].stickPotCalib(); + burnConfigDialog bcd; + QString tempDir = QDir::tempPath(); + QString tempFile = tempDir + "/temp.bin"; + saveFile(tempFile, false); + if(!QFileInfo(tempFile).exists()) { + QMessageBox::critical(this,tr("Error"), tr("Cannot write temporary file!")); + return; + } + EEPROMInterface *eepromInterface = GetEepromInterface(); + bool backup=false; + burnDialog *cd = new burnDialog(this, 1, &tempFile, &backup,strippedName(curFile)); + cd->exec(); + if (!tempFile.isEmpty()) { + if (backup) { + if (backupEnable) { + QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss")+".bin"; + if (IS_TARANIS(eepromInterface->getBoard())) { + QString path=((MainWindow *)this->parent())->FindTaranisPath(); + if (path.isEmpty()) { + taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); + tnfd->exec(); + return; + } + else { + QStringList str; + str << path << backupFile; + avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Backup EEPROM From Tx")); //, AVR_DIALOG_KEEP_OPEN); + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + else { + QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); + avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx")); + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + int oldrev=((MainWindow *)this->parent())->getEpromVersion(tempFile); + QString tempFlash=tempDir + "/flash.bin"; + QStringList str = ((MainWindow *)this->parent())->GetReceiveFlashCommand(tempFlash); + avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, "Read Flash From Tx"); + ad->setWindowIcon(CompanionIcon("read_flash.png")); + ad->exec(); + delete ad; + sleep(1); + QString restoreFile = tempDir + "/compat.bin"; + if (!((MainWindow *)this->parent())->convertEEPROM(tempFile, restoreFile, tempFlash)) { + int ret = QMessageBox::question(this, tr("Error"), tr("Cannot check eeprom compatibility! Continue anyway?"), QMessageBox::Yes | QMessageBox::No); + if (ret == QMessageBox::No) + return; + } + else { + int rev=((MainWindow *)this->parent())->getEpromVersion(restoreFile); + if ((rev/100)!=(oldrev/100)) { + QMessageBox::warning(this,tr("Warning"), tr("Firmware in radio is of a different family of eeprom written, check file and preferences!")); + } + if (revgetBoard())) { + QString path=((MainWindow *)this->parent())->FindTaranisPath(); + if (path.isEmpty()) { + taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); + tnfd->exec(); + return; + } + else { + QFile::copy(path,backupFile); + } + } + else { + QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); + avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx")); + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + } + + if (IS_TARANIS(eepromInterface->getBoard())) { + QString path=((MainWindow *)this->parent())->FindTaranisPath(); + if (path.isEmpty()) { + taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); + tnfd->exec(); + return; + } + else { + QStringList str; + str << tempFile << path; + avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Write EEPROM To Tx"), AVR_DIALOG_SHOW_DONE); //, AVR_DIALOG_KEEP_OPEN); + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + else { + QStringList str = ((MainWindow *)this->parent())->GetSendEEpromCommand(tempFile); + avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, "Write EEPROM To Tx", AVR_DIALOG_SHOW_DONE); + ad->setWindowIcon(CompanionIcon("write_eeprom.png")); + ad->exec(); + delete ad; + } + } +} + +void MdiChild::simulate() +{ + if (ui->modelsList->currentRow() >= 1) { + startSimulation(this, radioData, ui->modelsList->currentRow()-1); + } +} + +void MdiChild::print(int model, QString filename) +{ + if (model>=0 && !filename.isEmpty()) { + + printDialog *pd = new printDialog(this, &radioData.generalSettings, &radioData.models[model], filename); + pd->show(); + } + else { + if(ui->modelsList->currentRow()<1) return; + printDialog *pd = new printDialog(this, &radioData.generalSettings, &radioData.models[ui->modelsList->currentRow()-1]); + pd->show(); + } +} + +void MdiChild::viableModelSelected(bool viable) +{ + emit copyAvailable(viable); +} + +void MdiChild::setEEpromAvail(int eavail) +{ + EEPromAvail=eavail; +} + +bool MdiChild::loadBackup() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(),tr(EEPROM_FILES_FILTER)); + if (fileName.isEmpty()) + return false; + QFile file(fileName); + + if (!file.exists()) { + QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); + return false; + } + if(ui->modelsList->currentRow()<1) return false; + int index=ui->modelsList->currentRow()-1; + + int eeprom_size = file.size(); + if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } + QByteArray eeprom(eeprom_size, 0); + long result = file.read((char*)eeprom.data(), eeprom_size); + file.close(); + + if (result != eeprom_size) { + QMessageBox::critical(this, tr("Error"), + tr("Error reading file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + + return false; + } + + if (!LoadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index)) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid binary backup File %1") + .arg(fileName)); + return false; + } + + ui->modelsList->refreshList(); + + return true; +} diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h index 7a18491eb..1ff1730cc 100644 --- a/companion/src/mdichild.h +++ b/companion/src/mdichild.h @@ -89,8 +89,12 @@ private slots: void qSleep(int ms); public slots: - void OpenEditWindow(bool wizard); - + void checkAndInitModel(int row); + void generalEdit(); + void modelEdit(); + void wizardEdit(); + void openEditWindow(); + void cut(); void copy(); void paste(); diff --git a/companion/src/modelconfigdialog.cpp b/companion/src/modelconfigdialog.cpp deleted file mode 100644 index 4badaa906..000000000 --- a/companion/src/modelconfigdialog.cpp +++ /dev/null @@ -1,937 +0,0 @@ -#include "modelconfigdialog.h" -#include "ui_modelconfigdialog.h" -#include "helpers.h" -#include "eeprominterface.h" -#include -#include "helpers.h" - -#define NUM_CH 10 - -modelConfigDialog::modelConfigDialog(RadioData &radioData, uint64_t * result, QWidget *parent) : - QDialog(parent), - ui(new Ui::modelConfigDialog), - radioData(radioData), - result(result), - generalSettings(radioData.generalSettings) -{ - ui->setupUi(this); - this->setWindowIcon(CompanionIcon("wizard.png")); - rxLock=false; - ruddercolor << "#ffd100" << "#ffff00"; - throttlecolor << "#e40000"; - aileroncolor << "#0000ff" << "#00ffff"; - elevatorcolor << "#827f00" << "#ffff00"; - flapscolor << "#007f00" << "#00ff00"; - airbrakecolor << "#9b0099" << "#ff00fc"; - helicolor << "#00ff00" << "#0000ff" << "#00ffff" << "#ffff00" << "#e40000" << "#ffa400"; - connect(ui->ailType_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(ConfigChanged())); - connect(ui->flapsType_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(ConfigChanged())); - connect(ui->spoilersType_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(ConfigChanged())); - connect(ui->swashType_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(ConfigChanged())); - connect(ui->engine_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(ConfigChanged())); - connect(ui->rudder_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(ConfigChanged())); - connect(ui->tailType_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(tailConfigChanged())); - connect(ui->gyro_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(tailConfigChanged())); - connect(ui->chStyle_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(ConfigChanged())); - connect(ui->asail2_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(rxUpdate())); - connect(ui->asele2_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(rxUpdate())); - connect(ui->asrud2_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(rxUpdate())); - connect(ui->asfla1_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(rxUpdate())); - connect(ui->asfla2_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(rxUpdate())); - connect(ui->asspo1_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(rxUpdate())); - connect(ui->asspo2_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(rxUpdate())); - connect(ui->as_CB,SIGNAL(clicked()),this,SLOT(rxUpdate())); - formSetup(); - QTimer::singleShot(0, this, SLOT(shrink())); - connect(ui->buttonBox,SIGNAL(clicked(QAbstractButton*)), this, SLOT(doAction(QAbstractButton*))); -} - -modelConfigDialog::~modelConfigDialog() -{ - delete ui; -} - -void modelConfigDialog::rxUpdate() -{ - QLabel * channel[] = {ui->CH_1,ui->CH_2,ui->CH_3,ui->CH_4,ui->CH_5,ui->CH_6,ui->CH_7,ui->CH_8,ui->CH_9,ui->CH_10,NULL}; - for (int i=0; channel[i]; i++) { - channel[i]->setStyleSheet(""); - } - for (int i=0; ias_CB->isChecked()) { - if ((ModelType==0) || (ModelType==2)) { - index=ui->asail2_CB->currentIndex(); - if (ailerons>1 && index>0) { - rx[index-1]=true; - } - index=ui->asele2_CB->currentIndex(); - if (elevators>1 && index>0) { - rx[index-1]=true; - } - } - if (ModelType==3) { - index=ui->asrud2_CB->currentIndex(); - if (rudders>1 && index>0) { - rx[index-1]=true; - } - } - index=ui->asfla1_CB->currentIndex(); - if (flaps>0 && index>0) { - rx[index-1]=true; - } - index=ui->asfla2_CB->currentIndex(); - if (flaps>1 && index>0) { - rx[index-1]=true; - } - if ((ModelType==0) || (ModelType==2)) { - index=ui->asspo1_CB->currentIndex(); - if (spoilers>0 && index>0) { - rx[index-1]=true; - } - index=ui->asspo2_CB->currentIndex(); - if (spoilers>1 && index>0) { - rx[index-1]=true; - } - } - } - #define ICC(x) icc[(x)-1] - uint8_t icc[4] = {0}; - for(uint8_t i=1; i<=4; i++) //generate inverse array - for(uint8_t j=1; j<=4; j++) if(CC(i)==j) icc[j-1]=i; - uint8_t stick; - switch (ModelType) { - case 0: //AIRPLANE - stick=ICC(STK_THR); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(throttlecolor.at(0))); - rx[stick-1]=true; - stick=ICC(STK_RUD); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(ruddercolor.at(0))); - rx[stick-1]=true; - if (ailerons>0) { - stick=ICC(STK_AIL); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(aileroncolor.at(0))); - rx[stick-1]=true; - } - stick=ICC(STK_ELE); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(elevatorcolor.at(0))); - rx[stick-1]=true; - if (ailerons>1) { - index=ui->asail2_CB->currentIndex(); - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(aileroncolor.at(1))); - rx[j]=true; - break; - } - } - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(aileroncolor.at(1))); - } - } - if (elevators>1) { - index=ui->asele2_CB->currentIndex(); - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(elevatorcolor.at(1))); - rx[j]=true; - break; - } - } - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(elevatorcolor.at(1))); - } - } - for (uint8_t i=0; i< flaps; i++) { - if (i==0) { - index=ui->asfla1_CB->currentIndex(); - } else { - index=ui->asfla2_CB->currentIndex(); - } - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(flapscolor.at(i))); - rx[j]=true; - break; - } - }; - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(flapscolor.at(i))); - } - } - break; - case 1: //HELI - switch (ui->chStyle_CB->currentIndex()) { - case 0: - channel[0]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(0))); //ELE CYC1 - channel[1]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(1))); //AIL CYC2 - channel[2]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(2))); //PITCH CYC3 - channel[3]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(3))); //RUD - channel[4]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(4))); //THR - if (ui->gyro_CB->currentIndex()>0) { - channel[5]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(5))); //GYRO - } - break; - case 1: - channel[0]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(1))); //AIL CYC2 - channel[1]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(0))); //ELE CYC1 - channel[2]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(4))); //THR - channel[3]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(3))); //RUD - if (ui->gyro_CB->currentIndex()>0) { - channel[4]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(5))); //GYRO - } - channel[5]->setStyleSheet(QString("background-color: %1;").arg(helicolor.at(2))); //PIT CYC3 - break; - } - break; - case 2: //GLIDER - if (throttle>0) { - stick=ICC(STK_THR); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(throttlecolor.at(0))); - rx[stick-1]=true; - } - if (ailerons>0) { - stick=ICC(STK_AIL); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(aileroncolor.at(0))); - rx[stick-1]=true; - } - stick=ICC(STK_ELE); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(elevatorcolor.at(0))); - rx[stick-1]=true; - stick=ICC(STK_RUD); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(ruddercolor.at(0))); - rx[stick-1]=true; - if (ailerons>1) { - index=ui->asail2_CB->currentIndex(); - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(aileroncolor.at(1))); - rx[j]=true; - break; - } - } - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(aileroncolor.at(1))); - } - } - if (elevators>1) { - index=ui->asele2_CB->currentIndex(); - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(elevatorcolor.at(1))); - rx[j]=true; - break; - } - } - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(elevatorcolor.at(1))); - } - } - for (uint8_t i=0; i< flaps; i++) { - if (i==0) { - index=ui->asfla1_CB->currentIndex(); - } else { - index=ui->asfla2_CB->currentIndex(); - } - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(flapscolor.at(i))); - rx[j]=true; - break; - } - }; - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(flapscolor.at(i))); - } - } - for (uint8_t i=0; i< spoilers; i++) { - if (i==0) { - index=ui->asspo1_CB->currentIndex(); - } else { - index=ui->asspo2_CB->currentIndex(); - } - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(airbrakecolor.at(i))); - rx[j]=true; - break; - } - }; - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(airbrakecolor.at(i))); - } - } - break; - case 3: //DELTA WING - if (throttle>0) { - stick=ICC(STK_THR); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(throttlecolor.at(0))); - rx[stick-1]=true; - } - stick=ICC(STK_AIL); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(aileroncolor.at(0))); - rx[stick-1]=true; - stick=ICC(STK_ELE); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(elevatorcolor.at(0))); - rx[stick-1]=true; - if (rudders>0) { - stick=ICC(STK_RUD); - channel[stick-1]->setStyleSheet(QString("background-color: %1;").arg(ruddercolor.at(0))); - rx[stick-1]=true; - } - if (rudders>1) { - index=ui->asrud2_CB->currentIndex(); - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(ruddercolor.at(1))); - rx[j]=true; - break; - } - } - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(ruddercolor.at(1))); - } - } - for (uint8_t i=0; i< flaps; i++) { - if (i==0) { - index=ui->asfla1_CB->currentIndex(); - } else { - index=ui->asfla2_CB->currentIndex(); - } - if (!ui->as_CB->isChecked()) - index=0; - if (index==0) { - for (int j=0; jsetStyleSheet(QString("background-color: %1;").arg(flapscolor.at(i))); - rx[j]=true; - break; - } - }; - } else { - channel[index-1]->setStyleSheet(QString("background-color: %1;").arg(flapscolor.at(i))); - } - } - break; - } - asUpdate(); -} - -void modelConfigDialog::tailConfigChanged() -{ - if (tailLock) - return; - tailLock=true; - QImage image; - int index; - int head; - switch (ModelType) { - case 0: - index=ui->tailType_CB->currentIndex(); - switch (index) { - case 0: - rudders=1; - elevators=1; - image.load(":/images/mcw/at1e1r.png"); - break; - case 1: - rudders=1; - elevators=1; - image.load(":/images/mcw/atailv.png"); - break; - case 2: - rudders=1; - elevators=2; - image.load(":/images/mcw/at2e1r.png"); - break; - } - break; - case 1: - elevators=1; - rudders=1; - head=ui->swashType_CB->currentIndex(); - if (head==4) { - index=ui->gyro_CB->currentIndex(); - switch (index) { - case 0: - image.load(":/images/mcw/htailfblng.png"); - break; - case 1: - image.load(":/images/mcw/htailfblg.png"); - break; - case 2: - image.load(":/images/mcw/htailfblg.png"); - break; - } - } else { - index=ui->gyro_CB->currentIndex(); - switch (index) { - case 0: - image.load(":/images/mcw/htailng.png"); - break; - case 1: - image.load(":/images/mcw/htailg.png"); - break; - case 2: - image.load(":/images/mcw/htailg.png"); - break; - } - } - break; - case 2: - index=ui->tailType_CB->currentIndex(); - switch (index) { - case 0: - elevators=1; - rudders=1; - image.load(":/images/mcw/gt1e1r.png"); - break; - case 1: - elevators=1; - rudders=1; - image.load(":/images/mcw/gtailv.png"); - break; - case 2: - elevators=2; - rudders=1; - image.load(":/images/mcw/gt2e1r.png"); - break; - } - break; - } - ui->tailImg->setPixmap(QPixmap::fromImage(image)); - tailLock=false; - rxUpdate(); -} - -void modelConfigDialog::ConfigChanged() -{ - if (wingsLock) - return; - wingsLock=true; - QImage image; - QString imgname=":/images/mcw/"; - QStringList wimages; - int index; - switch (ModelType) { - case 0: - if (ui->ailType_CB->currentIndex()==0) { - ui->flapsType_CB->setCurrentIndex(0); - ui->flapsType_CB->setDisabled(true); - } else { - ui->flapsType_CB->setEnabled(true); - } - ailerons=ui->ailType_CB->currentIndex(); - flaps=ui->flapsType_CB->currentIndex(); - throttle=1; - imgname.append(QString("aw%1a%2f.png").arg(ui->ailType_CB->currentIndex()).arg(ui->flapsType_CB->currentIndex())); - image.load(imgname); - ui->wingImg->setPixmap(QPixmap::fromImage(image)); - break; - case 1: - wimages.clear(); - wimages << "h90.png" << "h120.png" << "h120x.png" << "h140.png" << "hfbl.png"; - index=ui->swashType_CB->currentIndex(); - ui->gyroType_Label->show(); - ui->gyro_CB->show(); - ailerons=1; - throttle=1; - imgname.append(wimages.at(index)); - image.load(imgname); - ui->wingImg->setPixmap(QPixmap::fromImage(image)); - tailConfigChanged(); - break; - case 2: - if (ui->ailType_CB->currentIndex()==0) { - ui->flapsType_CB->setCurrentIndex(0); - ui->flapsType_CB->setDisabled(true); - } else { - ui->flapsType_CB->setEnabled(true); - } - if (ui->ailType_CB->currentIndex()==0) { - ui->spoilersType_CB->setCurrentIndex(0); - ui->spoilersType_CB->setDisabled(true); - } else { - ui->spoilersType_CB->setEnabled(true); - } - ailerons=ui->ailType_CB->currentIndex(); - flaps=ui->flapsType_CB->currentIndex(); - spoilers=ui->spoilersType_CB->currentIndex(); - throttle=ui->engine_CB->currentIndex(); - imgname.append(QString("gw%1t%2a%3f%4s.png").arg(ui->engine_CB->currentIndex()).arg(ui->ailType_CB->currentIndex()).arg(ui->flapsType_CB->currentIndex()).arg(ui->spoilersType_CB->currentIndex())); - image.load(imgname); - ui->wingImg->setPixmap(QPixmap::fromImage(image)); - break; - case 3: - ailerons=ui->ailType_CB->currentIndex(); - flaps=ui->flapsType_CB->currentIndex(); - rudders=ui->rudder_CB->currentIndex(); - throttle=ui->engine_CB->currentIndex(); - imgname.append(QString("dt%1t2e%2f%3r.png").arg(ui->engine_CB->currentIndex()).arg(ui->flapsType_CB->currentIndex()).arg(ui->rudder_CB->currentIndex())); - image.load(imgname); - ui->wingImg->setPixmap(QPixmap::fromImage(image)); - imgname.clear(); - imgname.append(QString(":/images/mcw/db%1t2e%2f%3r.png").arg(ui->engine_CB->currentIndex()).arg(ui->flapsType_CB->currentIndex()).arg(ui->rudder_CB->currentIndex())); - image.load(imgname); - ui->tailImg->setPixmap(QPixmap::fromImage(image)); - break; - default: - ui->wingImg->clear(); - break; - } - wingsLock=false; - rxUpdate(); -} - -void modelConfigDialog::on_planeButton_clicked() -{ - ui->planeButton->setStyleSheet("background-color: #007f00; color: white;"); - ui->heliButton->setStyleSheet(""); - ui->gliderButton->setStyleSheet(""); - ui->deltaButton->setStyleSheet(""); - ModelType=0; - wingsLock=true; - tailLock=true; - ui->engine_Label->hide(); - ui->engine_CB->setCurrentIndex(0); - ui->engine_CB->hide(); - ui->rudder_Label->hide(); - ui->rudder_CB->setCurrentIndex(0); - ui->rudder_CB->hide(); - ui->spoilersLabel->hide(); - ui->spoilersType_CB->setCurrentIndex(0); - ui->spoilersType_CB->hide(); - ui->spLabel->hide(); - ui->sp_Label->hide(); - ui->swashType_CB->setCurrentIndex(0); - ui->swashType_CB->hide(); - ui->gyroType_Label->hide(); - ui->gyro_CB->setCurrentIndex(0); - ui->gyro_CB->hide(); - ui->chStyle_CB->hide(); - ui->chStyle_CB->setCurrentIndex(0); - ui->chassign_Label->hide(); - ui->wingLabel->show(); - ui->ailType_Label->show(); - ui->ailType_CB->show(); - ui->ailType_CB->setCurrentIndex(0); - ui->tailLabel->show(); - ui->tailType_Label->show(); - ui->tailType_CB->show(); - ui->tailType_CB->setCurrentIndex(0); - ui->flapsType_Label->show(); - ui->flapsType_CB->show(); - ui->flapsType_CB->setCurrentIndex(0); - ui->flapsType_CB->setDisabled(true); - ui->planeButton->setDisabled(true); - ui->heliButton->setEnabled(true); - ui->gliderButton->setEnabled(true); - ui->deltaButton->setEnabled(true); - wingsLock=false; - tailLock=false; - resetControls(); - ConfigChanged(); - tailConfigChanged(); -} - -void modelConfigDialog::on_heliButton_clicked() -{ - ui->planeButton->setStyleSheet(""); - ui->heliButton->setStyleSheet("background-color: #007f00; color: white;"); - ui->gliderButton->setStyleSheet(""); - ui->deltaButton->setStyleSheet(""); - ModelType=1; - wingsLock=true; - tailLock=true; - ui->engine_Label->hide(); - ui->engine_CB->setCurrentIndex(0); - ui->engine_CB->hide(); - ui->rudder_Label->hide(); - ui->rudder_CB->setCurrentIndex(0); - ui->rudder_CB->hide(); - ui->wingLabel->hide(); - ui->ailType_Label->hide(); - ui->ailType_CB->hide(); - ui->ailType_CB->setCurrentIndex(0); - ui->tailType_Label->hide(); - ui->tailType_CB->hide(); - ui->tailType_CB->setCurrentIndex(0); - ui->flapsType_Label->hide(); - ui->flapsType_CB->hide(); - ui->flapsType_CB->setCurrentIndex(0); - ui->flapsType_CB->setDisabled(true); - ui->spoilersLabel->hide(); - ui->spoilersType_CB->setCurrentIndex(0); - ui->spoilersType_CB->hide(); - ui->tailLabel->show(); - ui->spLabel->show(); - ui->sp_Label->show(); - ui->swashType_CB->setCurrentIndex(0); - ui->swashType_CB->show(); - ui->gyroType_Label->show(); - ui->gyro_CB->setCurrentIndex(0); - ui->gyro_CB->show(); - ui->chStyle_CB->show(); - ui->chStyle_CB->setCurrentIndex(0); - ui->chassign_Label->show(); - ui->planeButton->setEnabled(true); - ui->heliButton->setDisabled(true); - ui->gliderButton->setEnabled(true); - ui->deltaButton->setEnabled(true); - wingsLock=false; - tailLock=false; - resetControls(); - ConfigChanged(); - tailConfigChanged(); -} - -void modelConfigDialog::on_gliderButton_clicked() -{ - ui->planeButton->setStyleSheet(""); - ui->heliButton->setStyleSheet(""); - ui->gliderButton->setStyleSheet("background-color: #007f00; color: white;"); - ui->deltaButton->setStyleSheet(""); - ModelType=2; - wingsLock=true; - tailLock=true; - ui->rudder_Label->hide(); - ui->rudder_CB->setCurrentIndex(0); - ui->rudder_CB->hide(); - ui->spLabel->hide(); - ui->sp_Label->hide(); - ui->swashType_CB->setCurrentIndex(0); - ui->swashType_CB->hide(); - ui->gyroType_Label->hide(); - ui->gyro_CB->setCurrentIndex(0); - ui->gyro_CB->hide(); - ui->chStyle_CB->hide(); - ui->chStyle_CB->setCurrentIndex(0); - ui->chassign_Label->hide(); - ui->wingLabel->show(); - ui->engine_Label->show(); - ui->engine_CB->setCurrentIndex(0); - ui->engine_CB->show(); - ui->ailType_Label->show(); - ui->ailType_CB->show(); - ui->ailType_CB->setCurrentIndex(0); - ui->tailLabel->show(); - ui->tailType_Label->show(); - ui->tailType_CB->show(); - ui->tailType_CB->setCurrentIndex(0); - ui->flapsType_Label->show(); - ui->flapsType_CB->show(); - ui->flapsType_CB->setCurrentIndex(0); - ui->flapsType_CB->setDisabled(true); - ui->spoilersLabel->show(); - ui->spoilersType_CB->setCurrentIndex(0); - ui->spoilersType_CB->setDisabled(true); - ui->spoilersType_CB->show(); - ui->planeButton->setEnabled(true); - ui->heliButton->setEnabled(true); - ui->gliderButton->setDisabled(true); - ui->deltaButton->setEnabled(true); - wingsLock=false; - tailLock=false; - resetControls(); - ConfigChanged(); - tailConfigChanged(); -} - -void modelConfigDialog::on_deltaButton_clicked() -{ - ui->planeButton->setStyleSheet(""); - ui->heliButton->setStyleSheet(""); - ui->gliderButton->setStyleSheet(""); - ui->deltaButton->setStyleSheet("background-color: #007f00; color: white;"); - ModelType=3; - wingsLock=true; - tailLock=true; - ui->spLabel->hide(); - ui->sp_Label->hide(); - ui->swashType_CB->setCurrentIndex(0); - ui->swashType_CB->hide(); - ui->gyroType_Label->hide(); - ui->gyro_CB->setCurrentIndex(0); - ui->gyro_CB->hide(); - ui->chStyle_CB->hide(); - ui->chStyle_CB->setCurrentIndex(0); - ui->chassign_Label->hide(); - ui->ailType_Label->hide(); - ui->ailType_CB->hide(); - ui->ailType_CB->setCurrentIndex(0); - ui->tailLabel->hide(); - ui->tailType_Label->hide(); - ui->tailType_CB->hide(); - ui->tailType_CB->setCurrentIndex(0); - ui->spoilersLabel->hide(); - ui->spoilersType_CB->setCurrentIndex(0); - ui->spoilersType_CB->hide(); - ui->engine_Label->show(); - ui->engine_CB->setCurrentIndex(0); - ui->engine_CB->show(); - ui->rudder_Label->show(); - ui->rudder_CB->setCurrentIndex(0); - ui->rudder_CB->show(); - ui->wingLabel->show(); - ui->flapsType_Label->show(); - ui->flapsType_CB->show(); - ui->flapsType_CB->setCurrentIndex(0); - ui->flapsType_CB->setEnabled(true); - ui->planeButton->setEnabled(true); - ui->heliButton->setEnabled(true); - ui->gliderButton->setEnabled(true); - ui->deltaButton->setDisabled(true); - wingsLock=false; - tailLock=false; - resetControls(); - ConfigChanged(); -} - - -void modelConfigDialog::formSetup() -{ - on_planeButton_clicked(); -} - -void modelConfigDialog::resetControls() { - ailerons=0; - rudders=0; - throttle=0; - elevators=0; - spoilers=0; - flaps=0; -} - - -void modelConfigDialog::shrink() -{ - resize(0,0); -} - -void modelConfigDialog::doAction(QAbstractButton *button) -{ - if ( ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole) { - int res = QMessageBox::question(this,tr("Apply configuration ?"),tr("Apply configuration deleting existing model ?"),QMessageBox::Yes | QMessageBox::No); - if(res==QMessageBox::Yes) { - uint64_t tmp=0; - tmp=ModelType; - tmp <<=2; - tmp |= ui->engine_CB->currentIndex(); - tmp <<=2; - tmp |= ui->ailType_CB->currentIndex(); - tmp <<=2; - tmp |= ui->flapsType_CB->currentIndex(); - tmp <<=2; - tmp |= ui->spoilersType_CB->currentIndex(); - tmp <<=2; - tmp |= ui->rudder_CB->currentIndex(); - tmp <<=3; - tmp |= ui->swashType_CB->currentIndex(); - tmp <<=2; - tmp |= ui->tailType_CB->currentIndex(); - tmp <<=2; - tmp |= ui->gyro_CB->currentIndex(); - tmp <<=2; - tmp |= ui->chStyle_CB->currentIndex(); - if (ui->as_CB->isChecked()) { - tmp <<=4; - tmp |= ui->asail2_CB->currentIndex(); - tmp <<=4; - tmp |= ui->asele2_CB->currentIndex(); - tmp <<=4; - tmp |= ui->asrud2_CB->currentIndex(); - tmp <<=4; - tmp |= ui->asfla1_CB->currentIndex(); - tmp <<=4; - tmp |= ui->asfla2_CB->currentIndex(); - tmp <<=4; - tmp |= ui->asspo1_CB->currentIndex(); - tmp <<=4; - tmp |= ui->asspo2_CB->currentIndex(); - } else { - tmp <<=28; - } - *result=tmp; - } - } - this->close(); -} - -void modelConfigDialog::asUpdate() -{ - if (rxLock==true) - return; - rxLock=true; - QVariant v(1 | 32); - int i; - //disable default channels used - for (i=0; i<4; i++ ) { - if (rx[i]) { - ui->asail2_CB->setItemData(i+1,false, Qt::UserRole - 1); - ui->asele2_CB->setItemData(i+1,false, Qt::UserRole - 1); - ui->asrud2_CB->setItemData(i+1,false, Qt::UserRole - 1); - ui->asfla1_CB->setItemData(i+1,false, Qt::UserRole - 1); - ui->asfla2_CB->setItemData(i+1,false, Qt::UserRole - 1); - ui->asspo1_CB->setItemData(i+1,false, Qt::UserRole - 1); - ui->asspo2_CB->setItemData(i+1,false, Qt::UserRole - 1); - } else { - ui->asail2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asele2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asrud2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asfla1_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asfla2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asspo1_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asspo2_CB->setItemData(i+1,v, Qt::UserRole-1); - } - } - for (i=4; iasail2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asele2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asrud2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asfla1_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asfla2_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asspo1_CB->setItemData(i+1,v, Qt::UserRole-1); - ui->asspo2_CB->setItemData(i+1,v, Qt::UserRole-1); - } - - i=ui->asail2_CB->currentIndex(); - if (i>0) { - ui->asele2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asrud2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo2_CB->setItemData(i,false, Qt::UserRole - 1); - } - i=ui->asrud2_CB->currentIndex(); - if (i>0) { - ui->asail2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asele2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo2_CB->setItemData(i,false, Qt::UserRole - 1); - } - i=ui->asele2_CB->currentIndex(); - if (i>0) { - ui->asail2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asrud2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo2_CB->setItemData(i,false, Qt::UserRole - 1); - } - i=ui->asfla1_CB->currentIndex(); - if (i>0) { - ui->asail2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asele2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asrud2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo2_CB->setItemData(i,false, Qt::UserRole - 1); - } - i=ui->asfla2_CB->currentIndex(); - if (i>0) { - ui->asail2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asele2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asrud2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo2_CB->setItemData(i,false, Qt::UserRole - 1); - } - i=ui->asspo1_CB->currentIndex(); - if (i>0) { - ui->asail2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asele2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asrud2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo2_CB->setItemData(i,false, Qt::UserRole - 1); - } - i=ui->asspo2_CB->currentIndex(); - if (i>0) { - ui->asail2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asele2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asrud2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla1_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asfla2_CB->setItemData(i,false, Qt::UserRole - 1); - ui->asspo1_CB->setItemData(i,false, Qt::UserRole - 1); - } - - if (ailerons>1 && ui->as_CB->isChecked()) { - ui->asail2_label->show(); - ui->asail2_CB->show(); - } else { - ui->asail2_label->hide(); - ui->asail2_CB->hide(); - } - if (elevators>1 && ui->as_CB->isChecked()) { - ui->asele2_label->show(); - ui->asele2_CB->show(); - } else { - ui->asele2_label->hide(); - ui->asele2_CB->hide(); - } - if (rudders>1 && ui->as_CB->isChecked()) { - ui->asrud2_label->show(); - ui->asrud2_CB->show(); - } else { - ui->asrud2_label->hide(); - ui->asrud2_CB->hide(); - } - if (flaps>0 && ui->as_CB->isChecked()) { - ui->asfla1_label->show(); - ui->asfla1_CB->show(); - } else { - ui->asfla1_label->hide(); - ui->asfla1_CB->hide(); - } - if (flaps>1 && ui->as_CB->isChecked()) { - ui->asfla2_label->show(); - ui->asfla2_CB->show(); - } else { - ui->asfla2_label->hide(); - ui->asfla2_CB->hide(); - } - if (spoilers>0 && ui->as_CB->isChecked()) { - ui->asspo1_label->show(); - ui->asspo1_CB->show(); - } else { - ui->asspo1_label->hide(); - ui->asspo1_CB->hide(); - } - if (spoilers>1 && ui->as_CB->isChecked()) { - ui->asspo2_label->show(); - ui->asspo2_CB->show(); - } else { - ui->asspo2_label->hide(); - ui->asspo2_CB->hide(); - } - rxLock=false; -} diff --git a/companion/src/modelconfigdialog.h b/companion/src/modelconfigdialog.h deleted file mode 100644 index f8f508c71..000000000 --- a/companion/src/modelconfigdialog.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef MODELCONFIGDIALOG_H -#define MODELCONFIGDIALOG_H -#include "eeprominterface.h" -#include -#include - - -namespace Ui { - class modelConfigDialog; -} - -class modelConfigDialog : public QDialog { - Q_OBJECT -public: - modelConfigDialog(RadioData &radioData, uint64_t * result, QWidget *parent = 0); - ~modelConfigDialog(); - -private: - Ui::modelConfigDialog *ui; - bool wingsLock; - bool tailLock; - bool rxLock; - int ModelType; - RadioData &radioData; - uint64_t * result; - GeneralSettings generalSettings; - QStringList ruddercolor; - QStringList aileroncolor; - QStringList elevatorcolor; - QStringList throttlecolor; - QStringList flapscolor; - QStringList airbrakecolor; - QStringList helicolor; - bool rx[10]; - unsigned int ailerons; - unsigned int rudders; - unsigned int throttle; - unsigned int elevators; - unsigned int spoilers; - unsigned int flaps; - - - -private slots: - void ConfigChanged(); - void tailConfigChanged(); - void rxUpdate(); - void resetControls(); - void on_planeButton_clicked(); - void on_heliButton_clicked(); - void on_gliderButton_clicked(); - void on_deltaButton_clicked(); - void formSetup(); - void asUpdate(); - void shrink(); - void doAction(QAbstractButton *button); -}; - -#endif // MODELCONFIGDIALOG_H diff --git a/companion/src/modelconfigdialog.ui b/companion/src/modelconfigdialog.ui deleted file mode 100644 index afa4dd0bd..000000000 --- a/companion/src/modelconfigdialog.ui +++ /dev/null @@ -1,1264 +0,0 @@ - - - modelConfigDialog - - - - 0 - 0 - 793 - 599 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Model Configuration Wizard - - - - - - Engine - - - - - - - 0 - - - - - Qt::Vertical - - - - 400 - 20 - - - - - - - - - 0 - 0 - - - - - 400 - 200 - - - - QFrame::Panel - - - 0 - - - - - - :/images/mcw/aw0a0f.png - - - false - - - 0 - - - - - - - - 0 - 0 - - - - - 400 - 200 - - - - QFrame::Panel - - - 0 - - - - - - :/images/mcw/atailv.png - - - false - - - 0 - - - - - - - - - Qt::Vertical - - - - - - - - 18 - - - - Model Type - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - Airplane - - - - - - - :/images/mcw/aicon.png:/images/mcw/aicon.png - - - - 50 - 29 - - - - - - - - - 0 - 0 - - - - - 85 - 0 - - - - Helicopter - - - - - - - :/images/mcw/hicon.png:/images/mcw/hicon.png - - - - 50 - 29 - - - - - - - - - 85 - 0 - - - - Glider - - - - - - - :/images/mcw/gicon.png:/images/mcw/gicon.png - - - - 50 - 29 - - - - - - - - - 0 - 0 - - - - - 14 - 75 - true - - - - Wing - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - Aileron controls - - - - - - - - No Ailerons - - - - - 1 Servo (or Y) - - - - - 2 Servos - - - - - - - - - 0 - 0 - - - - Flaps controls - - - - - - - - No Flaps - - - - - 1 Servo (or inverting Y) - - - - - 2 Servos - - - - - - - - Spoilers - - - - - - - - No Spoilers/Airbrakes - - - - - 1 Servo (or Y or inverting Y) - - - - - 2 Servos - - - - - - - - - 0 - 0 - - - - - 14 - 75 - true - - - - Swash Plate - - - Qt::AlignCenter - - - - - - - Swash plate - - - - - - - - 90° / Fixed / Coax - - - - - 120° - - - - - 120X° - - - - - 140° - - - - - FlyBarLess - - - - - - - - - 0 - 0 - - - - - 14 - 75 - true - - - - Tail - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - Tail controls - - - - - - - - 1 Servo Elevator / 1 Servo Rudder - - - - - V Tail - - - - - 2 Servos Elevator / 1 Servo Rudder - - - - - - - - Gyroscope - - - - - - - - NoGyro - - - - - Switch control - - - - - Pot control - - - - - - - - Channel style - - - - - - - - Open9x Style - - - - - Futaba Style - - - - - - - - 3 - - - - - QFrame::Panel - - - QFrame::Raised - - - 2 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 3 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 4 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 5 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 6 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 7 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 8 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 9 - - - Qt::AlignCenter - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 1 - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - QFrame::Panel - - - QFrame::Raised - - - 10 - - - Qt::AlignCenter - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 0 - - - - - - - - Ele2 - - - - - - - Use advanced controls - - - - - - - Spoiler2 - - - - - - - Flap2 - - - - - - - Flap1 - - - - - - - Rud2 - - - - - - - - AUTO - - - - - CH01 - - - - - CH02 - - - - - CH03 - - - - - CH04 - - - - - CH05 - - - - - CH06 - - - - - CH07 - - - - - CH08 - - - - - CH09 - - - - - CH10 - - - - - - - - Ail2 - - - - - - - Spoiler 1 - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Apply|QDialogButtonBox::Cancel - - - false - - - - - - - - AUTO - - - - - CH01 - - - - - CH02 - - - - - CH03 - - - - - CH04 - - - - - CH05 - - - - - CH06 - - - - - CH07 - - - - - CH08 - - - - - CH09 - - - - - CH10 - - - - - - - - - AUTO - - - - - CH01 - - - - - CH02 - - - - - CH03 - - - - - CH04 - - - - - CH05 - - - - - CH06 - - - - - CH07 - - - - - CH08 - - - - - CH09 - - - - - CH10 - - - - - - - - - AUTO - - - - - CH01 - - - - - CH02 - - - - - CH03 - - - - - CH04 - - - - - CH05 - - - - - CH06 - - - - - CH07 - - - - - CH08 - - - - - CH09 - - - - - CH10 - - - - - - - - - AUTO - - - - - CH01 - - - - - CH02 - - - - - CH03 - - - - - CH04 - - - - - CH05 - - - - - CH06 - - - - - CH07 - - - - - CH08 - - - - - CH09 - - - - - CH10 - - - - - - - - - AUTO - - - - - CH01 - - - - - CH02 - - - - - CH03 - - - - - CH04 - - - - - CH05 - - - - - CH06 - - - - - CH07 - - - - - CH08 - - - - - CH09 - - - - - CH10 - - - - - - - - - AUTO - - - - - CH01 - - - - - CH02 - - - - - CH03 - - - - - CH04 - - - - - CH05 - - - - - CH06 - - - - - CH07 - - - - - CH08 - - - - - CH09 - - - - - CH10 - - - - - - - - - - - 85 - 0 - - - - Delta wing - - - - - - - :/images/mcw/dicon.png:/images/mcw/dicon.png - - - - 50 - 29 - - - - - - - - - Not present - - - - - Present - - - - - - - - Rudder - - - - - - - - Not present - - - - - Single rudder - - - - - Dual rudder (with 2 servos) - - - - - - - - - - - diff --git a/companion/src/modeledit/expodialog.cpp b/companion/src/modeledit/expodialog.cpp index 511533894..0bf6e7965 100644 --- a/companion/src/modeledit/expodialog.cpp +++ b/companion/src/modeledit/expodialog.cpp @@ -183,7 +183,8 @@ void ExpoDialog::valuesChanged() phtemp >>=1; } } - } else { + } + else { ed->phases=0; } } diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index 15efc1403..e658c757c 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -85,7 +85,7 @@ void ModelsListWidget::ShowContextMenu(const QPoint& pos) bool hasData = mimeData->hasFormat("application/x-companion"); QMenu contextMenu; - contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(OpenEditWindow())); + contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(EditModel())); contextMenu.addAction(CompanionIcon("open.png"), tr("&Restore from backup"),this,SLOT(LoadBackup())); contextMenu.addAction(CompanionIcon("wizard.png"), tr("&Model Wizard"),this,SLOT(OpenWizard())); contextMenu.addSeparator(); @@ -103,14 +103,19 @@ void ModelsListWidget::ShowContextMenu(const QPoint& pos) contextMenu.exec(globalPos); } +void ModelsListWidget::EditModel() +{ + ((MdiChild *)parent())->modelEdit(); +} + void ModelsListWidget::OpenEditWindow() { - ((MdiChild *)parent())->OpenEditWindow(false); + ((MdiChild *)parent())->openEditWindow(); } void ModelsListWidget::OpenWizard() { - ((MdiChild *)parent())->OpenEditWindow(true); + ((MdiChild *)parent())->wizardEdit(); } void ModelsListWidget::LoadBackup() @@ -229,6 +234,7 @@ void ModelsListWidget::dropEvent(QDropEvent *event) // QMessageBox::warning(this, tr("Companion"),tr("Index :%1").arg(row)); const QMimeData *mimeData = event->mimeData(); + if(mimeData->hasFormat("application/x-companion")) { QByteArray gmData = mimeData->data("application/x-companion"); diff --git a/companion/src/modelslist.h b/companion/src/modelslist.h index 8d6e73e83..b21d4914b 100644 --- a/companion/src/modelslist.h +++ b/companion/src/modelslist.h @@ -81,6 +81,7 @@ public slots: void copy(); void paste(); void print(); + void EditModel(); void OpenEditWindow(); void LoadBackup(); void OpenWizard(); diff --git a/companion/src/wizarddata.cpp b/companion/src/wizarddata.cpp new file mode 100644 index 000000000..b67adcb55 --- /dev/null +++ b/companion/src/wizarddata.cpp @@ -0,0 +1,71 @@ +/* + * Author - Kjell Kernen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include "wizarddata.h" + +Channel::Channel() +{ + clear(); +} + +void Channel::clear() +{ + page = Page_None; + input1 = NOINPUT; + input2 = NOINPUT; + weight1 = 0; + weight2 = 0; +} + +WizMix::WizMix(const GeneralSettings & settings, const unsigned int modelId): + complete(false), + modelId(modelId), + settings(settings), + vehicle(NOVEHICLE) +{ + strcpy(name, " "); +} + +WizMix::operator ModelData() +{ + ModelData model; + + model.used = true; + model.modelId = modelId; + model.setDefaultInputs(settings); + + // Safe copy model name + strncpy(model.name, name, WIZ_MODEL_NAME_LENGTH); + model.name[WIZ_MODEL_NAME_LENGTH] = 0; + + for (int i=0; i= RUDDER && ch.input1 <= AILERON) { + if (IS_TARANIS(GetEepromInterface()->getBoard())) + mix.srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, ch.input1-1, &model); + else + mix.srcRaw = RawSource(SOURCE_TYPE_STICK, ch.input1-1); + } + mix.weight = ch.weight1; + } + } + + return model; +} + + diff --git a/companion/src/wizarddata.h b/companion/src/wizarddata.h new file mode 100644 index 000000000..bc190fdf6 --- /dev/null +++ b/companion/src/wizarddata.h @@ -0,0 +1,96 @@ +/* + * Author - Kjell Kernen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef WIZARDDATA_H +#define WIZARDDATA_H + +#include "eeprominterface.h" + +#define WIZ_MAX_CHANNELS 8 + +// TODO use a constant common to the whole companion +// TODO when in the wizard use the getCapacity(...) to know how long the name can be +#define WIZ_MODEL_NAME_LENGTH 12 + +enum Input { + NOINPUT, + RUDDER, + ELEVATOR, + THROTTLE, + AILERON, + FLAP, + AIRBREAK +}; + +enum Vehicle { + NOVEHICLE, + PLANE, + MULTICOPTER, + HELICOPTER +}; + +enum WizardPage { + Page_None = -1, + Page_Models, + Page_Throttle, + Page_Wingtypes, + Page_Ailerons, + Page_Flaps, + Page_Airbrakes, + Page_Bank, + Page_Rudder, + Page_Tails, + Page_Tail, + Page_Vtail, + Page_Simpletail, + Page_Cyclic, + Page_Gyro, + Page_Flybar, + Page_Fblheli, + Page_Helictrl, + Page_Multirotor, + Page_Conclusion +}; + +class Channel +{ + public: + WizardPage page; // Originating dialog, only of interest for producer + Input input1; + Input input2; + int weight1; + int weight2; + + Channel(); + void clear(); +}; + +class WizMix +{ + public: + bool complete; + char name[WIZ_MODEL_NAME_LENGTH + 1]; + unsigned int modelId; + const GeneralSettings & settings; + Vehicle vehicle; + Channel channel[WIZ_MAX_CHANNELS]; + + WizMix(const GeneralSettings & settings, const unsigned int modelId); + operator ModelData(); + + private: + WizMix(); +}; + +#endif // WIZARDDATA_H diff --git a/companion/src/wizarddialog.cpp b/companion/src/wizarddialog.cpp new file mode 100644 index 000000000..77df3bc80 --- /dev/null +++ b/companion/src/wizarddialog.cpp @@ -0,0 +1,817 @@ +/* + * Author - Kjell Kernen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "wizarddialog.h" +#include "wizarddata.h" + +WizardDialog::WizardDialog(const GeneralSettings & settings, unsigned int modelId, QWidget *parent) + : QWizard(parent), + mix(settings, modelId), + settings(settings) +{ + setWindowTitle(tr("Model Wizard")); + + setPage(Page_Models, new ModelSelectionPage(this, "models",tr("Model Type"),tr("Enter model name and model type."))); + setPage(Page_Throttle, new ThrottlePage(this, "throttle",tr("Throttle"),tr("Has your model got a motor or an engine?"), Page_Wingtypes)); + setPage(Page_Wingtypes, new WingtypeSelectionPage(this, "wingtype",tr("Wing Type"),tr("Is your model a flying wing/deltawing or has it a standard wing configuration?"))); + setPage(Page_Ailerons, new AileronsPage(this, "ailerons",tr("Ailerons"),tr("Has your model got ailerons?"), Page_Flaps)); + setPage(Page_Flaps, new FlapsPage(this, "flaps",tr("Flaps"),tr("Has your model got flaps?"), Page_Airbrakes)); + setPage(Page_Airbrakes, new AirbreaksPage(this, "airbrakes",tr("Airbrakes"),tr("Has your model got airbrakes?"), Page_Tails)); + setPage(Page_Bank, new BankPage(this, "bank",tr("Flying-wing / Delta-wing"),tr("Are the elevons controlled by servos connected to separate channels or by a single servo channel?"), Page_Rudder)); + setPage(Page_Rudder, new RudderPage(this, "rudder",tr("Rudder"),tr("Does your model have a rudder?"), Page_Conclusion)); + setPage(Page_Tails, new TailSelectionPage(this, "tails",tr("Tail Type"),tr("Select which type of tail your model is equiped with."))); + setPage(Page_Tail, new TailPage(this, "tail",tr("Tail"),tr("Select channels for tail control."), Page_Conclusion)); + setPage(Page_Vtail, new VTailPage(this, "vtail",tr("V-Tail"),tr("Select channels for tail control."), Page_Conclusion)); + setPage(Page_Simpletail, new SimpleTailPage(this, "simpletail",tr("Tail"),tr("Select elevator channel."), Page_Conclusion)); + setPage(Page_Cyclic, new CyclicPage(this, "cyclic",tr("Cyclic"),tr("Which type of swash control is installed in your helicopter?"), Page_Gyro)); + setPage(Page_Gyro, new GyroPage(this, "gyro",tr("Tail Gyro"),tr("Has your helicopter got an adjustable gyro for the tail?"), Page_Flybar)); + setPage(Page_Flybar, new FlybarSelectionPage(this, "flybar",tr("Rotor Type"),tr("Has your helicopter got a flybar?"))); + setPage(Page_Fblheli, new FblPage(this, "fblheli",tr("Helicopter"),tr("Select the controls for your helicopter"), Page_Conclusion)); + setPage(Page_Helictrl, new HeliPage(this, "helictrl",tr("Helicopter"),tr("Select the controls for your helicopter"), Page_Conclusion)); + setPage(Page_Multirotor, new MultirotorPage(this, "multirotor",tr("Multirotor"),tr("Select the control channels for your multirotor"), Page_Conclusion)); + setPage(Page_Conclusion, new ConclusionPage(this, "conclusion",tr("Save Changes"),tr( + "Manually check the direction of each control surface and reverse any channels that make controls move in the wrong direction. " + "Remove the propeller/propellers before you try to control your model for the first time.
" + "Please note that continuing removes all old model settings!"), -1)); + setStartId(Page_Models); + +#ifndef Q_WS_MAC + setWizardStyle(ModernStyle); +#endif + setOption(HaveHelpButton, true); + connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp())); +} + +void WizardDialog::showHelp() +{ + QString message; + + switch (currentId()) { + case Page_Models: + message = tr("Enter a name for your model and select model type."); break; + case Page_Throttle: + message = tr("Select the receiver channel that is connected to your ESC or throttle servo.

" + "Throttle - Spektrum: CH1, Futaba: CH3"); break; + case Page_Wingtypes: + message = tr("Most aircraft have a main wing and a tail with control surfaces. Flying wings and delta winged aircraft only have a single wing. " + "The main control surface on a standard wing controlls the roll of the aircraft. This surface is called an aileron.
" + "The control surface of a delta wing controls both roll and elevation. This surface is called an elevon. "); break; + case Page_Ailerons: + message = tr("Models use one or two channels to control the ailerons.
" + "A so called Y-cable can be used to connect single receiver channel to two separeate aileron servos. " + "If your servos are connected by a Y-cable you should select the single-servo option.

" + "Aileron - Spektrum: CH2, Futaba: CH1"); break; + case Page_Flaps: + message = tr("This wizard assumes that your flaps are controlled by a switch. " + "If your flaps are controlled by a potentiometer you can change that manually later."); break; + case Page_Airbrakes: + message = tr("Air brakes are used to reduce the speed of advanced sail planes.
" + "They are very uncommon on other types of planes."); break; + case Page_Bank: + message = tr("Models use one or two channels to control the elevons.
" + "A so called Y-cable can be used to connect single receiver channel to two separeate elevon servos. " + "If your servos are connected by a Y-cable you should select the single-servo option."); break; + case Page_Rudder: + message = tr("Select the receiver channel that is connected to your rudder.

" + "Rudder - Spektrum: CH4, Futaba: CH4"); break; + case Page_Tails: + message = tr("Select the tail type of your plane."); break; + case Page_Tail: + message = tr("Select the Rudder and Elevator channels.

" + "Rudder - Spektrum: CH4, Futaba: CH4
" + "Elevator - Spektrum: CH3, Futaba: CH2"); break; + case Page_Vtail: + message = tr("Select the Rudder and Elevator channels.

" + "Rudder - Spektrum: CH4, Futaba: CH4
" + "Elevator - Spektrum: CH3, Futaba: CH2"); break; + case Page_Simpletail: + message = tr("Select the Elevator channel.

" + "Elevator - Spektrum: CH3, Futaba: CH2"); break; + case Page_Flybar: + message = tr("TBD."); break; + case Page_Cyclic: + message = tr("TBD."); break; + case Page_Gyro: + message = tr("TBD."); break; + case Page_Fblheli: + message = tr("TBD."); break; + case Page_Helictrl: + message = tr("TBD."); break; + case Page_Multirotor: + message = tr("Select the control channels for your multirotor.

" + "Throttle - Spektrum: CH1, Futaba: CH3
" + "Yaw - Spektrum: CH4, Futaba: CH4
" + "Pitch - Spektrum: CH3, Futaba: CH2
" + "Roll - Spektrum: CH2, Futaba: CH1"); break; + case Page_Conclusion: + message = tr("TBD."); break; + default: + message = tr("There is no help available for the current page."); + } + QMessageBox::information(this, tr("Model Wizard Help"), message); +} + +StandardPage::StandardPage(WizardPage currentPage, WizardDialog *dlg, QString image, QString title, QString text, int nextPage ) + : QWizardPage(), + wizDlg(dlg), + pageCurrent(currentPage), + pageFollower(nextPage) +{ + setTitle(title); + setPixmap(QWizard::WatermarkPixmap, QPixmap(QString(":/images/wizard/%1.png").arg(image))); + topLabel = new QLabel(text+"
"); + topLabel->setWordWrap(true); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(topLabel); + setLayout(layout); +} + +int StandardPage::getDefaultChannel(const Input input) +{ + for (int channel=0; channel<4; channel++) { + unsigned int stick_index = chout_ar[4*wizDlg->settings.templateSetup + channel]; + if (input == stick_index) + return channel; + } + return -1; +} + +void StandardPage::populateCB(QComboBox *cb, int preferred) +{ + cb->clear(); + + for (int i=0; imix.channel[i].page == Page_None) { + // this channel is not already used + cb->addItem(tr("Channel %1").arg(i+1), i); + if (preferred == i) { + cb->setCurrentIndex(cb->count()-1); + } + } + } +} + +bool StandardPage::bookChannel(QComboBox * cb, Input input1, int weight1, Input input2, int weight2 ) +{ + int channel = cb->itemData(cb->currentIndex()).toInt(); + if (channel<0 || channel>=WIZ_MAX_CHANNELS) + return false; + if (wizDlg->mix.channel[channel].page != Page_None) + return false; + + wizDlg->mix.channel[channel].page = pageCurrent; + wizDlg->mix.channel[channel].input1 = input1; + wizDlg->mix.channel[channel].input2 = input2; + wizDlg->mix.channel[channel].weight1 = weight1; + wizDlg->mix.channel[channel].weight2 = weight2; + + return true; +} + +void StandardPage::releaseChannels() +{ + for (int i=0; imix.channel[i].page == pageCurrent){ + wizDlg->mix.channel[i].clear(); + } + } +} + +void StandardPage::cleanupPage() +{ + releaseChannels(); +} + +int StandardPage::nextId() const +{ + return pageFollower; +} + +ModelSelectionPage::ModelSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) + : StandardPage(Page_Models, dlg, image, title, text) +{ + nameLineEdit = new QLineEdit; + planeRB = new QRadioButton(tr("Plane")); + planeRB->setChecked(true); + multirotorRB = new QRadioButton(tr("Multirotor")); + helicopterRB = new QRadioButton(tr("Helicopter")); + + registerField("evaluate.name*", nameLineEdit); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Model Name:"))); + l->addWidget(nameLineEdit); + l->addWidget(new QLabel("")); + l->addWidget(new QLabel(tr("Model Type:"))); + l->addWidget(planeRB); + l->addWidget(multirotorRB); + l->addWidget(helicopterRB); +} + +bool ModelSelectionPage::validatePage() +{ + //Filter and insert model name in mix data + QString newName(nameLineEdit->text()); + newName = (newName.normalized(QString::NormalizationForm_D)); + newName = newName.replace(QRegExp("[^ A-Za-z0-9_.-,\\s]"), ""); + strncpy( wizDlg->mix.name, newName.toAscii(), WIZ_MODEL_NAME_LENGTH); + wizDlg->mix.name[WIZ_MODEL_NAME_LENGTH]=0; + + if (multirotorRB->isChecked()) + wizDlg->mix.vehicle = MULTICOPTER; + else if (helicopterRB->isChecked()) + wizDlg->mix.vehicle = HELICOPTER; + else + wizDlg->mix.vehicle = PLANE; + return true; +} + +int ModelSelectionPage::nextId() const +{ + if (helicopterRB->isChecked()) + return Page_Cyclic; + else if (multirotorRB->isChecked()) + return Page_Multirotor; + else + return Page_Throttle; +} + +WingtypeSelectionPage::WingtypeSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) + : StandardPage(Page_Wingtypes, dlg, image, title, text) +{ + standardWingRB = new QRadioButton(tr("Standard Wing")); + standardWingRB->setChecked(true); + deltaWingRB = new QRadioButton(tr("Flying Wing / Deltawing")); + + QLayout *l = layout(); + l->addWidget(standardWingRB); + l->addWidget(deltaWingRB); +} + +int WingtypeSelectionPage::nextId() const +{ + if (deltaWingRB->isChecked()) + return Page_Bank; + else + return Page_Ailerons; +} + +TailSelectionPage::TailSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) + : StandardPage(Page_Tails, dlg, image, title, text) +{ + standardTailRB = new QRadioButton(tr("Elevator and Rudder")); + standardTailRB->setChecked(true); + simpleTailRB = new QRadioButton(tr("Only Elevator")); + vTailRB = new QRadioButton(tr("V-tail")); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Tail Type:"))); + l->addWidget(standardTailRB); + l->addWidget(simpleTailRB); + l->addWidget(vTailRB); +} + +int TailSelectionPage::nextId() const +{ + if (simpleTailRB->isChecked()) + return Page_Simpletail; + else if (vTailRB->isChecked()) + return Page_Vtail; + else + return Page_Tail; +} + +FlybarSelectionPage::FlybarSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) + : StandardPage(Page_Flybar, dlg, image, title, text) +{ + flybarRB = new QRadioButton(tr("Has Flybar")); + flybarRB->setChecked(true); + noFlybarRB = new QRadioButton(tr("Flybarless")); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Flybar:"))); + l->addWidget(flybarRB); + l->addWidget(noFlybarRB); +} + +int FlybarSelectionPage::nextId() const +{ + if (flybarRB->isChecked()) + return Page_Helictrl; + else + return Page_Fblheli; +} + +ThrottlePage::ThrottlePage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Throttle, dlg, image, title, text, nextPage) +{ + motorRB = new QRadioButton(tr("Yes")); + noMotorRB = new QRadioButton(tr("No")); + motorRB->setChecked(true); + throttleCB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(motorRB); + l->addWidget(noMotorRB); + l->addWidget(new QLabel(tr("
Throttle Channel:"))); + l->addWidget(throttleCB); + + connect(motorRB, SIGNAL(toggled(bool)), this, SLOT(onMotorStateChanged(bool))); +} + +void ThrottlePage::initializePage() +{ + populateCB(throttleCB, getDefaultChannel(THROTTLE)); +} + +bool ThrottlePage::validatePage() +{ + releaseChannels(); + if (motorRB->isChecked()) + return bookChannel(throttleCB, THROTTLE, 100); + else + return true; +} + +void ThrottlePage::onMotorStateChanged(bool toggled) +{ + throttleCB->setEnabled(toggled); +} + +AileronsPage::AileronsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Ailerons, dlg, image, title, text, nextPage) +{ + noAileronsRB = new QRadioButton(tr("No")); + oneAileronRB = new QRadioButton(tr("Yes, controlled by a single channel")); + twoAileronsRB = new QRadioButton(tr("Yes, controlled by two channels")); + noAileronsRB->setChecked(true); + aileron1CB = new QComboBox(); + aileron2CB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(noAileronsRB); + l->addWidget(oneAileronRB); + l->addWidget(twoAileronsRB); + l->addWidget(new QLabel(tr("
First Aileron Channel:"))); + l->addWidget(aileron1CB); + l->addWidget(new QLabel(tr("Second Aileron Channel:"))); + l->addWidget(aileron2CB); +} + +void AileronsPage::initializePage(){ + populateCB(aileron1CB); + populateCB(aileron2CB); +} + +bool AileronsPage::validatePage() { + releaseChannels(); + if (noAileronsRB->isChecked()) { + return true; + } + if (oneAileronRB->isChecked()) { + return (bookChannel(aileron1CB, AILERON, 100 )); + } + return( bookChannel(aileron1CB, AILERON, 100 ) && + bookChannel(aileron2CB, AILERON, 100 )); +} + +FlapsPage::FlapsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Flaps, dlg, image, title, text, nextPage) +{ + noFlapsRB = new QRadioButton(tr("No")); + oneFlapRB = new QRadioButton(tr("Yes, controlled by a single channel")); + twoFlapsRB = new QRadioButton(tr("Yes, controlled by two channels")); + noFlapsRB->setChecked(true); + flap1CB = new QComboBox(); + flap2CB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(noFlapsRB); + l->addWidget(oneFlapRB); + l->addWidget(twoFlapsRB); + l->addWidget(new QLabel(tr("
First Flap Channel:"))); + l->addWidget(flap1CB); + l->addWidget(new QLabel(tr("Second Flap Channel:"))); + l->addWidget(flap2CB); +} + +void FlapsPage::initializePage(){ + populateCB(flap1CB); + populateCB(flap2CB); +} + +bool FlapsPage::validatePage() { + releaseChannels(); + if (noFlapsRB->isChecked()) { + return true; + } + if (oneFlapRB->isChecked()) { + return (bookChannel(flap1CB, FLAP, 100 )); + } + return( bookChannel(flap1CB, FLAP, 100 ) && + bookChannel(flap2CB, FLAP, 100 )); +} + +AirbreaksPage::AirbreaksPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Airbrakes, dlg, image, title, text, nextPage) +{ + noAirbreaksRB = new QRadioButton(tr("No")); + oneAirbreakRB = new QRadioButton(tr("Yes, controlled by a single channel")); + twoAirbreaksRB = new QRadioButton(tr("Yes, controlled by two channels")); + noAirbreaksRB->setChecked(true); + airbreak1CB = new QComboBox(); + airbreak2CB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(noAirbreaksRB); + l->addWidget(oneAirbreakRB); + l->addWidget(twoAirbreaksRB); + l->addWidget(new QLabel(tr("
First Airbreak Channel:"))); + l->addWidget(airbreak1CB); + l->addWidget(new QLabel(tr("Second Airbreak Channel:"))); + l->addWidget(airbreak2CB); +} + +void AirbreaksPage::initializePage(){ + populateCB(airbreak1CB); + populateCB(airbreak2CB); +} + +bool AirbreaksPage::validatePage() { + releaseChannels(); + if (noAirbreaksRB->isChecked()) { + return true; + } + if (oneAirbreakRB->isChecked()) { + return (bookChannel(airbreak1CB, AIRBREAK, 100 )); + } + return( bookChannel(airbreak1CB, AIRBREAK, 100 ) && + bookChannel(airbreak2CB, AIRBREAK, 100 )); +} + +BankPage::BankPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Bank, dlg, image, title, text, nextPage) +{ + oneElevonChRB = new QRadioButton(tr("One")); + oneElevonChRB->setChecked(true); + twoElevonsChRB = new QRadioButton(tr("Two")); + elevon1CB = new QComboBox(); + elevon2CB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(oneElevonChRB); + l->addWidget(twoElevonsChRB); + l->addWidget(new QLabel(tr("
First Elevon Channel:"))); + l->addWidget(elevon1CB); + l->addWidget(new QLabel(tr("Second Elevon Channel:"))); + l->addWidget(elevon2CB); +} + +void BankPage::initializePage(){ + populateCB(elevon1CB); + populateCB(elevon2CB); +} + +bool BankPage::validatePage() { + releaseChannels(); + if (oneElevonChRB->isChecked()) { + return (bookChannel(elevon1CB, AILERON, 100, ELEVATOR, 100 )); + } + return( bookChannel(elevon1CB, AILERON, 100, ELEVATOR, 100 ) && + bookChannel(elevon2CB, AILERON, 100, ELEVATOR, 100 )); +} + +RudderPage::RudderPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Rudder, dlg, image, title, text, nextPage) +{ + noRudderRB = new QRadioButton(tr("No")); + noRudderRB->setChecked(true); + hasRudderRB = new QRadioButton(tr("Yes")); + rudderCB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(noRudderRB); + l->addWidget(hasRudderRB); + l->addWidget(new QLabel(tr("
Rudder Channel:"))); + l->addWidget(rudderCB); +} + +void RudderPage::initializePage(){ + populateCB(rudderCB); +} + +bool RudderPage::validatePage() { + releaseChannels(); + if (noRudderRB->isChecked()) + return true; + + return (bookChannel(rudderCB, RUDDER, 100)); +} + +VTailPage::VTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Tail, dlg, image, title, text, nextPage) +{ + tail1CB = new QComboBox(); + tail2CB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("First Tail Channel:"))); + l->addWidget(tail1CB); + l->addWidget(new QLabel(tr("Second Tail Channel:"))); + l->addWidget(tail2CB); +} + +void VTailPage::initializePage(){ + populateCB(tail1CB); + populateCB(tail2CB); +} + +bool VTailPage::validatePage() { + releaseChannels(); + return (bookChannel(tail1CB, ELEVATOR, 100, RUDDER, 100) && + bookChannel(tail2CB, ELEVATOR, 100, RUDDER, 100 )); +} + +TailPage::TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Tail, dlg, image, title, text, nextPage) +{ + elevatorCB = new QComboBox(); + rudderCB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Rudder Channel:"))); + l->addWidget(rudderCB); + l->addWidget(new QLabel(tr("Elevator Channel:"))); + l->addWidget(elevatorCB); +} + +void TailPage::initializePage(){ + populateCB(elevatorCB); + populateCB(rudderCB); +} + +bool TailPage::validatePage() { + releaseChannels(); + return( bookChannel(elevatorCB, ELEVATOR, 100 ) && + bookChannel(rudderCB, RUDDER, 100 )); +} + +SimpleTailPage::SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Simpletail, dlg, image, title, text, nextPage) +{ + elevatorCB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Elevator Channel:"))); + l->addWidget(elevatorCB); +} + +void SimpleTailPage::initializePage(){ + populateCB(elevatorCB); +} + +bool SimpleTailPage::validatePage() { + releaseChannels(); + return( bookChannel(elevatorCB, ELEVATOR, 100 )); +} + +CyclicPage::CyclicPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Cyclic, dlg, image, title, text, nextPage) +{ + cyclic90RB = new QRadioButton(tr("90")); + cyclic90RB->setChecked(true); + cyclic120RB = new QRadioButton(tr("120")); + cyclic120XRB = new QRadioButton(tr("120x")); + cyclic140RB = new QRadioButton(tr("140")); + + QLayout *l = layout(); + l->addWidget(cyclic90RB); + l->addWidget(cyclic120RB); + l->addWidget(cyclic120XRB); + l->addWidget(cyclic140RB); +} + +void CyclicPage::initializePage(){ +} + +bool CyclicPage::validatePage() { + releaseChannels(); + return true; +} + +GyroPage::GyroPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Gyro, dlg, image, title, text, nextPage) +{ + noGyroRB = new QRadioButton(tr("No")); + noGyroRB->setChecked(true); + switchGyroRB = new QRadioButton(tr("Yes, controled by a switch")); + potGyroRB = new QRadioButton(tr("Yes, controlled by a pot")); + + QLayout *l = layout(); + l->addWidget(noGyroRB); + l->addWidget(switchGyroRB); + l->addWidget(potGyroRB); +} + +void GyroPage::initializePage(){ +} + +bool GyroPage::validatePage() { + releaseChannels(); + return true; +} + +FblPage::FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Fblheli, dlg, image, title, text, nextPage) +{ + throttleCB = new QComboBox(); + yawCB = new QComboBox(); + pitchCB = new QComboBox(); + rollCB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Trottle Channel:"))); + l->addWidget(throttleCB); + l->addWidget(new QLabel(tr("Yaw Channel:"))); + l->addWidget(yawCB); + l->addWidget(new QLabel(tr("Pitch Channel:"))); + l->addWidget(pitchCB); + l->addWidget(new QLabel(tr("Roll Channel:"))); + l->addWidget(rollCB); +} + +void FblPage::initializePage(){ + populateCB(throttleCB); + populateCB(yawCB); + populateCB(pitchCB); + populateCB(rollCB); +} + +bool FblPage::validatePage() { + releaseChannels(); + return( bookChannel(throttleCB, THROTTLE, 100 ) && + bookChannel( yawCB, RUDDER, 100 ) && + bookChannel( pitchCB, ELEVATOR, 100 ) && + bookChannel( rollCB, AILERON, 100 )); +} + +HeliPage::HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Helictrl, dlg, image, title, text, nextPage) +{ + throttleCB = new QComboBox(); + yawCB = new QComboBox(); + pitchCB = new QComboBox(); + rollCB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Trottle Channel:"))); + l->addWidget(throttleCB); + l->addWidget(new QLabel(tr("Yaw Channel:"))); + l->addWidget(yawCB); + l->addWidget(new QLabel(tr("Pitch Channel:"))); + l->addWidget(pitchCB); + l->addWidget(new QLabel(tr("Roll Channel:"))); + l->addWidget(rollCB); +} + +void HeliPage::initializePage(){ + populateCB(throttleCB); + populateCB(yawCB); + populateCB(pitchCB); + populateCB(rollCB); +} + +bool HeliPage::validatePage() { + releaseChannels(); + return( bookChannel(throttleCB, THROTTLE, 100 ) && + bookChannel( yawCB, RUDDER, 100 ) && + bookChannel( pitchCB, ELEVATOR, 100 ) && + bookChannel( rollCB, AILERON, 100 )); +} + +MultirotorPage::MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Multirotor, dlg, image, title, text, nextPage) +{ + throttleCB = new QComboBox(); + yawCB = new QComboBox(); + pitchCB = new QComboBox(); + rollCB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("Trottle Channel:"))); + l->addWidget(throttleCB); + l->addWidget(new QLabel(tr("Yaw Channel:"))); + l->addWidget(yawCB); + l->addWidget(new QLabel(tr("Pitch Channel:"))); + l->addWidget(pitchCB); + l->addWidget(new QLabel(tr("Roll Channel:"))); + l->addWidget(rollCB); +} + +void MultirotorPage::initializePage(){ + populateCB(throttleCB); + populateCB(yawCB); + populateCB(pitchCB); + populateCB(rollCB); +} + +bool MultirotorPage::validatePage() { + releaseChannels(); + return( bookChannel(throttleCB, THROTTLE, 100 ) && + bookChannel(yawCB, RUDDER, 100 ) && + bookChannel(pitchCB, ELEVATOR, 100 ) && + bookChannel(rollCB, AILERON, 100 )); +} + +ConclusionPage::ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(Page_Conclusion, dlg, image, title, text, nextPage) +{ + textLabel = new QLabel(); + proceedCB = new QCheckBox(tr("OK, I understand.")); + registerField("evaluate.proceed*", proceedCB); + + QLayout *l = layout(); + l->addWidget(textLabel); + l->addWidget(proceedCB); +} + +void ConclusionPage::initializePage(){ + WizardPrinter p(&wizDlg->mix); + textLabel->setText(p.print()); +} + +bool ConclusionPage::validatePage() { + wizDlg->mix.complete = true; + return true; +} + + +QString WizardPrinter::inputName(Input input) +{ + switch (input){ + case THROTTLE: return "THR"; + case RUDDER: return "RUD"; + case ELEVATOR: return "ELE"; + case AILERON: return "AIL"; + case FLAP: return "FLP"; + case AIRBREAK: return "AIR"; + default: return "---"; + } +} + +QString WizardPrinter::vehicleName(Vehicle vehicle) +{ + switch (vehicle){ + case PLANE: return "Plane"; + case MULTICOPTER: return "Multicopter"; + case HELICOPTER: return "Helicopter"; + default: return "---"; + } +} + +WizardPrinter::WizardPrinter(WizMix *wizMix) +{ + mix = wizMix; +} + + QString WizardPrinter::printChannel( Input input1, int weight1, Input input2, int weight2 ) +{ + QString str; + str = QString("[%1, %2]").arg(inputName(input1)).arg(weight1); + if ( input2 != NOINPUT ) + str += QString("[%1, %2]").arg(inputName(input2)).arg(weight2); + return str; +} + +QString WizardPrinter::print() +{ + QString str; + str = QString(tr("Model Name: ")) + mix->name + "\n"; + str += QString(tr("Model Type: ")) + vehicleName(mix->vehicle) + "\n"; + for (int i=0; ichannel[i].page != Page_None) { + Channel ch = mix->channel[i]; + str += QString(tr("Channel %1: ").arg(i+1)); + str += printChannel(ch.input1, ch.weight1, ch.input2, ch.weight2 ); + str += QString("\n"); + } + } + return str; +} + + + diff --git a/companion/src/wizarddialog.h b/companion/src/wizarddialog.h new file mode 100644 index 000000000..9819947b8 --- /dev/null +++ b/companion/src/wizarddialog.h @@ -0,0 +1,334 @@ +/* + * Author - Kjell Kernen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef WIZARDDIALOG_H +#define WIZARDDIALOG_H +#include +#include "wizarddata.h" + +QT_BEGIN_NAMESPACE +class QCheckBox; +class QLabel; +class QLineEdit; +class QRadioButton; +class QComboBox; +QT_END_NAMESPACE + +class WizardDialog : public QWizard +{ + Q_OBJECT + + public: + WizMix mix; + WizardDialog(const GeneralSettings & settings, const unsigned int modelId, QWidget *parent = 0); + const GeneralSettings & settings; + + private slots: + void showHelp(); +}; + +class StandardPage: public QWizardPage +{ + Q_OBJECT + + public: + StandardPage(WizardPage curPage, WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + WizardDialog *wizDlg; + + // TODO public for these 3 ones? + void releaseChannels(); + void cleanupPage(); + + protected: + int getDefaultChannel(const Input input); + void populateCB(QComboBox * cb, int preferred=-1); + bool bookChannel(QComboBox * cb, Input input1, int weight1, Input input2=NOINPUT, int weight2=0); + + private: + QLabel *topLabel; + WizardPage pageCurrent; + int pageFollower; + int nextId() const; +}; + +class ModelSelectionPage: public StandardPage +{ + Q_OBJECT +public: + ModelSelectionPage(WizardDialog *dlg, QString image, QString title, QString text); +private: + QLineEdit *nameLineEdit; + QRadioButton *planeRB; + QRadioButton *multirotorRB; + QRadioButton *helicopterRB; + bool validatePage(); + int nextId() const; +}; + +class WingtypeSelectionPage: public StandardPage +{ + Q_OBJECT +public: + WingtypeSelectionPage(WizardDialog *dlg, QString image, QString title, QString text); +private: + QRadioButton *deltaWingRB; + QRadioButton *standardWingRB; + int nextId() const; +}; + +class TailSelectionPage: public StandardPage +{ + Q_OBJECT +public: + TailSelectionPage(WizardDialog *dlg, QString image, QString title, QString text); +private: + QRadioButton *vTailRB; + QRadioButton *standardTailRB; + QRadioButton *simpleTailRB; + int nextId() const; +}; + +class FlybarSelectionPage: public StandardPage +{ + Q_OBJECT +public: + FlybarSelectionPage(WizardDialog *dlg, QString image, QString title, QString text); +private: + QRadioButton *flybarRB; + QRadioButton *noFlybarRB; + int nextId() const; +}; + +class ThrottlePage: public StandardPage +{ + Q_OBJECT + + public: + ThrottlePage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); + + protected slots: + void onMotorStateChanged(bool toggled); + + private: + QRadioButton *motorRB; + QRadioButton *noMotorRB; + QComboBox *throttleCB; +}; + +class AileronsPage: public StandardPage +{ + Q_OBJECT +public: + AileronsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QRadioButton *oneAileronRB; + QRadioButton *twoAileronsRB; + QRadioButton *noAileronsRB; + QComboBox *aileron1CB; + QComboBox *aileron2CB; +}; + +class FlapsPage: public StandardPage +{ + Q_OBJECT +public: + FlapsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QRadioButton *oneFlapRB; + QRadioButton *twoFlapsRB; + QRadioButton *noFlapsRB; + QComboBox *flap1CB; + QComboBox *flap2CB; +}; + +class AirbreaksPage: public StandardPage +{ + Q_OBJECT +public: + AirbreaksPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QRadioButton *oneAirbreakRB; + QRadioButton *twoAirbreaksRB; + QRadioButton *noAirbreaksRB; + QComboBox *airbreak1CB; + QComboBox *airbreak2CB; +}; + +class BankPage: public StandardPage +{ + Q_OBJECT +public: + BankPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QRadioButton *oneElevonChRB; + QRadioButton *twoElevonsChRB; + QComboBox *elevon1CB; + QComboBox *elevon2CB; +}; + +class RudderPage: public StandardPage +{ + Q_OBJECT +public: + RudderPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QRadioButton *noRudderRB; + QRadioButton *hasRudderRB; + QComboBox *rudderCB; +}; + +class TailPage: public StandardPage +{ + Q_OBJECT +public: + TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QComboBox *elevatorCB; + QComboBox *rudderCB; +}; + +class VTailPage: public StandardPage +{ + Q_OBJECT +public: + VTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QComboBox *tail1CB; + QComboBox *tail2CB; +}; + +class SimpleTailPage: public StandardPage +{ + Q_OBJECT +public: + SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QComboBox *elevatorCB; +}; + +class CyclicPage: public StandardPage +{ + Q_OBJECT +public: + CyclicPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QRadioButton *cyclic90RB; + QRadioButton *cyclic120RB; + QRadioButton *cyclic120XRB; + QRadioButton *cyclic140RB; +}; + +class GyroPage: public StandardPage +{ + Q_OBJECT +public: + GyroPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QRadioButton *noGyroRB; + QRadioButton *switchGyroRB; + QRadioButton *potGyroRB; +}; + +class FblPage: public StandardPage +{ + Q_OBJECT +public: + FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QComboBox *throttleCB; + QComboBox *yawCB; + QComboBox *pitchCB; + QComboBox *rollCB; +}; + +class HeliPage: public StandardPage +{ + Q_OBJECT +public: + HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QComboBox *throttleCB; + QComboBox *yawCB; + QComboBox *pitchCB; + QComboBox *rollCB; +}; + +class MultirotorPage: public StandardPage +{ + Q_OBJECT +public: + MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QComboBox *throttleCB; + QComboBox *yawCB; + QComboBox *pitchCB; + QComboBox *rollCB; +}; + +class ConclusionPage: public StandardPage +{ + Q_OBJECT +public: + ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QCheckBox *proceedCB; + QLabel *textLabel; +}; + +class WizardPrinter:QObject +{ + Q_OBJECT +public: + WizardPrinter( WizMix * ); + QString print(); +private: + WizMix *mix; + QString inputName( Input ); + QString vehicleName( Vehicle ); + QString printChannel( Input, int, Input, int ); +}; +#endif // WIZARDDIALOG_H + + +