2 ******************************************************************************
4 * @file configgadgetwidget.cpp
5 * @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
8 * @addtogroup ConfigPlugin Config Plugin
10 * @brief The Configuration Gadget used to update settings in the firmware
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "configgadgetwidget.h"
30 #include "configvehicletypewidget.h"
31 #include "configccattitudewidget.h"
32 #include "configinputwidget.h"
33 #include "configoutputwidget.h"
34 #include "configstabilizationwidget.h"
35 #include "configcamerastabilizationwidget.h"
36 #include "configtxpidwidget.h"
37 #include "configrevohwwidget.h"
38 #include "config_cc_hw_widget.h"
39 #include "configoplinkwidget.h"
40 #include "configrevowidget.h"
41 #include "configrevonanohwwidget.h"
42 #include "defaultattitudewidget.h"
43 #include "defaulthwsettingswidget.h"
44 #include "uavobjectutilmanager.h"
46 #include <uavtalk/telemetrymanager.h>
49 #include <QStringList>
52 #include <QVBoxLayout>
53 #include <QPushButton>
55 ConfigGadgetWidget::ConfigGadgetWidget(QWidget
*parent
) : QWidget(parent
)
57 setSizePolicy(QSizePolicy::MinimumExpanding
, QSizePolicy::MinimumExpanding
);
59 stackWidget
= new MyTabbedStackWidget(this, true, true);
60 stackWidget
->setIconSize(64);
62 QVBoxLayout
*layout
= new QVBoxLayout
;
63 layout
->setContentsMargins(0, 0, 0, 0);
64 layout
->addWidget(stackWidget
);
69 QIcon
*icon
= new QIcon();
70 icon
->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
71 icon
->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
72 qwd
= new DefaultHwSettingsWidget(this);
73 stackWidget
->insertTab(ConfigGadgetWidget::hardware
, qwd
, *icon
, QString("Hardware"));
76 icon
->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
77 icon
->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
78 qwd
= new ConfigVehicleTypeWidget(this);
79 stackWidget
->insertTab(ConfigGadgetWidget::aircraft
, qwd
, *icon
, QString("Vehicle"));
82 icon
->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
83 icon
->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
84 qwd
= new ConfigInputWidget(this);
85 stackWidget
->insertTab(ConfigGadgetWidget::input
, qwd
, *icon
, QString("Input"));
88 icon
->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
89 icon
->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
90 qwd
= new ConfigOutputWidget(this);
91 stackWidget
->insertTab(ConfigGadgetWidget::output
, qwd
, *icon
, QString("Output"));
94 icon
->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
95 icon
->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
96 qwd
= new DefaultAttitudeWidget(this);
97 stackWidget
->insertTab(ConfigGadgetWidget::sensors
, qwd
, *icon
, QString("Attitude"));
100 icon
->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
101 icon
->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
102 qwd
= new ConfigStabilizationWidget(this);
103 stackWidget
->insertTab(ConfigGadgetWidget::stabilization
, qwd
, *icon
, QString("Stabilization"));
106 icon
->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
107 icon
->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
108 qwd
= new ConfigCameraStabilizationWidget(this);
109 stackWidget
->insertTab(ConfigGadgetWidget::camerastabilization
, qwd
, *icon
, QString("Gimbal"));
112 icon
->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
113 icon
->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
114 qwd
= new ConfigTxPIDWidget(this);
115 stackWidget
->insertTab(ConfigGadgetWidget::txpid
, qwd
, *icon
, QString("TxPID"));
117 stackWidget
->setCurrentIndex(ConfigGadgetWidget::hardware
);
119 // Listen to autopilot connection events
120 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
121 TelemetryManager
*telMngr
= pm
->getObject
<TelemetryManager
>();
122 connect(telMngr
, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
123 connect(telMngr
, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
125 // And check whether by any chance we are not already connected
126 if (telMngr
->isConnected()) {
127 onAutopilotConnect();
131 connect(stackWidget
, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
133 // Connect to the OPLinkStatus object updates
134 UAVObjectManager
*objManager
= pm
->getObject
<UAVObjectManager
>();
135 oplinkStatusObj
= dynamic_cast<UAVDataObject
*>(objManager
->getObject("OPLinkStatus"));
136 if (oplinkStatusObj
!= NULL
) {
137 connect(oplinkStatusObj
, SIGNAL(objectUpdated(UAVObject
*)), this, SLOT(updateOPLinkStatus(UAVObject
*)));
139 qDebug() << "Error: Object is unknown (OPLinkStatus).";
142 // Create the timer that is used to timeout the connection to the OPLink.
143 oplinkTimeout
= new QTimer(this);
144 connect(oplinkTimeout
, SIGNAL(timeout()), this, SLOT(onOPLinkDisconnect()));
145 oplinkConnected
= false;
148 ConfigGadgetWidget::~ConfigGadgetWidget()
153 void ConfigGadgetWidget::startInputWizard()
155 stackWidget
->setCurrentIndex(ConfigGadgetWidget::input
);
156 ConfigInputWidget
*inputWidget
= dynamic_cast<ConfigInputWidget
*>(stackWidget
->getWidget(ConfigGadgetWidget::input
));
157 Q_ASSERT(inputWidget
);
158 inputWidget
->startInputWizard();
161 void ConfigGadgetWidget::resizeEvent(QResizeEvent
*event
)
163 QWidget::resizeEvent(event
);
166 void ConfigGadgetWidget::onAutopilotDisconnect()
168 QWidget
*qwd
= new DefaultAttitudeWidget(this);
170 stackWidget
->replaceTab(ConfigGadgetWidget::sensors
, qwd
);
172 qwd
= new DefaultHwSettingsWidget(this);
173 stackWidget
->replaceTab(ConfigGadgetWidget::hardware
, qwd
);
175 emit
autopilotDisconnected();
178 void ConfigGadgetWidget::onAutopilotConnect()
180 qDebug() << "ConfigGadgetWidget onAutopilotConnect";
181 // First of all, check what Board type we are talking to, and
182 // if necessary, remove/add tabs in the config gadget:
183 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
184 UAVObjectUtilManager
*utilMngr
= pm
->getObject
<UAVObjectUtilManager
>();
186 int board
= utilMngr
->getBoardModel();
187 if ((board
& 0xff00) == 0x0400) {
188 // CopterControl family
189 QWidget
*qwd
= new ConfigCCAttitudeWidget(this);
190 stackWidget
->replaceTab(ConfigGadgetWidget::sensors
, qwd
);
191 qwd
= new ConfigCCHWWidget(this);
192 stackWidget
->replaceTab(ConfigGadgetWidget::hardware
, qwd
);
193 } else if ((board
& 0xff00) == 0x0900) {
195 QWidget
*qwd
= new ConfigRevoWidget(this);
196 stackWidget
->replaceTab(ConfigGadgetWidget::sensors
, qwd
);
197 if (board
== 0x0903) {
198 qwd
= new ConfigRevoHWWidget(this);
199 } else if (board
== 0x0905) {
200 qwd
= new ConfigRevoNanoHWWidget(this);
202 stackWidget
->replaceTab(ConfigGadgetWidget::hardware
, qwd
);
205 qDebug() << "Unknown board " << board
;
209 emit
autopilotConnected();
212 void ConfigGadgetWidget::tabAboutToChange(int i
, bool *proceed
)
216 ConfigTaskWidget
*wid
= qobject_cast
<ConfigTaskWidget
*>(stackWidget
->currentWidget());
220 if (wid
->isDirty()) {
221 int ans
= QMessageBox::warning(this, tr("Unsaved changes"), tr("The tab you are leaving has unsaved changes,"
222 "if you proceed they will be lost.\n"
223 "Do you still want to proceed?"), QMessageBox::Yes
, QMessageBox::No
);
224 if (ans
== QMessageBox::No
) {
227 wid
->setDirty(false);
233 \brief Called by updates to @OPLinkStatus
235 void ConfigGadgetWidget::updateOPLinkStatus(UAVObject
*)
237 // Restart the disconnection timer.
238 oplinkTimeout
->start(5000);
239 if (!oplinkConnected
) {
240 qDebug() << "ConfigGadgetWidget onOPLinkConnect";
242 QIcon
*icon
= new QIcon();
243 icon
->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal
, QIcon::Off
);
244 icon
->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected
, QIcon::Off
);
246 QWidget
*qwd
= new ConfigOPLinkWidget(this);
247 stackWidget
->insertTab(ConfigGadgetWidget::oplink
, qwd
, *icon
, QString("OPLink"));
248 oplinkConnected
= true;
252 void ConfigGadgetWidget::onOPLinkDisconnect()
254 qDebug() << "ConfigGadgetWidget onOPLinkDisconnect";
255 oplinkTimeout
->stop();
256 oplinkConnected
= false;
258 if (stackWidget
->currentIndex() == ConfigGadgetWidget::oplink
) {
259 stackWidget
->setCurrentIndex(0);
261 stackWidget
->removeTab(ConfigGadgetWidget::oplink
);