5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include "wizarddialog.h"
22 #include "wizarddata.h"
25 WizardDialog::WizardDialog(const GeneralSettings
& settings
, unsigned int modelId
, const ModelData
& modelData
, QWidget
*parent
):
27 mix(settings
, modelId
, modelData
),
30 setWindowIcon(CompanionIcon("wizard.png"));
31 setWindowTitle(tr("Model Wizard"));
33 setPage(Page_Models
, new ModelSelectionPage(this, "models", tr("Model Type"), tr("Enter model name and model type.")));
34 setPage(Page_Throttle
, new ThrottlePage(this, "throttle", tr("Throttle"), tr("Has your model got a motor or an engine?"), Page_Wingtypes
));
35 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?")));
36 setPage(Page_Ailerons
, new AileronsPage(this, "ailerons", tr("Ailerons"), tr("Has your model got ailerons?"), Page_Flaps
));
37 setPage(Page_Flaps
, new FlapsPage(this, "flaps", tr("Flaps"), tr("Has your model got flaps?"), Page_Airbrakes
));
38 setPage(Page_Airbrakes
, new AirbrakesPage(this, "airbrakes", tr("Airbrakes"), tr("Has your model got airbrakes?"), Page_Tails
));
39 setPage(Page_Elevons
, new ElevonsPage(this, "elevons", tr("Flying-wing / Delta-wing"), tr("Select the elevons channels"), Page_Rudder
));
40 setPage(Page_Rudder
, new RudderPage(this, "rudder", tr("Rudder"), tr("Does your model have a rudder?"), Page_Options
));
41 setPage(Page_Tails
, new TailSelectionPage(this, "tails", tr("Tail Type"), tr("Select which type of tail your model is equiped with.")));
42 setPage(Page_Tail
, new TailPage(this, "tail", tr("Tail"), tr("Select channels for tail control."), Page_Options
));
43 setPage(Page_Vtail
, new VTailPage(this, "vtail", tr("V-Tail"), tr("Select channels for tail control."), Page_Options
));
44 setPage(Page_Simpletail
, new SimpleTailPage(this, "simpletail", tr("Tail"), tr("Select elevator channel."), Page_Options
));
45 setPage(Page_Cyclic
, new CyclicPage(this, "cyclic", tr("Cyclic"), tr("Which type of swash control is installed in your helicopter?"), Page_Gyro
));
46 setPage(Page_Gyro
, new GyroPage(this, "gyro", tr("Tail Gyro"), tr("Has your helicopter got an adjustable gyro for the tail?"), Page_Flybar
));
47 setPage(Page_Flybar
, new FlybarSelectionPage(this, "flybar", tr("Rotor Type"), tr("Has your helicopter got a flybar?")));
48 setPage(Page_Fblheli
, new FblPage(this, "fblheli", tr("Helicopter"), tr("Select the controls for your helicopter"), Page_Options
));
49 setPage(Page_Helictrl
, new HeliPage(this, "helictrl", tr("Helicopter"), tr("Select the controls for your helicopter"), Page_Options
));
50 setPage(Page_Multirotor
, new MultirotorPage(this, "multirotor", tr("Multirotor"), tr("Select the control channels for your multirotor"), Page_Options
));
51 setPage(Page_Options
, new OptionsPage(this, "options", tr("Model Options"), tr("Select additional options"), Page_Conclusion
));
52 setPage(Page_Conclusion
, new ConclusionPage(this, "conclusion", tr("Save Changes"), tr(
53 "Manually check the direction of each control surface and reverse any channels that make controls move in the wrong direction. "
54 "Remove the propeller/propellers before you try to control your model for the first time.<br>"
55 "Please note that continuing removes all old model settings!"), -1));
56 setStartId(Page_Models
);
58 // Workaround for Qt radio button rendering issue on Mac
59 Q_FOREACH(QAbstractButton
* rb
, findChildren
<QAbstractButton
*>()) {
60 rb
->setAttribute(Qt::WA_LayoutUsesWidgetRect
);
63 setWizardStyle(ModernStyle
);
64 setOption(QWizard::NoCancelButton
, false);
65 setOption(HaveHelpButton
, true);
66 connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp()));
69 void WizardDialog::showHelp()
73 switch (currentId()) {
75 message
= tr("Enter a name for your model and select model type.");
78 message
= tr("Select the receiver channel that is connected to your ESC or throttle servo.<br><br>"
79 "Throttle - Spektrum: CH1, Futaba: CH3");
82 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. "
83 "The main control surface on a standard wing controls the roll of the aircraft. This surface is called an aileron.<br>"
84 "The control surface of a delta wing controls both roll and pitch. This surface is called an elevon. ");
87 message
= tr("Models use one or two channels to control the ailerons.<br>"
88 "A so called Y-cable can be used to connect a single receiver channel to two separate aileron servos. "
89 "If your servos are connected by a Y-cable you should select the single-servo option.<br><br>"
90 "Aileron - Spektrum: CH2, Futaba: CH1");
93 message
= tr("This wizard assumes that your flaps are controlled by a switch. "
94 "If your flaps are controlled by a potentiometer you can change that manually later.");
97 message
= tr("Air brakes are used to reduce the speed of advanced sail planes.<br>"
98 "They are very uncommon on other types of planes.");
101 message
= tr("Models use two channels to control the elevons.<br>"
102 "Select these two channels");
105 message
= tr("Select the receiver channel that is connected to your rudder.<br><br>"
106 "Rudder - Spektrum: CH4, Futaba: CH4");
109 message
= tr("Select the tail type of your plane.");
112 message
= tr("Select the Rudder and Elevator channels.<br><br>"
113 "Rudder - Spektrum: CH4, Futaba: CH4<br>"
114 "Elevator - Spektrum: CH3, Futaba: CH2");
117 message
= tr("Select the Rudder and Elevator channels.<br><br>"
118 "Rudder - Spektrum: CH4, Futaba: CH4<br>"
119 "Elevator - Spektrum: CH3, Futaba: CH2");
121 case Page_Simpletail
:
122 message
= tr("Select the Elevator channel.<br><br>"
123 "Elevator - Spektrum: CH3, Futaba: CH2");
126 message
= tr("TBD.");
129 message
= tr("TBD.");
132 message
= tr("TBD.");
135 message
= tr("TBD.");
138 message
= tr("TBD.");
140 case Page_Multirotor
:
141 message
= tr("Select the control channels for your multirotor.<br><br>"
142 "Throttle - Spektrum: CH1, Futaba: CH3<br>"
143 "Yaw - Spektrum: CH4, Futaba: CH4<br>"
144 "Pitch - Spektrum: CH3, Futaba: CH2<br>"
145 "Roll - Spektrum: CH2, Futaba: CH1");
148 message
= tr("TBD.");
150 case Page_Conclusion
:
151 message
= tr("TBD.");
154 message
= tr("There is no help available for the current page.");
157 QMessageBox::information(this, tr("Model Wizard Help"), message
);
160 StandardPage::StandardPage(WizardPage currentPage
, WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
163 pageCurrent(currentPage
),
164 pageFollower(nextPage
)
167 setPixmap(QWizard::WatermarkPixmap
, QPixmap(QString(":/images/wizard/%1.png").arg(image
)));
168 topLabel
= new QLabel(text
+"<br>");
169 topLabel
->setWordWrap(true);
171 QVBoxLayout
*layout
= new QVBoxLayout
;
172 layout
->addWidget(topLabel
);
176 int StandardPage::getDefaultChannel(const Input input
)
178 return wizDlg
->settings
.getDefaultChannel(input
-1);
181 int StandardPage::nextFreeChannel(int channel
)
183 for(int i
=channel
;i
<8; i
++)
184 if (wizDlg
->mix
.channel
[i
].page
== Page_None
)
189 int StandardPage::totalChannelsAvailable()
192 for(int i
=0; i
<WIZ_MAX_CHANNELS
; i
++)
193 if (wizDlg
->mix
.channel
[i
].page
== Page_None
)
199 void StandardPage::populateCB(QComboBox
*cb
, int preferred
)
203 // Add all unbooked channels and select the preferred one
204 for (int i
=0; i
<WIZ_MAX_CHANNELS
; i
++) {
205 if (wizDlg
->mix
.channel
[i
].page
== Page_None
) {
206 cb
->addItem(tr("Channel %1").arg(i
+1), i
);
207 if (preferred
== i
) {
208 cb
->setCurrentIndex(cb
->count()-1);
212 // Avoid selecting prebooked channels
213 int channel
= cb
->itemData(cb
->currentIndex()).toInt();
214 if (wizDlg
->mix
.channel
[channel
].prebooked
) {
215 for (int i
=cb
->count()-1; i
>=0; i
--){
216 channel
= cb
->itemData(i
).toInt();
217 if (!wizDlg
->mix
.channel
[channel
].prebooked
) {
218 cb
->setCurrentIndex(i
);
223 // Prebook the selected channel
224 channel
= cb
->itemData(cb
->currentIndex()).toInt();
225 wizDlg
->mix
.channel
[channel
].prebooked
= true;
228 bool StandardPage::bookChannel(QComboBox
* cb
, Input input1
, int weight1
, Input input2
, int weight2
)
230 int channel
= cb
->itemData(cb
->currentIndex()).toInt();
231 if (channel
<0 || channel
>=WIZ_MAX_CHANNELS
)
233 if (wizDlg
->mix
.channel
[channel
].page
!= Page_None
)
236 wizDlg
->mix
.channel
[channel
].page
= pageCurrent
;
237 wizDlg
->mix
.channel
[channel
].input1
= input1
;
238 wizDlg
->mix
.channel
[channel
].input2
= input2
;
239 wizDlg
->mix
.channel
[channel
].weight1
= weight1
;
240 wizDlg
->mix
.channel
[channel
].weight2
= weight2
;
245 void StandardPage::releaseBookings()
247 for (int i
=0; i
<WIZ_MAX_CHANNELS
; i
++) {
248 if (wizDlg
->mix
.channel
[i
].page
== pageCurrent
) {
249 wizDlg
->mix
.channel
[i
].clear();
254 void StandardPage::releasePreBookings()
256 for (int i
=0; i
<WIZ_MAX_CHANNELS
; i
++) {
257 wizDlg
->mix
.channel
[i
].prebooked
= false;
261 void StandardPage::initializePage()
263 releasePreBookings(); // All prebookings are void after page has initialized
266 void StandardPage::cleanupPage()
271 int StandardPage::nextId() const
276 ModelSelectionPage::ModelSelectionPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
)
277 : StandardPage(Page_Models
, dlg
, image
, title
, text
)
279 nameLineEdit
= new QLineEdit
;
280 planeRB
= new QRadioButton(tr("Plane"));
281 planeRB
->setChecked(true);
282 multirotorRB
= new QRadioButton(tr("Multirotor"));
283 helicopterRB
= new QRadioButton(tr("Helicopter"));
284 helicopterRB
->setDisabled(true); //TODO REMOVE TO ENABLE HELICOPTERS
286 registerField("evaluate.name*", nameLineEdit
);
288 QLayout
*l
= layout();
289 l
->addWidget(new QLabel(tr("Model Name:")));
290 l
->addWidget(nameLineEdit
);
291 l
->addWidget(new QLabel(""));
292 l
->addWidget(new QLabel(tr("Model Type:")));
293 l
->addWidget(planeRB
);
294 l
->addWidget(multirotorRB
);
295 l
->addWidget(helicopterRB
);
298 void ModelSelectionPage::initializePage()
300 nameLineEdit
->setText(wizDlg
->mix
.name
);
303 bool ModelSelectionPage::validatePage()
305 //Filter and insert model name in mix data
306 QString
newName(nameLineEdit
->text());
307 newName
= (newName
.normalized(QString::NormalizationForm_D
));
308 newName
= newName
.replace(QRegExp("[^ A-Za-z0-9_.-,\\s]"), "");
309 strncpy( wizDlg
->mix
.name
, newName
.toLatin1(), WIZ_MODEL_NAME_LENGTH
);
310 wizDlg
->mix
.name
[WIZ_MODEL_NAME_LENGTH
] = 0;
312 if (multirotorRB
->isChecked())
313 wizDlg
->mix
.vehicle
= MULTICOPTER
;
314 else if (helicopterRB
->isChecked())
315 wizDlg
->mix
.vehicle
= HELICOPTER
;
317 wizDlg
->mix
.vehicle
= PLANE
;
321 int ModelSelectionPage::nextId() const
323 if (helicopterRB
->isChecked())
325 else if (multirotorRB
->isChecked())
326 return Page_Multirotor
;
328 return Page_Throttle
;
331 WingtypeSelectionPage::WingtypeSelectionPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
)
332 : StandardPage(Page_Wingtypes
, dlg
, image
, title
, text
)
334 standardWingRB
= new QRadioButton(tr("Standard Wing"));
335 standardWingRB
->setChecked(true);
336 deltaWingRB
= new QRadioButton(tr("Flying Wing / Deltawing"));
338 QLayout
*l
= layout();
339 l
->addWidget(standardWingRB
);
340 l
->addWidget(deltaWingRB
);
343 int WingtypeSelectionPage::nextId() const
345 if (deltaWingRB
->isChecked())
348 return Page_Ailerons
;
351 TailSelectionPage::TailSelectionPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
)
352 : StandardPage(Page_Tails
, dlg
, image
, title
, text
)
354 standardTailRB
= new QRadioButton(tr("Elevator and Rudder"));
355 standardTailRB
->setChecked(true);
356 simpleTailRB
= new QRadioButton(tr("Only Elevator"));
357 vTailRB
= new QRadioButton(tr("V-tail"));
359 QLayout
*l
= layout();
360 l
->addWidget(new QLabel(tr("Tail Type:")));
361 l
->addWidget(standardTailRB
);
362 l
->addWidget(simpleTailRB
);
363 l
->addWidget(vTailRB
);
366 int TailSelectionPage::nextId() const
368 if (simpleTailRB
->isChecked())
369 return Page_Simpletail
;
370 else if (vTailRB
->isChecked())
376 FlybarSelectionPage::FlybarSelectionPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
)
377 : StandardPage(Page_Flybar
, dlg
, image
, title
, text
)
379 flybarRB
= new QRadioButton(tr("Has Flybar"));
380 flybarRB
->setChecked(true);
381 noFlybarRB
= new QRadioButton(tr("Flybarless"));
383 QLayout
*l
= layout();
384 l
->addWidget(new QLabel(tr("Flybar:")));
385 l
->addWidget(flybarRB
);
386 l
->addWidget(noFlybarRB
);
389 int FlybarSelectionPage::nextId() const
391 if (flybarRB
->isChecked())
392 return Page_Helictrl
;
397 ThrottlePage::ThrottlePage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
)
398 : StandardPage(Page_Throttle
, dlg
, image
, title
, text
, nextPage
)
400 motorRB
= new QRadioButton(tr("Yes"));
401 noMotorRB
= new QRadioButton(tr("No"));
402 motorRB
->setChecked(true);
403 throttleCB
= new QComboBox();
405 QLayout
*l
= layout();
406 l
->addWidget(motorRB
);
407 l
->addWidget(noMotorRB
);
408 l
->addWidget(new QLabel(tr("<br>Throttle Channel:")));
409 l
->addWidget(throttleCB
);
411 connect(motorRB
, SIGNAL(toggled(bool)), this, SLOT(onMotorStateChanged(bool)));
414 void ThrottlePage::initializePage()
416 populateCB(throttleCB
, getDefaultChannel(THROTTLE_INPUT
));
417 StandardPage::initializePage();
420 bool ThrottlePage::validatePage()
423 if (motorRB
->isChecked())
424 return bookChannel(throttleCB
, THROTTLE_INPUT
, 100);
429 void ThrottlePage::onMotorStateChanged(bool toggled
)
431 throttleCB
->setEnabled(toggled
);
434 AileronsPage::AileronsPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
)
435 : StandardPage(Page_Ailerons
, dlg
, image
, title
, text
, nextPage
)
437 noAileronsRB
= new QRadioButton(tr("No"));
438 oneAileronRB
= new QRadioButton(tr("Yes, controlled by a single channel"));
439 twoAileronsRB
= new QRadioButton(tr("Yes, controlled by two channels"));
440 noAileronsRB
->setChecked(true);
442 aileron1CB
= new QComboBox();
443 aileron2CB
= new QComboBox();
444 aileron1CB
->setEnabled(false);
445 aileron2CB
->setEnabled(false);
447 QLayout
*l
= layout();
448 l
->addWidget(noAileronsRB
);
449 l
->addWidget(oneAileronRB
);
450 l
->addWidget(twoAileronsRB
);
451 l
->addWidget(new QLabel(tr("<br>First Aileron Channel:")));
452 l
->addWidget(aileron1CB
);
453 l
->addWidget(new QLabel(tr("Second Aileron Channel:")));
454 l
->addWidget(aileron2CB
);
456 connect(noAileronsRB
, SIGNAL(toggled(bool)), this, SLOT(noAileronChannel()));
457 connect(oneAileronRB
, SIGNAL(toggled(bool)), this, SLOT(oneAileronChannel()));
458 connect(twoAileronsRB
, SIGNAL(toggled(bool)), this, SLOT(twoAileronChannels()));
461 void AileronsPage::initializePage()
463 populateCB(aileron1CB
, getDefaultChannel(AILERONS_INPUT
));
464 populateCB(aileron2CB
, nextFreeChannel(4));
465 StandardPage::initializePage();
468 bool AileronsPage::validatePage()
471 if (noAileronsRB
->isChecked()) {
474 if (oneAileronRB
->isChecked()) {
475 return (bookChannel(aileron1CB
, AILERONS_INPUT
, 100 ));
477 return( bookChannel(aileron1CB
, AILERONS_INPUT
, 100 ) &&
478 bookChannel(aileron2CB
, AILERONS_INPUT
, -100 ));
481 void AileronsPage::noAileronChannel()
483 aileron1CB
->setEnabled(false);
484 aileron2CB
->setEnabled(false);
487 void AileronsPage::oneAileronChannel()
489 aileron1CB
->setEnabled(true);
490 aileron2CB
->setEnabled(false);
493 void AileronsPage::twoAileronChannels()
495 aileron1CB
->setEnabled(true);
496 aileron2CB
->setEnabled(true);
499 FlapsPage::FlapsPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
500 StandardPage(Page_Flaps
, dlg
, image
, title
, text
, nextPage
)
502 noFlapsRB
= new QRadioButton(tr("No"));
503 oneFlapRB
= new QRadioButton(tr("Yes, controlled by a single channel"));
504 twoFlapsRB
= new QRadioButton(tr("Yes, controlled by two channels"));
505 noFlapsRB
->setChecked(true);
507 flap1CB
= new QComboBox();
508 flap2CB
= new QComboBox();
509 flap1CB
->setEnabled(false);
510 flap2CB
->setEnabled(false);
512 QLayout
*l
= layout();
513 l
->addWidget(noFlapsRB
);
514 l
->addWidget(oneFlapRB
);
515 l
->addWidget(twoFlapsRB
);
516 l
->addWidget(new QLabel(tr("<br>First Flap Channel:")));
517 l
->addWidget(flap1CB
);
518 l
->addWidget(new QLabel(tr("Second Flap Channel:")));
519 l
->addWidget(flap2CB
);
521 connect(noFlapsRB
, SIGNAL(toggled(bool)), this, SLOT(noFlapChannel()));
522 connect(oneFlapRB
, SIGNAL(toggled(bool)), this, SLOT(oneFlapChannel()));
523 connect(twoFlapsRB
, SIGNAL(toggled(bool)), this, SLOT(twoFlapChannels()));
526 void FlapsPage::initializePage()
528 populateCB(flap1CB
, nextFreeChannel(4));
529 populateCB(flap2CB
, nextFreeChannel(4));
530 StandardPage::initializePage();
533 bool FlapsPage::validatePage() {
535 if (noFlapsRB
->isChecked()) {
538 if (oneFlapRB
->isChecked()) {
539 return (bookChannel(flap1CB
, FLAPS_INPUT
, 100 ));
541 return( bookChannel(flap1CB
, FLAPS_INPUT
, 100 ) &&
542 bookChannel(flap2CB
, FLAPS_INPUT
, 100 ));
545 void FlapsPage::noFlapChannel()
547 flap1CB
->setEnabled(false);
548 flap2CB
->setEnabled(false);
551 void FlapsPage::oneFlapChannel()
553 flap1CB
->setEnabled(true);
554 flap2CB
->setEnabled(false);
557 void FlapsPage::twoFlapChannels()
559 flap1CB
->setEnabled(true);
560 flap2CB
->setEnabled(true);
563 AirbrakesPage::AirbrakesPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
564 StandardPage(Page_Airbrakes
, dlg
, image
, title
, text
, nextPage
)
566 noAirbrakesRB
= new QRadioButton(tr("No"));
567 oneAirbrakeRB
= new QRadioButton(tr("Yes, controlled by a single channel"));
568 twoAirbrakesRB
= new QRadioButton(tr("Yes, controlled by two channels"));
569 noAirbrakesRB
->setChecked(true);
571 airbrake1CB
= new QComboBox();
572 airbrake2CB
= new QComboBox();
573 airbrake1CB
->setEnabled(false);
574 airbrake2CB
->setEnabled(false);
576 QLayout
*l
= layout();
577 l
->addWidget(noAirbrakesRB
);
578 l
->addWidget(oneAirbrakeRB
);
579 l
->addWidget(twoAirbrakesRB
);
580 l
->addWidget(new QLabel(tr("<br>First Airbrake Channel:")));
581 l
->addWidget(airbrake1CB
);
582 l
->addWidget(new QLabel(tr("Second Airbrake Channel:")));
583 l
->addWidget(airbrake2CB
);
585 connect(noAirbrakesRB
, SIGNAL(toggled(bool)), this, SLOT(noAirbrakeChannel()));
586 connect(oneAirbrakeRB
, SIGNAL(toggled(bool)), this, SLOT(oneAirbrakeChannel()));
587 connect(twoAirbrakesRB
, SIGNAL(toggled(bool)), this, SLOT(twoAirbrakeChannels()));
590 void AirbrakesPage::initializePage()
592 populateCB(airbrake1CB
, nextFreeChannel(4));
593 populateCB(airbrake2CB
, nextFreeChannel(4));
594 StandardPage::initializePage();
597 bool AirbrakesPage::validatePage()
600 if (noAirbrakesRB
->isChecked()) {
603 if (oneAirbrakeRB
->isChecked()) {
604 return (bookChannel(airbrake1CB
, AIRBRAKES_INPUT
, 100 ));
606 return( bookChannel(airbrake1CB
, AIRBRAKES_INPUT
, 100 ) &&
607 bookChannel(airbrake2CB
, AIRBRAKES_INPUT
, 100 ));
610 void AirbrakesPage::noAirbrakeChannel()
612 airbrake1CB
->setEnabled(false);
613 airbrake2CB
->setEnabled(false);
616 void AirbrakesPage::oneAirbrakeChannel()
618 airbrake1CB
->setEnabled(true);
619 airbrake2CB
->setEnabled(false);
622 void AirbrakesPage::twoAirbrakeChannels()
624 airbrake1CB
->setEnabled(true);
625 airbrake2CB
->setEnabled(true);
628 ElevonsPage::ElevonsPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
629 StandardPage(Page_Elevons
, dlg
, image
, title
, text
, nextPage
)
631 elevon1CB
= new QComboBox();
632 elevon2CB
= new QComboBox();
634 QLayout
*l
= layout();
635 l
->addWidget(new QLabel(tr("<br>First Elevon Channel:")));
636 l
->addWidget(elevon1CB
);
637 l
->addWidget(new QLabel(tr("Second Elevon Channel:")));
638 l
->addWidget(elevon2CB
);
641 void ElevonsPage::initializePage()
643 populateCB(elevon1CB
, getDefaultChannel(ELEVATOR_INPUT
));
644 populateCB(elevon2CB
, getDefaultChannel(AILERONS_INPUT
));
645 StandardPage::initializePage();
648 bool ElevonsPage::validatePage()
651 return (bookChannel(elevon1CB
, AILERONS_INPUT
, 50, ELEVATOR_INPUT
, 50) &&
652 bookChannel(elevon2CB
, AILERONS_INPUT
, -50, ELEVATOR_INPUT
, 50));
655 RudderPage::RudderPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
656 StandardPage(Page_Rudder
, dlg
, image
, title
, text
, nextPage
)
658 noRudderRB
= new QRadioButton(tr("No"));
659 hasRudderRB
= new QRadioButton(tr("Yes"));
660 noRudderRB
->setChecked(true);
662 rudderCB
= new QComboBox();
663 rudderCB
->setEnabled(false);
665 QLayout
*l
= layout();
666 l
->addWidget(noRudderRB
);
667 l
->addWidget(hasRudderRB
);
668 l
->addWidget(new QLabel(tr("<br>Rudder Channel:")));
669 l
->addWidget(rudderCB
);
670 connect(noRudderRB
, SIGNAL(toggled(bool)), this, SLOT(noRudder()));
671 connect(hasRudderRB
, SIGNAL(toggled(bool)), this, SLOT(hasRudder()));
674 void RudderPage::initializePage()
676 populateCB(rudderCB
, getDefaultChannel(RUDDER_INPUT
));
677 StandardPage::initializePage();
680 bool RudderPage::validatePage() {
682 if (noRudderRB
->isChecked())
685 return (bookChannel(rudderCB
, RUDDER_INPUT
, 100));
688 void RudderPage::noRudder()
690 rudderCB
->setEnabled(false);
693 void RudderPage::hasRudder()
695 rudderCB
->setEnabled(true);
698 VTailPage::VTailPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
)
699 : StandardPage(Page_Tail
, dlg
, image
, title
, text
, nextPage
)
701 tail1CB
= new QComboBox();
702 tail2CB
= new QComboBox();
704 QLayout
*l
= layout();
705 l
->addWidget(new QLabel(tr("First Tail Channel:")));
706 l
->addWidget(tail1CB
);
707 l
->addWidget(new QLabel(tr("Second Tail Channel:")));
708 l
->addWidget(tail2CB
);
711 void VTailPage::initializePage()
713 populateCB(tail1CB
, getDefaultChannel(ELEVATOR_INPUT
));
714 populateCB(tail2CB
, getDefaultChannel(AILERONS_INPUT
));
715 StandardPage::initializePage();
718 bool VTailPage::validatePage()
721 return (bookChannel(tail1CB
, ELEVATOR_INPUT
, 50, RUDDER_INPUT
, 50) &&
722 bookChannel(tail2CB
, ELEVATOR_INPUT
, 50, RUDDER_INPUT
, -50 ));
725 TailPage::TailPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
726 StandardPage(Page_Tail
, dlg
, image
, title
, text
, nextPage
)
728 elevatorCB
= new QComboBox();
729 rudderCB
= new QComboBox();
732 l
->addWidget(new QLabel(tr("Rudder Channel:")));
733 l
->addWidget(rudderCB
);
734 l
->addWidget(new QLabel(tr("Elevator Channel:")));
735 l
->addWidget(elevatorCB
);
740 void TailPage::initializePage()
742 populateCB(elevatorCB
, getDefaultChannel(ELEVATOR_INPUT
));
743 populateCB(rudderCB
, getDefaultChannel(RUDDER_INPUT
));
744 StandardPage::initializePage();
746 if (totalChannelsAvailable() < 2) {
747 errorMessage
= new QLabel(tr("Only one channel still available!<br>"
748 "You probably should configure your model without using the wizard."));
749 errorMessage
->setStyleSheet("QLabel { color : red; }");
750 l
->addWidget(errorMessage
);
754 bool TailPage::validatePage()
757 return( bookChannel(elevatorCB
, ELEVATOR_INPUT
, 100) &&
758 bookChannel(rudderCB
, RUDDER_INPUT
, 100));
761 void TailPage::cleanupPage()
765 l
->removeWidget(errorMessage
);
769 StandardPage::cleanupPage();
772 SimpleTailPage::SimpleTailPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
)
773 : StandardPage(Page_Simpletail
, dlg
, image
, title
, text
, nextPage
)
775 elevatorCB
= new QComboBox();
777 QLayout
*l
= layout();
778 l
->addWidget(new QLabel(tr("Elevator Channel:")));
779 l
->addWidget(elevatorCB
);
782 void SimpleTailPage::initializePage()
784 populateCB(elevatorCB
, getDefaultChannel(ELEVATOR_INPUT
));
785 StandardPage::initializePage();
788 bool SimpleTailPage::validatePage()
791 return( bookChannel(elevatorCB
, ELEVATOR_INPUT
, 100 ));
794 CyclicPage::CyclicPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
795 StandardPage(Page_Cyclic
, dlg
, image
, title
, text
, nextPage
)
797 cyclic90RB
= new QRadioButton(tr("90"));
798 cyclic90RB
->setChecked(true);
799 cyclic120RB
= new QRadioButton(tr("120"));
800 cyclic120XRB
= new QRadioButton(tr("120x"));
801 cyclic140RB
= new QRadioButton(tr("140"));
803 QLayout
*l
= layout();
804 l
->addWidget(cyclic90RB
);
805 l
->addWidget(cyclic120RB
);
806 l
->addWidget(cyclic120XRB
);
807 l
->addWidget(cyclic140RB
);
810 void CyclicPage::initializePage()
812 StandardPage::initializePage();
815 bool CyclicPage::validatePage()
821 GyroPage::GyroPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
822 StandardPage(Page_Gyro
, dlg
, image
, title
, text
, nextPage
)
824 noGyroRB
= new QRadioButton(tr("No"));
825 noGyroRB
->setChecked(true);
826 switchGyroRB
= new QRadioButton(tr("Yes, controled by a switch"));
827 potGyroRB
= new QRadioButton(tr("Yes, controlled by a pot"));
829 QLayout
*l
= layout();
830 l
->addWidget(noGyroRB
);
831 l
->addWidget(switchGyroRB
);
832 l
->addWidget(potGyroRB
);
835 void GyroPage::initializePage()
837 StandardPage::initializePage();
840 bool GyroPage::validatePage() {
845 FblPage::FblPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
846 StandardPage(Page_Fblheli
, dlg
, image
, title
, text
, nextPage
)
848 throttleCB
= new QComboBox();
849 yawCB
= new QComboBox();
850 pitchCB
= new QComboBox();
851 rollCB
= new QComboBox();
853 QLayout
*l
= layout();
854 l
->addWidget(new QLabel(tr("Throttle Channel:")));
855 l
->addWidget(throttleCB
);
856 l
->addWidget(new QLabel(tr("Yaw Channel:")));
858 l
->addWidget(new QLabel(tr("Pitch Channel:")));
859 l
->addWidget(pitchCB
);
860 l
->addWidget(new QLabel(tr("Roll Channel:")));
861 l
->addWidget(rollCB
);
864 void FblPage::initializePage()
866 populateCB(throttleCB
, getDefaultChannel(THROTTLE_INPUT
));
867 populateCB(yawCB
, getDefaultChannel(RUDDER_INPUT
));
868 populateCB(pitchCB
, getDefaultChannel(ELEVATOR_INPUT
));
869 populateCB(rollCB
, getDefaultChannel(AILERONS_INPUT
));
870 StandardPage::initializePage();
873 bool FblPage::validatePage()
876 return( bookChannel(throttleCB
, THROTTLE_INPUT
, 100 ) &&
877 bookChannel( yawCB
, RUDDER_INPUT
, 100 ) &&
878 bookChannel( pitchCB
, ELEVATOR_INPUT
, 100 ) &&
879 bookChannel( rollCB
, AILERONS_INPUT
, 100 ));
882 HeliPage::HeliPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
883 StandardPage(Page_Helictrl
, dlg
, image
, title
, text
, nextPage
)
885 throttleCB
= new QComboBox();
886 yawCB
= new QComboBox();
887 pitchCB
= new QComboBox();
888 rollCB
= new QComboBox();
890 QLayout
*l
= layout();
891 l
->addWidget(new QLabel(tr("Throttle Channel:")));
892 l
->addWidget(throttleCB
);
893 l
->addWidget(new QLabel(tr("Yaw Channel:")));
895 l
->addWidget(new QLabel(tr("Pitch Channel:")));
896 l
->addWidget(pitchCB
);
897 l
->addWidget(new QLabel(tr("Roll Channel:")));
898 l
->addWidget(rollCB
);
901 void HeliPage::initializePage()
903 populateCB(throttleCB
, getDefaultChannel(THROTTLE_INPUT
));
904 populateCB(yawCB
, getDefaultChannel(RUDDER_INPUT
));
905 populateCB(pitchCB
, getDefaultChannel(ELEVATOR_INPUT
));
906 populateCB(rollCB
, getDefaultChannel(AILERONS_INPUT
));
907 StandardPage::initializePage();
910 bool HeliPage::validatePage()
913 return( bookChannel(throttleCB
, THROTTLE_INPUT
, 100 ) &&
914 bookChannel( yawCB
, RUDDER_INPUT
, 100 ) &&
915 bookChannel( pitchCB
, ELEVATOR_INPUT
, 100 ) &&
916 bookChannel( rollCB
, AILERONS_INPUT
, 100 ));
919 MultirotorPage::MultirotorPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
920 StandardPage(Page_Multirotor
, dlg
, image
, title
, text
, nextPage
)
922 throttleCB
= new QComboBox();
923 yawCB
= new QComboBox();
924 pitchCB
= new QComboBox();
925 rollCB
= new QComboBox();
927 QLayout
*l
= layout();
928 l
->addWidget(new QLabel(tr("Throttle Channel:")));
929 l
->addWidget(throttleCB
);
930 l
->addWidget(new QLabel(tr("Yaw Channel:")));
932 l
->addWidget(new QLabel(tr("Pitch Channel:")));
933 l
->addWidget(pitchCB
);
934 l
->addWidget(new QLabel(tr("Roll Channel:")));
935 l
->addWidget(rollCB
);
938 void MultirotorPage::initializePage()
940 populateCB(throttleCB
, getDefaultChannel(THROTTLE_INPUT
));
941 populateCB(yawCB
, getDefaultChannel(RUDDER_INPUT
));
942 populateCB(pitchCB
, getDefaultChannel(ELEVATOR_INPUT
));
943 populateCB(rollCB
, getDefaultChannel(AILERONS_INPUT
));
944 StandardPage::initializePage();
947 bool MultirotorPage::validatePage()
950 return( bookChannel(throttleCB
, THROTTLE_INPUT
, 100 ) &&
951 bookChannel(yawCB
, RUDDER_INPUT
, 100 ) &&
952 bookChannel(pitchCB
, ELEVATOR_INPUT
, 100 ) &&
953 bookChannel(rollCB
, AILERONS_INPUT
, 100 ));
956 OptionsPage::OptionsPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
):
957 StandardPage(Page_Options
, dlg
, image
, title
, text
, nextPage
)
959 throttleCutRB
= new QCheckBox(tr("Throttle Cut"));
960 throttleTimerRB
= new QCheckBox(tr("Throttle Timer"));
961 flightTimerRB
= new QCheckBox(tr("Flight Timer"));
963 QLayout
*l
= layout();
964 l
->addWidget(throttleCutRB
);
965 l
->addWidget(throttleTimerRB
);
966 l
->addWidget(flightTimerRB
);
969 void OptionsPage::initializePage(){
970 StandardPage::initializePage();
973 bool OptionsPage::validatePage(){
974 wizDlg
->mix
.options
[THROTTLE_CUT_OPTION
] = throttleCutRB
->isChecked();
975 wizDlg
->mix
.options
[THROTTLE_TIMER_OPTION
] = throttleTimerRB
->isChecked();
976 wizDlg
->mix
.options
[FLIGHT_TIMER_OPTION
] = flightTimerRB
->isChecked();
980 ConclusionPage::ConclusionPage(WizardDialog
*dlg
, QString image
, QString title
, QString text
, int nextPage
)
981 : StandardPage(Page_Conclusion
, dlg
, image
, title
, text
, nextPage
)
983 textLabel
= new QLabel();
984 proceedCB
= new QCheckBox(tr("OK, I understand."));
985 registerField("evaluate.proceed*", proceedCB
);
987 QLayout
*l
= layout();
988 l
->addWidget(textLabel
);
989 l
->addWidget(proceedCB
);
992 void ConclusionPage::initializePage()
994 WizardPrinter
p(&wizDlg
->mix
);
995 textLabel
->setText(p
.print());
996 StandardPage::initializePage();
999 bool ConclusionPage::validatePage()
1001 wizDlg
->mix
.complete
= true;
1006 QString
WizardPrinter::inputName(Input input
)
1009 case THROTTLE_INPUT
:
1013 case ELEVATOR_INPUT
:
1015 case AILERONS_INPUT
:
1019 case AIRBRAKES_INPUT
:
1026 QString
WizardPrinter::vehicleName(Vehicle vehicle
)
1032 return tr("Multicopter");
1034 return tr("Helicopter");
1040 WizardPrinter::WizardPrinter(WizMix
*wizMix
)
1045 QString
WizardPrinter::printChannel( Input input1
, int weight1
, Input input2
, int weight2
)
1048 str
= QString("[%1, %2]").arg(inputName(input1
)).arg(weight1
);
1049 if ( input2
!= NO_INPUT
)
1050 str
+= QString("[%1, %2]").arg(inputName(input2
)).arg(weight2
);
1054 QString
WizardPrinter::print()
1056 QString str
= tr("Model Name: ") + mix
->name
+ "\n";
1057 str
+= tr("Model Type: ") + vehicleName(mix
->vehicle
) + "\n";
1059 str
+= tr("Options: ") + "[";
1060 for (int i
=0; i
<WIZ_MAX_OPTIONS
; i
++) {
1061 if (mix
->options
[i
])
1066 str
+= QString("]") + "\n";
1068 for (int i
=0; i
<WIZ_MAX_CHANNELS
; i
++) {
1069 if (mix
->channel
[i
].page
!= Page_None
) {
1070 Channel ch
= mix
->channel
[i
];
1071 str
+= tr("Channel %1: ").arg(i
+1);
1072 str
+= printChannel(ch
.input1
, ch
.weight1
, ch
.input2
, ch
.weight2
);
1073 str
+= QString("\n");