removed PrefixPath debug line
[opentx.git] / companion / src / wizarddialog.cpp
blobad46d1fb05f621cdce442aee1b592f9069d44882
1 /*
2 * Author - Kjell Kernen
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <QtGui>
16 #include "wizarddialog.h"
17 #include "wizarddata.h"
18 #include "helpers.h"
20 WizardDialog::WizardDialog(const GeneralSettings & settings, unsigned int modelId, QWidget *parent):
21 QWizard(parent),
22 mix(settings, modelId),
23 settings(settings)
25 setWindowIcon(CompanionIcon("wizard.png"));
26 setWindowTitle(tr("Model Wizard"));
28 setPage(Page_Models, new ModelSelectionPage(this, "models", tr("Model Type"), tr("Enter model name and model type.")));
29 setPage(Page_Throttle, new ThrottlePage(this, "throttle", tr("Throttle"), tr("Has your model got a motor or an engine?"), Page_Wingtypes));
30 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?")));
31 setPage(Page_Ailerons, new AileronsPage(this, "ailerons", tr("Ailerons"), tr("Has your model got ailerons?"), Page_Flaps));
32 setPage(Page_Flaps, new FlapsPage(this, "flaps", tr("Flaps"), tr("Has your model got flaps?"), Page_Airbrakes));
33 setPage(Page_Airbrakes, new AirbrakesPage(this, "airbrakes", tr("Airbrakes"), tr("Has your model got airbrakes?"), Page_Tails));
34 setPage(Page_Elevons, new ElevonsPage(this, "elevons", tr("Flying-wing / Delta-wing"), tr("Select the elevons channels"), Page_Rudder));
35 setPage(Page_Rudder, new RudderPage(this, "rudder", tr("Rudder"), tr("Does your model have a rudder?"), Page_Options));
36 setPage(Page_Tails, new TailSelectionPage(this, "tails", tr("Tail Type"), tr("Select which type of tail your model is equiped with.")));
37 setPage(Page_Tail, new TailPage(this, "tail", tr("Tail"), tr("Select channels for tail control."), Page_Options));
38 setPage(Page_Vtail, new VTailPage(this, "vtail", tr("V-Tail"), tr("Select channels for tail control."), Page_Options));
39 setPage(Page_Simpletail, new SimpleTailPage(this, "simpletail", tr("Tail"), tr("Select elevator channel."), Page_Options));
40 setPage(Page_Cyclic, new CyclicPage(this, "cyclic", tr("Cyclic"), tr("Which type of swash control is installed in your helicopter?"), Page_Gyro));
41 setPage(Page_Gyro, new GyroPage(this, "gyro", tr("Tail Gyro"), tr("Has your helicopter got an adjustable gyro for the tail?"), Page_Flybar));
42 setPage(Page_Flybar, new FlybarSelectionPage(this, "flybar", tr("Rotor Type"), tr("Has your helicopter got a flybar?")));
43 setPage(Page_Fblheli, new FblPage(this, "fblheli", tr("Helicopter"), tr("Select the controls for your helicopter"), Page_Options));
44 setPage(Page_Helictrl, new HeliPage(this, "helictrl", tr("Helicopter"), tr("Select the controls for your helicopter"), Page_Options));
45 setPage(Page_Multirotor, new MultirotorPage(this, "multirotor", tr("Multirotor"), tr("Select the control channels for your multirotor"), Page_Options));
46 setPage(Page_Options, new OptionsPage(this, "options", tr("Model Options"), tr("Select additional options"), Page_Conclusion));
47 setPage(Page_Conclusion, new ConclusionPage(this, "conclusion", tr("Save Changes"), tr(
48 "Manually check the direction of each control surface and reverse any channels that make controls move in the wrong direction. "
49 "Remove the propeller/propellers before you try to control your model for the first time.<br>"
50 "Please note that continuing removes all old model settings!"), -1));
51 setStartId(Page_Models);
53 // Workaround for Qt radio button rendering issue on Mac
54 Q_FOREACH(QAbstractButton * rb, findChildren<QAbstractButton *>()) {
55 rb->setAttribute(Qt::WA_LayoutUsesWidgetRect);
58 setWizardStyle(ModernStyle);
59 setOption(QWizard::NoCancelButton, false);
60 setOption(HaveHelpButton, true);
61 connect(this, SIGNAL(helpRequested()), this, SLOT(showHelp()));
64 void WizardDialog::showHelp()
66 QString message;
68 switch (currentId()) {
69 case Page_Models:
70 message = tr("Enter a name for your model and select model type.");
71 break;
72 case Page_Throttle:
73 message = tr("Select the receiver channel that is connected to your ESC or throttle servo.<br><br>"
74 "Throttle - Spektrum: CH1, Futaba: CH3");
75 break;
76 case Page_Wingtypes:
77 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. "
78 "The main control surface on a standard wing controls the roll of the aircraft. This surface is called an aileron.<br>"
79 "The control surface of a delta wing controls both roll and pitch. This surface is called an elevon. ");
80 break;
81 case Page_Ailerons:
82 message = tr("Models use one or two channels to control the ailerons.<br>"
83 "A so called Y-cable can be used to connect a single receiver channel to two separate aileron servos. "
84 "If your servos are connected by a Y-cable you should select the single-servo option.<br><br>"
85 "Aileron - Spektrum: CH2, Futaba: CH1");
86 break;
87 case Page_Flaps:
88 message = tr("This wizard assumes that your flaps are controlled by a switch. "
89 "If your flaps are controlled by a potentiometer you can change that manually later.");
90 break;
91 case Page_Airbrakes:
92 message = tr("Air brakes are used to reduce the speed of advanced sail planes.<br>"
93 "They are very uncommon on other types of planes.");
94 break;
95 case Page_Elevons:
96 message = tr("Models use two channels to control the elevons.<br>"
97 "Select these two channels");
98 break;
99 case Page_Rudder:
100 message = tr("Select the receiver channel that is connected to your rudder.<br><br>"
101 "Rudder - Spektrum: CH4, Futaba: CH4");
102 break;
103 case Page_Tails:
104 message = tr("Select the tail type of your plane.");
105 break;
106 case Page_Tail:
107 message = tr("Select the Rudder and Elevator channels.<br><br>"
108 "Rudder - Spektrum: CH4, Futaba: CH4<br>"
109 "Elevator - Spektrum: CH3, Futaba: CH2");
110 break;
111 case Page_Vtail:
112 message = tr("Select the Rudder and Elevator channels.<br><br>"
113 "Rudder - Spektrum: CH4, Futaba: CH4<br>"
114 "Elevator - Spektrum: CH3, Futaba: CH2");
115 break;
116 case Page_Simpletail:
117 message = tr("Select the Elevator channel.<br><br>"
118 "Elevator - Spektrum: CH3, Futaba: CH2");
119 break;
120 case Page_Flybar:
121 message = tr("TBD.");
122 break;
123 case Page_Cyclic:
124 message = tr("TBD.");
125 break;
126 case Page_Gyro:
127 message = tr("TBD.");
128 break;
129 case Page_Fblheli:
130 message = tr("TBD.");
131 break;
132 case Page_Helictrl:
133 message = tr("TBD.");
134 break;
135 case Page_Multirotor:
136 message = tr("Select the control channels for your multirotor.<br><br>"
137 "Throttle - Spektrum: CH1, Futaba: CH3<br>"
138 "Yaw - Spektrum: CH4, Futaba: CH4<br>"
139 "Pitch - Spektrum: CH3, Futaba: CH2<br>"
140 "Roll - Spektrum: CH2, Futaba: CH1");
141 break;
142 case Page_Options:
143 message = tr("TBD.");
144 break;
145 case Page_Conclusion:
146 message = tr("TBD.");
147 break;
148 default:
149 message = tr("There is no help available for the current page.");
152 QMessageBox::information(this, tr("Model Wizard Help"), message);
155 StandardPage::StandardPage(WizardPage currentPage, WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
156 QWizardPage(),
157 wizDlg(dlg),
158 pageCurrent(currentPage),
159 pageFollower(nextPage)
161 setTitle(title);
162 setPixmap(QWizard::WatermarkPixmap, QPixmap(QString(":/images/wizard/%1.png").arg(image)));
163 topLabel = new QLabel(text+"<br>");
164 topLabel->setWordWrap(true);
166 QVBoxLayout *layout = new QVBoxLayout;
167 layout->addWidget(topLabel);
168 setLayout(layout);
171 int StandardPage::getDefaultChannel(const Input input)
173 return wizDlg->settings.getDefaultChannel(input-1);
176 int StandardPage::nextFreeChannel(int channel)
178 for(int i=channel;i<8; i++)
179 if (wizDlg->mix.channel[i].page == Page_None)
180 return i;
181 return -1;
184 void StandardPage::populateCB(QComboBox *cb, int preferred)
186 cb->clear();
188 // Add all unbooked channels and select the preferred one
189 for (int i=0; i<WIZ_MAX_CHANNELS; i++) {
190 if (wizDlg->mix.channel[i].page == Page_None) {
191 cb->addItem(tr("Channel %1").arg(i+1), i);
192 if (preferred == i) {
193 cb->setCurrentIndex(cb->count()-1);
197 // Avoid selecting prebooked channels
198 int channel = cb->itemData(cb->currentIndex()).toInt();
199 if (wizDlg->mix.channel[channel].prebooked) {
200 for (int i=cb->count()-1; i>=0; i--){
201 channel = cb->itemData(i).toInt();
202 if (!wizDlg->mix.channel[channel].prebooked) {
203 cb->setCurrentIndex(i);
204 break;
208 // Prebook the selected channel
209 channel = cb->itemData(cb->currentIndex()).toInt();
210 wizDlg->mix.channel[channel].prebooked = true;
213 bool StandardPage::bookChannel(QComboBox * cb, Input input1, int weight1, Input input2, int weight2 )
215 int channel = cb->itemData(cb->currentIndex()).toInt();
216 if (channel<0 || channel>=WIZ_MAX_CHANNELS)
217 return false;
218 if (wizDlg->mix.channel[channel].page != Page_None)
219 return false;
221 wizDlg->mix.channel[channel].page = pageCurrent;
222 wizDlg->mix.channel[channel].input1 = input1;
223 wizDlg->mix.channel[channel].input2 = input2;
224 wizDlg->mix.channel[channel].weight1 = weight1;
225 wizDlg->mix.channel[channel].weight2 = weight2;
227 return true;
230 void StandardPage::releaseBookings()
232 for (int i=0; i<WIZ_MAX_CHANNELS; i++) {
233 if (wizDlg->mix.channel[i].page == pageCurrent) {
234 wizDlg->mix.channel[i].clear();
239 void StandardPage::releasePreBookings()
241 for (int i=0; i<WIZ_MAX_CHANNELS; i++) {
242 wizDlg->mix.channel[i].prebooked = false;
246 void StandardPage::initializePage()
248 releasePreBookings(); // All prebookings are void after page has initialized
251 void StandardPage::cleanupPage()
253 releaseBookings();
256 int StandardPage::nextId() const
258 return pageFollower;
261 ModelSelectionPage::ModelSelectionPage(WizardDialog *dlg, QString image, QString title, QString text)
262 : StandardPage(Page_Models, dlg, image, title, text)
264 nameLineEdit = new QLineEdit;
265 planeRB = new QRadioButton(tr("Plane"));
266 planeRB->setChecked(true);
267 multirotorRB = new QRadioButton(tr("Multirotor"));
268 helicopterRB = new QRadioButton(tr("Helicopter"));
269 helicopterRB->setDisabled(true); //TODO REMOVE TO ENABLE HELICOPTERS
271 registerField("evaluate.name*", nameLineEdit);
273 QLayout *l = layout();
274 l->addWidget(new QLabel(tr("Model Name:")));
275 l->addWidget(nameLineEdit);
276 l->addWidget(new QLabel(""));
277 l->addWidget(new QLabel(tr("Model Type:")));
278 l->addWidget(planeRB);
279 l->addWidget(multirotorRB);
280 l->addWidget(helicopterRB);
283 bool ModelSelectionPage::validatePage()
285 //Filter and insert model name in mix data
286 QString newName(nameLineEdit->text());
287 newName = (newName.normalized(QString::NormalizationForm_D));
288 newName = newName.replace(QRegExp("[^ A-Za-z0-9_.-,\\s]"), "");
289 strncpy( wizDlg->mix.name, newName.toAscii(), WIZ_MODEL_NAME_LENGTH);
290 wizDlg->mix.name[WIZ_MODEL_NAME_LENGTH]=0;
292 if (multirotorRB->isChecked())
293 wizDlg->mix.vehicle = MULTICOPTER;
294 else if (helicopterRB->isChecked())
295 wizDlg->mix.vehicle = HELICOPTER;
296 else
297 wizDlg->mix.vehicle = PLANE;
298 return true;
301 int ModelSelectionPage::nextId() const
303 if (helicopterRB->isChecked())
304 return Page_Cyclic;
305 else if (multirotorRB->isChecked())
306 return Page_Multirotor;
307 else
308 return Page_Throttle;
311 WingtypeSelectionPage::WingtypeSelectionPage(WizardDialog *dlg, QString image, QString title, QString text)
312 : StandardPage(Page_Wingtypes, dlg, image, title, text)
314 standardWingRB = new QRadioButton(tr("Standard Wing"));
315 standardWingRB->setChecked(true);
316 deltaWingRB = new QRadioButton(tr("Flying Wing / Deltawing"));
318 QLayout *l = layout();
319 l->addWidget(standardWingRB);
320 l->addWidget(deltaWingRB);
323 int WingtypeSelectionPage::nextId() const
325 if (deltaWingRB->isChecked())
326 return Page_Elevons;
327 else
328 return Page_Ailerons;
331 TailSelectionPage::TailSelectionPage(WizardDialog *dlg, QString image, QString title, QString text)
332 : StandardPage(Page_Tails, dlg, image, title, text)
334 standardTailRB = new QRadioButton(tr("Elevator and Rudder"));
335 standardTailRB->setChecked(true);
336 simpleTailRB = new QRadioButton(tr("Only Elevator"));
337 vTailRB = new QRadioButton(tr("V-tail"));
339 QLayout *l = layout();
340 l->addWidget(new QLabel(tr("Tail Type:")));
341 l->addWidget(standardTailRB);
342 l->addWidget(simpleTailRB);
343 l->addWidget(vTailRB);
346 int TailSelectionPage::nextId() const
348 if (simpleTailRB->isChecked())
349 return Page_Simpletail;
350 else if (vTailRB->isChecked())
351 return Page_Vtail;
352 else
353 return Page_Tail;
356 FlybarSelectionPage::FlybarSelectionPage(WizardDialog *dlg, QString image, QString title, QString text)
357 : StandardPage(Page_Flybar, dlg, image, title, text)
359 flybarRB = new QRadioButton(tr("Has Flybar"));
360 flybarRB->setChecked(true);
361 noFlybarRB = new QRadioButton(tr("Flybarless"));
363 QLayout *l = layout();
364 l->addWidget(new QLabel(tr("Flybar:")));
365 l->addWidget(flybarRB);
366 l->addWidget(noFlybarRB);
369 int FlybarSelectionPage::nextId() const
371 if (flybarRB->isChecked())
372 return Page_Helictrl;
373 else
374 return Page_Fblheli;
377 ThrottlePage::ThrottlePage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage)
378 : StandardPage(Page_Throttle, dlg, image, title, text, nextPage)
380 motorRB = new QRadioButton(tr("Yes"));
381 noMotorRB = new QRadioButton(tr("No"));
382 motorRB->setChecked(true);
383 throttleCB = new QComboBox();
385 QLayout *l = layout();
386 l->addWidget(motorRB);
387 l->addWidget(noMotorRB);
388 l->addWidget(new QLabel(tr("<br>Throttle Channel:")));
389 l->addWidget(throttleCB);
391 connect(motorRB, SIGNAL(toggled(bool)), this, SLOT(onMotorStateChanged(bool)));
394 void ThrottlePage::initializePage()
396 populateCB(throttleCB, getDefaultChannel(THROTTLE_INPUT));
397 StandardPage::initializePage();
400 bool ThrottlePage::validatePage()
402 releaseBookings();
403 if (motorRB->isChecked())
404 return bookChannel(throttleCB, THROTTLE_INPUT, 100);
405 else
406 return true;
409 void ThrottlePage::onMotorStateChanged(bool toggled)
411 throttleCB->setEnabled(toggled);
414 AileronsPage::AileronsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage)
415 : StandardPage(Page_Ailerons, dlg, image, title, text, nextPage)
417 noAileronsRB = new QRadioButton(tr("No"));
418 oneAileronRB = new QRadioButton(tr("Yes, controlled by a single channel"));
419 twoAileronsRB = new QRadioButton(tr("Yes, controlled by two channels"));
420 noAileronsRB->setChecked(true);
422 aileron1CB = new QComboBox();
423 aileron2CB = new QComboBox();
424 aileron1CB->setEnabled(false);
425 aileron2CB->setEnabled(false);
427 QLayout *l = layout();
428 l->addWidget(noAileronsRB);
429 l->addWidget(oneAileronRB);
430 l->addWidget(twoAileronsRB);
431 l->addWidget(new QLabel(tr("<br>First Aileron Channel:")));
432 l->addWidget(aileron1CB);
433 l->addWidget(new QLabel(tr("Second Aileron Channel:")));
434 l->addWidget(aileron2CB);
436 connect(noAileronsRB, SIGNAL(toggled(bool)), this, SLOT(noAileronChannel()));
437 connect(oneAileronRB, SIGNAL(toggled(bool)), this, SLOT(oneAileronChannel()));
438 connect(twoAileronsRB, SIGNAL(toggled(bool)), this, SLOT(twoAileronChannels()));
441 void AileronsPage::initializePage()
443 populateCB(aileron1CB, getDefaultChannel(AILERONS_INPUT));
444 populateCB(aileron2CB, nextFreeChannel(4));
445 StandardPage::initializePage();
448 bool AileronsPage::validatePage()
450 releaseBookings();
451 if (noAileronsRB->isChecked()) {
452 return true;
454 if (oneAileronRB->isChecked()) {
455 return (bookChannel(aileron1CB, AILERONS_INPUT, 100 ));
457 return( bookChannel(aileron1CB, AILERONS_INPUT, 100 ) &&
458 bookChannel(aileron2CB, AILERONS_INPUT, -100 ));
461 void AileronsPage::noAileronChannel()
463 aileron1CB->setEnabled(false);
464 aileron2CB->setEnabled(false);
467 void AileronsPage::oneAileronChannel()
469 aileron1CB->setEnabled(true);
470 aileron2CB->setEnabled(false);
473 void AileronsPage::twoAileronChannels()
475 aileron1CB->setEnabled(true);
476 aileron2CB->setEnabled(true);
479 FlapsPage::FlapsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
480 StandardPage(Page_Flaps, dlg, image, title, text, nextPage)
482 noFlapsRB = new QRadioButton(tr("No"));
483 oneFlapRB = new QRadioButton(tr("Yes, controlled by a single channel"));
484 twoFlapsRB = new QRadioButton(tr("Yes, controlled by two channels"));
485 noFlapsRB->setChecked(true);
487 flap1CB = new QComboBox();
488 flap2CB = new QComboBox();
489 flap1CB->setEnabled(false);
490 flap2CB->setEnabled(false);
492 QLayout *l = layout();
493 l->addWidget(noFlapsRB);
494 l->addWidget(oneFlapRB);
495 l->addWidget(twoFlapsRB);
496 l->addWidget(new QLabel(tr("<br>First Flap Channel:")));
497 l->addWidget(flap1CB);
498 l->addWidget(new QLabel(tr("Second Flap Channel:")));
499 l->addWidget(flap2CB);
501 connect(noFlapsRB, SIGNAL(toggled(bool)), this, SLOT(noFlapChannel()));
502 connect(oneFlapRB, SIGNAL(toggled(bool)), this, SLOT(oneFlapChannel()));
503 connect(twoFlapsRB, SIGNAL(toggled(bool)), this, SLOT(twoFlapChannels()));
506 void FlapsPage::initializePage()
508 populateCB(flap1CB, nextFreeChannel(4));
509 populateCB(flap2CB, nextFreeChannel(4));
510 StandardPage::initializePage();
513 bool FlapsPage::validatePage() {
514 releaseBookings();
515 if (noFlapsRB->isChecked()) {
516 return true;
518 if (oneFlapRB->isChecked()) {
519 return (bookChannel(flap1CB, FLAPS_INPUT, 100 ));
521 return( bookChannel(flap1CB, FLAPS_INPUT, 100 ) &&
522 bookChannel(flap2CB, FLAPS_INPUT, 100 ));
525 void FlapsPage::noFlapChannel()
527 flap1CB->setEnabled(false);
528 flap2CB->setEnabled(false);
531 void FlapsPage::oneFlapChannel()
533 flap1CB->setEnabled(true);
534 flap2CB->setEnabled(false);
537 void FlapsPage::twoFlapChannels()
539 flap1CB->setEnabled(true);
540 flap2CB->setEnabled(true);
543 AirbrakesPage::AirbrakesPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
544 StandardPage(Page_Airbrakes, dlg, image, title, text, nextPage)
546 noAirbrakesRB = new QRadioButton(tr("No"));
547 oneAirbrakeRB = new QRadioButton(tr("Yes, controlled by a single channel"));
548 twoAirbrakesRB = new QRadioButton(tr("Yes, controlled by two channels"));
549 noAirbrakesRB->setChecked(true);
551 airbrake1CB = new QComboBox();
552 airbrake2CB = new QComboBox();
553 airbrake1CB->setEnabled(false);
554 airbrake2CB->setEnabled(false);
556 QLayout *l = layout();
557 l->addWidget(noAirbrakesRB);
558 l->addWidget(oneAirbrakeRB);
559 l->addWidget(twoAirbrakesRB);
560 l->addWidget(new QLabel(tr("<br>First Airbrake Channel:")));
561 l->addWidget(airbrake1CB);
562 l->addWidget(new QLabel(tr("Second Airbrake Channel:")));
563 l->addWidget(airbrake2CB);
565 connect(noAirbrakesRB, SIGNAL(toggled(bool)), this, SLOT(noAirbrakeChannel()));
566 connect(oneAirbrakeRB, SIGNAL(toggled(bool)), this, SLOT(oneAirbrakeChannel()));
567 connect(twoAirbrakesRB, SIGNAL(toggled(bool)), this, SLOT(twoAirbrakeChannels()));
570 void AirbrakesPage::initializePage()
572 populateCB(airbrake1CB, nextFreeChannel(4));
573 populateCB(airbrake2CB, nextFreeChannel(4));
574 StandardPage::initializePage();
577 bool AirbrakesPage::validatePage()
579 releaseBookings();
580 if (noAirbrakesRB->isChecked()) {
581 return true;
583 if (oneAirbrakeRB->isChecked()) {
584 return (bookChannel(airbrake1CB, AIRBRAKES_INPUT, 100 ));
586 return( bookChannel(airbrake1CB, AIRBRAKES_INPUT, 100 ) &&
587 bookChannel(airbrake2CB, AIRBRAKES_INPUT, 100 ));
590 void AirbrakesPage::noAirbrakeChannel()
592 airbrake1CB->setEnabled(false);
593 airbrake2CB->setEnabled(false);
596 void AirbrakesPage::oneAirbrakeChannel()
598 airbrake1CB->setEnabled(true);
599 airbrake2CB->setEnabled(false);
602 void AirbrakesPage::twoAirbrakeChannels()
604 airbrake1CB->setEnabled(true);
605 airbrake2CB->setEnabled(true);
608 ElevonsPage::ElevonsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
609 StandardPage(Page_Elevons, dlg, image, title, text, nextPage)
611 elevon1CB = new QComboBox();
612 elevon2CB = new QComboBox();
614 QLayout *l = layout();
615 l->addWidget(new QLabel(tr("<br>First Elevon Channel:")));
616 l->addWidget(elevon1CB);
617 l->addWidget(new QLabel(tr("Second Elevon Channel:")));
618 l->addWidget(elevon2CB);
621 void ElevonsPage::initializePage()
623 populateCB(elevon1CB, getDefaultChannel(ELEVATOR_INPUT));
624 populateCB(elevon2CB, getDefaultChannel(AILERONS_INPUT));
625 StandardPage::initializePage();
628 bool ElevonsPage::validatePage()
630 releaseBookings();
631 return (bookChannel(elevon1CB, AILERONS_INPUT, 50, ELEVATOR_INPUT, 50) &&
632 bookChannel(elevon2CB, AILERONS_INPUT, -50, ELEVATOR_INPUT, 50));
635 RudderPage::RudderPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
636 StandardPage(Page_Rudder, dlg, image, title, text, nextPage)
638 noRudderRB = new QRadioButton(tr("No"));
639 hasRudderRB = new QRadioButton(tr("Yes"));
640 noRudderRB->setChecked(true);
642 rudderCB = new QComboBox();
643 rudderCB->setEnabled(false);
645 QLayout *l = layout();
646 l->addWidget(noRudderRB);
647 l->addWidget(hasRudderRB);
648 l->addWidget(new QLabel(tr("<br>Rudder Channel:")));
649 l->addWidget(rudderCB);
650 connect(noRudderRB, SIGNAL(toggled(bool)), this, SLOT(noRudder()));
651 connect(hasRudderRB, SIGNAL(toggled(bool)), this, SLOT(hasRudder()));
654 void RudderPage::initializePage()
656 populateCB(rudderCB, getDefaultChannel(RUDDER_INPUT));
657 StandardPage::initializePage();
660 bool RudderPage::validatePage() {
661 releaseBookings();
662 if (noRudderRB->isChecked())
663 return true;
665 return (bookChannel(rudderCB, RUDDER_INPUT, 100));
668 void RudderPage::noRudder()
670 rudderCB->setEnabled(false);
673 void RudderPage::hasRudder()
675 rudderCB->setEnabled(true);
678 VTailPage::VTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage)
679 : StandardPage(Page_Tail, dlg, image, title, text, nextPage)
681 tail1CB = new QComboBox();
682 tail2CB = new QComboBox();
684 QLayout *l = layout();
685 l->addWidget(new QLabel(tr("First Tail Channel:")));
686 l->addWidget(tail1CB);
687 l->addWidget(new QLabel(tr("Second Tail Channel:")));
688 l->addWidget(tail2CB);
691 void VTailPage::initializePage()
693 populateCB(tail1CB, getDefaultChannel(ELEVATOR_INPUT));
694 populateCB(tail2CB, getDefaultChannel(AILERONS_INPUT));
695 StandardPage::initializePage();
698 bool VTailPage::validatePage()
700 releaseBookings();
701 return (bookChannel(tail1CB, ELEVATOR_INPUT, 50, RUDDER_INPUT, 50) &&
702 bookChannel(tail2CB, ELEVATOR_INPUT, 50, RUDDER_INPUT, -50 ));
705 TailPage::TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
706 StandardPage(Page_Tail, dlg, image, title, text, nextPage)
708 elevatorCB = new QComboBox();
709 rudderCB = new QComboBox();
711 QLayout *l = layout();
712 l->addWidget(new QLabel(tr("Rudder Channel:")));
713 l->addWidget(rudderCB);
714 l->addWidget(new QLabel(tr("Elevator Channel:")));
715 l->addWidget(elevatorCB);
718 void TailPage::initializePage()
720 populateCB(elevatorCB, getDefaultChannel(ELEVATOR_INPUT));
721 populateCB(rudderCB, getDefaultChannel(RUDDER_INPUT));
722 StandardPage::initializePage();
725 bool TailPage::validatePage()
727 releaseBookings();
728 return( bookChannel(elevatorCB, ELEVATOR_INPUT, 100) &&
729 bookChannel(rudderCB, RUDDER_INPUT, 100));
732 SimpleTailPage::SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage)
733 : StandardPage(Page_Simpletail, dlg, image, title, text, nextPage)
735 elevatorCB = new QComboBox();
737 QLayout *l = layout();
738 l->addWidget(new QLabel(tr("Elevator Channel:")));
739 l->addWidget(elevatorCB);
742 void SimpleTailPage::initializePage()
744 populateCB(elevatorCB, getDefaultChannel(ELEVATOR_INPUT));
745 StandardPage::initializePage();
748 bool SimpleTailPage::validatePage()
750 releaseBookings();
751 return( bookChannel(elevatorCB, ELEVATOR_INPUT, 100 ));
754 CyclicPage::CyclicPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
755 StandardPage(Page_Cyclic, dlg, image, title, text, nextPage)
757 cyclic90RB = new QRadioButton(tr("90"));
758 cyclic90RB->setChecked(true);
759 cyclic120RB = new QRadioButton(tr("120"));
760 cyclic120XRB = new QRadioButton(tr("120x"));
761 cyclic140RB = new QRadioButton(tr("140"));
763 QLayout *l = layout();
764 l->addWidget(cyclic90RB);
765 l->addWidget(cyclic120RB);
766 l->addWidget(cyclic120XRB);
767 l->addWidget(cyclic140RB);
770 void CyclicPage::initializePage()
772 StandardPage::initializePage();
775 bool CyclicPage::validatePage()
777 releaseBookings();
778 return true;
781 GyroPage::GyroPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
782 StandardPage(Page_Gyro, dlg, image, title, text, nextPage)
784 noGyroRB = new QRadioButton(tr("No"));
785 noGyroRB->setChecked(true);
786 switchGyroRB = new QRadioButton(tr("Yes, controled by a switch"));
787 potGyroRB = new QRadioButton(tr("Yes, controlled by a pot"));
789 QLayout *l = layout();
790 l->addWidget(noGyroRB);
791 l->addWidget(switchGyroRB);
792 l->addWidget(potGyroRB);
795 void GyroPage::initializePage()
797 StandardPage::initializePage();
800 bool GyroPage::validatePage() {
801 releaseBookings();
802 return true;
805 FblPage::FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
806 StandardPage(Page_Fblheli, dlg, image, title, text, nextPage)
808 throttleCB = new QComboBox();
809 yawCB = new QComboBox();
810 pitchCB = new QComboBox();
811 rollCB = new QComboBox();
813 QLayout *l = layout();
814 l->addWidget(new QLabel(tr("Throttle Channel:")));
815 l->addWidget(throttleCB);
816 l->addWidget(new QLabel(tr("Yaw Channel:")));
817 l->addWidget(yawCB);
818 l->addWidget(new QLabel(tr("Pitch Channel:")));
819 l->addWidget(pitchCB);
820 l->addWidget(new QLabel(tr("Roll Channel:")));
821 l->addWidget(rollCB);
824 void FblPage::initializePage()
826 populateCB(throttleCB, getDefaultChannel(THROTTLE_INPUT));
827 populateCB(yawCB, getDefaultChannel(RUDDER_INPUT));
828 populateCB(pitchCB, getDefaultChannel(ELEVATOR_INPUT));
829 populateCB(rollCB, getDefaultChannel(AILERONS_INPUT));
830 StandardPage::initializePage();
833 bool FblPage::validatePage()
835 releaseBookings();
836 return( bookChannel(throttleCB, THROTTLE_INPUT, 100 ) &&
837 bookChannel( yawCB, RUDDER_INPUT, 100 ) &&
838 bookChannel( pitchCB, ELEVATOR_INPUT, 100 ) &&
839 bookChannel( rollCB, AILERONS_INPUT, 100 ));
842 HeliPage::HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
843 StandardPage(Page_Helictrl, dlg, image, title, text, nextPage)
845 throttleCB = new QComboBox();
846 yawCB = new QComboBox();
847 pitchCB = new QComboBox();
848 rollCB = new QComboBox();
850 QLayout *l = layout();
851 l->addWidget(new QLabel(tr("Throttle Channel:")));
852 l->addWidget(throttleCB);
853 l->addWidget(new QLabel(tr("Yaw Channel:")));
854 l->addWidget(yawCB);
855 l->addWidget(new QLabel(tr("Pitch Channel:")));
856 l->addWidget(pitchCB);
857 l->addWidget(new QLabel(tr("Roll Channel:")));
858 l->addWidget(rollCB);
861 void HeliPage::initializePage()
863 populateCB(throttleCB, getDefaultChannel(THROTTLE_INPUT));
864 populateCB(yawCB, getDefaultChannel(RUDDER_INPUT));
865 populateCB(pitchCB, getDefaultChannel(ELEVATOR_INPUT));
866 populateCB(rollCB, getDefaultChannel(AILERONS_INPUT));
867 StandardPage::initializePage();
870 bool HeliPage::validatePage()
872 releaseBookings();
873 return( bookChannel(throttleCB, THROTTLE_INPUT, 100 ) &&
874 bookChannel( yawCB, RUDDER_INPUT, 100 ) &&
875 bookChannel( pitchCB, ELEVATOR_INPUT, 100 ) &&
876 bookChannel( rollCB, AILERONS_INPUT, 100 ));
879 MultirotorPage::MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
880 StandardPage(Page_Multirotor, dlg, image, title, text, nextPage)
882 throttleCB = new QComboBox();
883 yawCB = new QComboBox();
884 pitchCB = new QComboBox();
885 rollCB = new QComboBox();
887 QLayout *l = layout();
888 l->addWidget(new QLabel(tr("Throttle Channel:")));
889 l->addWidget(throttleCB);
890 l->addWidget(new QLabel(tr("Yaw Channel:")));
891 l->addWidget(yawCB);
892 l->addWidget(new QLabel(tr("Pitch Channel:")));
893 l->addWidget(pitchCB);
894 l->addWidget(new QLabel(tr("Roll Channel:")));
895 l->addWidget(rollCB);
898 void MultirotorPage::initializePage()
900 populateCB(throttleCB, getDefaultChannel(THROTTLE_INPUT));
901 populateCB(yawCB, getDefaultChannel(RUDDER_INPUT));
902 populateCB(pitchCB, getDefaultChannel(ELEVATOR_INPUT));
903 populateCB(rollCB, getDefaultChannel(AILERONS_INPUT));
904 StandardPage::initializePage();
907 bool MultirotorPage::validatePage()
909 releaseBookings();
910 return( bookChannel(throttleCB, THROTTLE_INPUT, 100 ) &&
911 bookChannel(yawCB, RUDDER_INPUT, 100 ) &&
912 bookChannel(pitchCB, ELEVATOR_INPUT, 100 ) &&
913 bookChannel(rollCB, AILERONS_INPUT, 100 ));
916 OptionsPage::OptionsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage):
917 StandardPage(Page_Options, dlg, image, title, text, nextPage)
919 throttleCutRB = new QCheckBox(tr("Throttle Cut"));
920 throttleTimerRB = new QCheckBox(tr("Throttle Timer"));
921 flightTimerRB = new QCheckBox(tr("Flight Timer"));
923 QLayout *l = layout();
924 l->addWidget(throttleCutRB);
925 l->addWidget(throttleTimerRB);
926 l->addWidget(flightTimerRB);
929 void OptionsPage::initializePage(){
930 StandardPage::initializePage();
933 bool OptionsPage::validatePage(){
934 wizDlg->mix.options[THROTTLE_CUT_OPTION] = throttleCutRB->isChecked();
935 wizDlg->mix.options[THROTTLE_TIMER_OPTION] = throttleTimerRB->isChecked();
936 wizDlg->mix.options[FLIGHT_TIMER_OPTION] = flightTimerRB->isChecked();
937 return true;
940 ConclusionPage::ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage)
941 : StandardPage(Page_Conclusion, dlg, image, title, text, nextPage)
943 textLabel = new QLabel();
944 proceedCB = new QCheckBox(tr("OK, I understand."));
945 registerField("evaluate.proceed*", proceedCB);
947 QLayout *l = layout();
948 l->addWidget(textLabel);
949 l->addWidget(proceedCB);
952 void ConclusionPage::initializePage()
954 WizardPrinter p(&wizDlg->mix);
955 textLabel->setText(p.print());
956 StandardPage::initializePage();
959 bool ConclusionPage::validatePage()
961 wizDlg->mix.complete = true;
962 return true;
966 QString WizardPrinter::inputName(Input input)
968 switch (input) {
969 case THROTTLE_INPUT:
970 return "THR";
971 case RUDDER_INPUT:
972 return "RUD";
973 case ELEVATOR_INPUT:
974 return "ELE";
975 case AILERONS_INPUT:
976 return "AIL";
977 case FLAPS_INPUT:
978 return "FLP";
979 case AIRBRAKES_INPUT:
980 return "AIR";
981 default:
982 return "---";
986 QString WizardPrinter::vehicleName(Vehicle vehicle)
988 switch (vehicle) {
989 case PLANE:
990 return tr("Plane");
991 case MULTICOPTER:
992 return tr("Multicopter");
993 case HELICOPTER:
994 return tr("Helicopter");
995 default:
996 return "---";
1000 WizardPrinter::WizardPrinter(WizMix *wizMix)
1002 mix = wizMix;
1005 QString WizardPrinter::printChannel( Input input1, int weight1, Input input2, int weight2 )
1007 QString str;
1008 str = QString("[%1, %2]").arg(inputName(input1)).arg(weight1);
1009 if ( input2 != NO_INPUT )
1010 str += QString("[%1, %2]").arg(inputName(input2)).arg(weight2);
1011 return str;
1014 QString WizardPrinter::print()
1016 QString str = tr("Model Name: ") + mix->name + "\n";
1017 str += tr("Model Type: ") + vehicleName(mix->vehicle) + "\n";
1019 str += tr("Options: ") + "[";
1020 for (int i=0; i<WIZ_MAX_OPTIONS; i++) {
1021 if (mix->options[i])
1022 str += "X";
1023 else
1024 str += "-";
1026 str += QString("]") + "\n";
1028 for (int i=0; i<WIZ_MAX_CHANNELS; i++) {
1029 if (mix->channel[i].page != Page_None) {
1030 Channel ch = mix->channel[i];
1031 str += tr("Channel %1: ").arg(i+1);
1032 str += printChannel(ch.input1, ch.weight1, ch.input2, ch.weight2 );
1033 str += QString("\n");
1036 return str;