LP-551 Add signal/slot logic between Input and Output tab - Prevent actuator manipula...
[librepilot.git] / ground / gcs / src / plugins / config / configgadgetwidget.cpp
blob8f37762051ba7039da1d0e1e761d4ef71b82696b
1 /**
2 ******************************************************************************
4 * @file configgadgetwidget.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2017.
6 * E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
7 * @addtogroup GCSPlugins GCS Plugins
8 * @{
9 * @addtogroup ConfigPlugin Config Plugin
10 * @{
11 * @brief The Configuration Gadget used to update settings in the firmware
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "configgadgetwidget.h"
31 #include "configvehicletypewidget.h"
32 #include "configccattitudewidget.h"
33 #include "configinputwidget.h"
34 #include "configoutputwidget.h"
35 #include "configstabilizationwidget.h"
36 #include "configcamerastabilizationwidget.h"
37 #include "configtxpidwidget.h"
38 #include "configrevohwwidget.h"
39 #include "config_cc_hw_widget.h"
40 #include "configautotunewidget.h"
41 #include "configoplinkwidget.h"
42 #include "configrevowidget.h"
43 #include "configrevonanohwwidget.h"
44 #include "configsparky2hwwidget.h"
45 #include "configspracingf3evohwwidget.h"
46 #include "configtinyfishhwwidget.h"
47 #include "configpikoblxhwwidget.h"
48 #include "defaultconfigwidget.h"
50 #include <extensionsystem/pluginmanager.h>
51 #include <uavobjectutilmanager.h>
52 #include <uavtalk/telemetrymanager.h>
53 #include <uavtalk/oplinkmanager.h>
55 #include "utils/mytabbedstackwidget.h"
57 #include <QWidget>
58 #include <QVBoxLayout>
59 #include <QMessageBox>
60 #include <QSettings>
61 #include <QDebug>
63 #define OPLINK_TIMEOUT 2000
65 ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
67 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
69 stackWidget = new MyTabbedStackWidget(this, true, true);
70 stackWidget->setIconSize(64);
72 QVBoxLayout *layout = new QVBoxLayout;
73 layout->setContentsMargins(0, 0, 0, 0);
74 layout->addWidget(stackWidget);
75 setLayout(layout);
77 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
79 QWidget *widget;
80 QWidget *inputWidget;
81 QWidget *outputWidget;
82 QIcon *icon;
84 icon = new QIcon();
85 icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
86 icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off);
87 widget = new DefaultConfigWidget(this, tr("Hardware"));
88 stackWidget->insertTab(ConfigGadgetWidget::Hardware, widget, *icon, QString("Hardware"));
90 icon = new QIcon();
91 icon->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal, QIcon::Off);
92 icon->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected, QIcon::Off);
93 widget = new ConfigVehicleTypeWidget(this);
94 static_cast<ConfigTaskWidget *>(widget)->bind();
95 stackWidget->insertTab(ConfigGadgetWidget::Aircraft, widget, *icon, QString("Vehicle"));
97 icon = new QIcon();
98 icon->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal, QIcon::Off);
99 icon->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected, QIcon::Off);
100 widget = new ConfigInputWidget(this);
101 static_cast<ConfigTaskWidget *>(widget)->bind();
102 stackWidget->insertTab(ConfigGadgetWidget::Input, widget, *icon, QString("Input"));
103 inputWidget = widget;
105 icon = new QIcon();
106 icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal, QIcon::Off);
107 icon->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected, QIcon::Off);
108 widget = new ConfigOutputWidget(this);
109 static_cast<ConfigTaskWidget *>(widget)->bind();
110 stackWidget->insertTab(ConfigGadgetWidget::Output, widget, *icon, QString("Output"));
111 outputWidget = widget;
113 icon = new QIcon();
114 icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
115 icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
116 widget = new DefaultConfigWidget(this, tr("Attitude"));
117 stackWidget->insertTab(ConfigGadgetWidget::Sensors, widget, *icon, QString("Attitude"));
119 icon = new QIcon();
120 icon->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal, QIcon::Off);
121 icon->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected, QIcon::Off);
122 widget = new ConfigStabilizationWidget(this);
123 static_cast<ConfigTaskWidget *>(widget)->bind();
124 stackWidget->insertTab(ConfigGadgetWidget::Stabilization, widget, *icon, QString("Stabilization"));
126 icon = new QIcon();
127 icon->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal, QIcon::Off);
128 icon->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected, QIcon::Off);
129 widget = new ConfigCameraStabilizationWidget(this);
130 static_cast<ConfigTaskWidget *>(widget)->bind();
131 stackWidget->insertTab(ConfigGadgetWidget::CameraStabilization, widget, *icon, QString("Gimbal"));
133 icon = new QIcon();
134 icon->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal, QIcon::Off);
135 icon->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected, QIcon::Off);
136 widget = new ConfigTxPIDWidget(this);
137 static_cast<ConfigTaskWidget *>(widget)->bind();
138 stackWidget->insertTab(ConfigGadgetWidget::TxPid, widget, *icon, QString("TxPID"));
140 icon = new QIcon();
141 icon->addFile(":/configgadget/images/autotune_normal.png", QSize(), QIcon::Normal, QIcon::Off);
142 icon->addFile(":/configgadget/images/autotune_selected.png", QSize(), QIcon::Selected, QIcon::Off);
143 widget = new DefaultConfigWidget(this, tr("AutoTune Configuration"));
144 stackWidget->insertTab(ConfigGadgetWidget::AutoTune, widget, *icon, QString("AutoTune"));
146 icon = new QIcon();
147 icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off);
148 icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
149 widget = new DefaultConfigWidget(this, tr("OPLink Configuration"));
150 stackWidget->insertTab(ConfigGadgetWidget::OPLink, widget, *icon, QString("OPLink"));
152 stackWidget->setCurrentIndex(ConfigGadgetWidget::Hardware);
154 // connect to autopilot connection events
155 TelemetryManager *tm = pm->getObject<TelemetryManager>();
156 connect(tm, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
157 connect(tm, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
158 // check if we are already connected
159 if (tm->isConnected()) {
160 onAutopilotConnect();
163 // connect to oplink manager
164 OPLinkManager *om = pm->getObject<OPLinkManager>();
165 connect(om, SIGNAL(connected()), this, SLOT(onOPLinkConnect()));
166 connect(om, SIGNAL(disconnected()), this, SLOT(onOPLinkDisconnect()));
167 // check if we are already connected
168 if (om->isConnected()) {
169 onOPLinkConnect();
172 // Connect output tab and input tab for safe
173 // output config and input calibration
174 connect(outputWidget, SIGNAL(outputConfigSafe(bool)), inputWidget, SLOT(outputConfigSafe(bool)));
175 connect(inputWidget, SIGNAL(inputCalibrationStatus(bool)), outputWidget, SLOT(inputCalibrationStatus(bool)));
177 help = 0;
178 connect(stackWidget, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
181 ConfigGadgetWidget::~ConfigGadgetWidget()
183 delete stackWidget;
186 void ConfigGadgetWidget::startInputWizard()
188 stackWidget->setCurrentIndex(ConfigGadgetWidget::Input);
189 ConfigInputWidget *inputWidget = dynamic_cast<ConfigInputWidget *>(stackWidget->getWidget(ConfigGadgetWidget::Input));
190 Q_ASSERT(inputWidget);
191 inputWidget->startInputWizard();
194 void ConfigGadgetWidget::saveState(QSettings &settings) const
196 settings.setValue("currentIndex", stackWidget->currentIndex());
199 void ConfigGadgetWidget::restoreState(QSettings &settings)
201 int index = settings.value("currentIndex", 0).toInt();
203 stackWidget->setCurrentIndex(index);
206 void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
208 QWidget::resizeEvent(event);
211 void ConfigGadgetWidget::onAutopilotConnect()
213 // qDebug() << "ConfigGadgetWidget::onAutopilotConnect";
215 // Check what Board type we are talking to, and if necessary, remove/add tabs in the config gadget
216 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
217 UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
219 if (utilMngr) {
220 int board = utilMngr->getBoardModel();
221 if ((board & 0xff00) == 0x0400) {
222 // CopterControl family
224 ConfigTaskWidget *widget;
226 if ((board & 0x00ff) == 0x03) {
227 widget = new ConfigRevoWidget(this);
228 } else {
229 widget = new ConfigCCAttitudeWidget(this);
232 widget->bind();
233 stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
235 widget = new ConfigCCHWWidget(this);
236 widget->bind();
237 stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
238 } else if ((board & 0xff00) == 0x0900) {
239 // Revolution family
240 ConfigTaskWidget *widget;
241 widget = new ConfigRevoWidget(this);
242 widget->bind();
243 stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
244 widget = new ConfigAutoTuneWidget(this);
245 widget->bind();
246 stackWidget->replaceTab(ConfigGadgetWidget::AutoTune, widget);
247 if (board == 0x0903 || board == 0x0904) {
248 widget = new ConfigRevoHWWidget(this);
249 } else if (board == 0x0905) {
250 widget = new ConfigRevoNanoHWWidget(this);
252 widget->bind();
253 stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
254 } else if ((board & 0xff00) == 0x9200) {
255 // Sparky2
256 ConfigTaskWidget *widget;
257 widget = new ConfigRevoWidget(this);
258 widget->bind();
259 stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
260 widget = new ConfigAutoTuneWidget(this);
261 widget->bind();
262 stackWidget->replaceTab(ConfigGadgetWidget::AutoTune, widget);
263 widget = new ConfigSparky2HWWidget(this);
264 widget->bind();
265 stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
266 } else if ((board & 0xff00) == 0x1000) { // F3 boards
267 ConfigTaskWidget *widget;
268 widget = new ConfigRevoWidget(this);
269 widget->bind();
270 stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
272 widget = 0;
274 switch (board) {
275 case 0x1001:
276 // widget = new ConfigSPRacingF3HWWidget(this);
277 break;
278 case 0x1002:
279 case 0x1003:
280 widget = new ConfigSPRacingF3EVOHWWidget(this);
281 break;
282 case 0x1005:
283 widget = new ConfigPikoBLXHWWidget(this);
284 break;
285 case 0x1006:
286 widget = new ConfigTinyFISHHWWidget(this);
287 break;
290 if (widget) {
291 widget->bind();
292 stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
294 } else {
295 // Unknown board
296 qWarning() << "Unknown board " << board;
301 void ConfigGadgetWidget::onAutopilotDisconnect()
303 // qDebug() << "ConfigGadgetWidget::onAutopilotDiconnect";
304 QWidget *widget;
306 widget = new DefaultConfigWidget(this, tr("Attitude"));
307 stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
309 widget = new DefaultConfigWidget(this, tr("Hardware"));
310 stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
312 widget = new DefaultConfigWidget(this, tr("AutoTune"));
313 stackWidget->replaceTab(ConfigGadgetWidget::AutoTune, widget);
316 void ConfigGadgetWidget::onOPLinkConnect()
318 // qDebug() << "ConfigGadgetWidget::onOPLinkConnect";
320 ConfigTaskWidget *widget = new ConfigOPLinkWidget(this);
322 widget->bind();
323 stackWidget->replaceTab(ConfigGadgetWidget::OPLink, widget);
326 void ConfigGadgetWidget::onOPLinkDisconnect()
328 // qDebug() << "ConfigGadgetWidget::onOPLinkDisconnect";
330 QWidget *widget = new DefaultConfigWidget(this, tr("OPLink Configuration"));
332 stackWidget->replaceTab(ConfigGadgetWidget::OPLink, widget);
335 void ConfigGadgetWidget::tabAboutToChange(int index, bool *proceed)
337 Q_UNUSED(index);
338 *proceed = true;
339 ConfigTaskWidget *wid = qobject_cast<ConfigTaskWidget *>(stackWidget->currentWidget());
340 if (!wid) {
341 return;
343 if (wid->isDirty()) {
344 int ans = QMessageBox::warning(this, tr("Unsaved changes"), tr("The tab you are leaving has unsaved changes, "
345 "if you proceed they will be lost.\n"
346 "Do you still want to proceed?"), QMessageBox::Yes, QMessageBox::No);
347 if (ans == QMessageBox::No) {
348 *proceed = false;
349 } else {
350 wid->clearDirty();