dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
configgadgetwidget.cpp
Go to the documentation of this file.
1 
14 /*
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  * for more details.
24  *
25  * You should have received a copy of the GNU General Public License along
26  * with this program; if not, see <http://www.gnu.org/licenses/>
27  *
28  * Additional note on redistribution: The copyright and license notices above
29  * must be maintained in each individual source file that is a derivative work
30  * of this source file; otherwise redistribution is prohibited.
31  */
32 
33 #include "configgadgetwidget.h"
34 
36 #include "configinputwidget.h"
37 #include "configoutputwidget.h"
39 #include "configosdwidget.h"
40 #include "configradiowidget.h"
41 #include "configmodulewidget.h"
42 #include "configautotunewidget.h"
44 #include "configtxpidwidget.h"
45 #include "configattitudewidget.h"
48 
49 #include <QDebug>
50 #include <QMessageBox>
51 #include <QStringList>
52 #include <QWidget>
53 #include <QTextEdit>
54 #include <QVBoxLayout>
55 #include <QPushButton>
56 #include <QTimer>
57 
59  : QWidget(parent)
60 {
61  setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
62 
63  ftw = new MyTabbedStackWidget(this, true, true);
64  ftw->setIconSize(64);
65 
66  QVBoxLayout *layout = new QVBoxLayout;
67  layout->setContentsMargins(0, 0, 0, 0);
68  layout->addWidget(ftw);
69  setLayout(layout);
70 
71  help = nullptr;
72  chunk = 0;
73  lastTabIndex = ConfigGadgetWidget::hardware;
74 
75  QTimer::singleShot(500, this, &ConfigGadgetWidget::deferredLoader);
76 }
77 
79 {
80  QIcon *icon;
81  QWidget *qwd;
82 
83  switch (chunk) {
84  case 0:
85  // *********************
86  icon = new QIcon();
87  icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal,
88  QIcon::Off);
89  icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected,
90  QIcon::Off);
91  qwd = new QLabel(tr("<p>No recognized board detected. Hardware tab will refresh once a "
92  "known board is detected.</p>"),
93  this);
94  qobject_cast<QLabel *>(qwd)->setWordWrap(true);
95  ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString(tr("Hardware")));
96  break;
97 
98  case 1:
100  break;
101 
102  case 2:
103  icon = new QIcon();
104  icon->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal,
105  QIcon::Off);
106  icon->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected,
107  QIcon::Off);
108  qwd = new ConfigVehicleTypeWidget(this);
109  ftw->insertTab(ConfigGadgetWidget::aircraft, qwd, *icon, QString("Vehicle"));
110  break;
111 
112  case 3:
113  icon = new QIcon();
114  icon->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal, QIcon::Off);
115  icon->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected,
116  QIcon::Off);
117  qwd = new ConfigInputWidget(this);
118  ftw->insertTab(ConfigGadgetWidget::input, qwd, *icon, QString("Input"));
119  break;
120 
121  case 4:
122  icon = new QIcon();
123  icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal,
124  QIcon::Off);
125  icon->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected,
126  QIcon::Off);
127  qwd = new ConfigOutputWidget(this);
128  ftw->insertTab(ConfigGadgetWidget::output, qwd, *icon, QString("Output"));
129  break;
130 
131  case 5:
132  icon = new QIcon();
133  icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
134  icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected,
135  QIcon::Off);
136  qwd = new ConfigAttitudeWidget(this);
137  ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
138  break;
139 
140  case 6:
141  icon = new QIcon();
142  icon->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal,
143  QIcon::Off);
144  icon->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected,
145  QIcon::Off);
146  qwd = new ConfigStabilizationWidget(this);
147  ftw->insertTab(ConfigGadgetWidget::stabilization, qwd, *icon, QString("Stabilization"));
148  break;
149 
150  case 7:
151  icon = new QIcon();
152  icon->addFile(":/configgadget/images/modules_normal.png", QSize(), QIcon::Normal,
153  QIcon::Off);
154  icon->addFile(":/configgadget/images/modules_selected.png", QSize(), QIcon::Selected,
155  QIcon::Off);
156  qwd = new ConfigModuleWidget(this);
157  ftw->insertTab(ConfigGadgetWidget::modules, qwd, *icon, QString("Modules"));
158  break;
159 
160  case 8:
161  icon = new QIcon();
162  icon->addFile(":/configgadget/images/autotune_normal.png", QSize(), QIcon::Normal,
163  QIcon::Off);
164  icon->addFile(":/configgadget/images/autotune_selected.png", QSize(), QIcon::Selected,
165  QIcon::Off);
166  qwd = new ConfigAutotuneWidget(this);
167  ftw->insertTab(ConfigGadgetWidget::autotune, qwd, *icon, QString("Autotune"));
168  break;
169 
170  case 9:
171  icon = new QIcon();
172  icon->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal,
173  QIcon::Off);
174  icon->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected,
175  QIcon::Off);
176  qwd = new ConfigCameraStabilizationWidget(this);
177  ftw->insertTab(ConfigGadgetWidget::camerastabilization, qwd, *icon, QString("Camera Stab"));
178  break;
179 
180  case 10:
181  icon = new QIcon();
182  icon->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal, QIcon::Off);
183  icon->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected,
184  QIcon::Off);
185  qwd = new ConfigTxPIDWidget(this);
186  ftw->insertTab(ConfigGadgetWidget::txpid, qwd, *icon, QString("TxPID"));
187  break;
188 
189  case 11:
190  icon = new QIcon();
191  icon->addFile(":/configgadget/images/osd_normal.png", QSize(), QIcon::Normal, QIcon::Off);
192  icon->addFile(":/configgadget/images/osd_selected.png", QSize(), QIcon::Selected,
193  QIcon::Off);
194  qwd = new ConfigOsdWidget(this);
195  ftw->insertTab(ConfigGadgetWidget::osd, qwd, *icon, QString("OSD"));
196  // Hide OSD if not applicable, else show
198  break;
199 
200  case 12:
201  icon = new QIcon();
202  icon->addFile(":/configgadget/images/radio_normal.png", QSize(), QIcon::Normal, QIcon::Off);
203  icon->addFile(":/configgadget/images/radio_selected.png", QSize(), QIcon::Selected,
204  QIcon::Off);
205  qwd = new ConfigRadioWidget(this);
206  ftw->insertTab(ConfigGadgetWidget::radio, qwd, *icon, QString("Radio"));
207  // Hide Radio if not applicable, else show
209  break;
210 
211  case 13:
212  default:
213  // *********************
214  // Listen to autopilot connection events
215 
216  ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
217  TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
218  connect(telMngr, &TelemetryManager::connected, this,
220  connect(telMngr, &TelemetryManager::disconnected, this,
222 
223  // And check whether by any chance we are not already connected
224  if (telMngr->isConnected()) {
226  }
227 
229  &ConfigGadgetWidget::tabAboutToChange); //,Qt::BlockingQueuedConnection);
230  return;
231  }
232 
233  chunk++;
234 
235  QTimer::singleShot(0, this, &ConfigGadgetWidget::deferredLoader);
236 }
237 
238 void ConfigGadgetWidget::paintEvent(QPaintEvent *event)
239 {
240  (void)event;
241 
242  if (chunk < 12) {
243  // jumpstart loading.
244  deferredLoader();
245  deferredLoader();
246  }
247 }
248 
250 {
251  // TODO: properly delete all the tabs in ftw before exiting
252 }
253 
255 {
257  ConfigInputWidget *inputWidget =
259  Q_ASSERT(inputWidget);
260  inputWidget->startInputWizard();
261 }
262 
263 void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
264 {
265  QWidget::resizeEvent(event);
266 }
267 
269 {
270  lastTabIndex = ftw->currentIndex();
271 
274 
275  QIcon *icon = new QIcon();
276  icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
277  icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected,
278  QIcon::Off);
279  QLabel *qwd = new QLabel(tr("<p>No recognized board detected. Hardware tab will refresh once a "
280  "known board is detected.</p>"),
281  this);
282  qwd->setWordWrap(true);
283  ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
285 
286  emit autopilotDisconnected();
287 }
288 
290 {
291  QIcon *icon;
292  QWidget *qwd;
293 
294  bool hasOSD = false;
295  bool hasRadio = false;
296 
297  int index = ftw->currentIndex();
298 
299  if (index != ConfigGadgetWidget::hardware) {
300  lastTabIndex = index;
301  }
302 
303  // First of all, check what Board type we are talking to, and
304  // if necessary, remove/add tabs in the config gadget:
305  ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
306  UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
307  if (utilMngr) {
310 
311  // If the board provides a custom configuration widget then use it,
312  // otherwise use the default which populates the fields from the
313  // hardware UAVO
314  bool valid_board = false;
315  Core::IBoardType *board = utilMngr->getBoardType();
316  if (board) {
317  qwd = board->getBoardConfiguration();
318  if (qwd) {
319  valid_board = true;
320  } else {
321  UAVObject *settingsObj =
322  utilMngr->getObjectManager()->getObject(board->getHwUAVO());
323  if (settingsObj) {
324  qwd = new DefaultHwSettingsWidget(settingsObj, this);
325  valid_board = true;
326  }
327  }
328 
330  hasOSD = true;
331  } else if (lastTabIndex == ConfigGadgetWidget::osd) {
332  lastTabIndex = ConfigGadgetWidget::hardware;
333  }
334 
336  hasRadio = true;
337  } else if (lastTabIndex == ConfigGadgetWidget::radio) {
338  lastTabIndex = ConfigGadgetWidget::hardware;
339  }
340  }
341 
342  if (!valid_board) {
343  QLabel *txt = new QLabel(tr("<p>Board detected, but of unknown type. This could be "
344  "because either your GCS or firmware is out of date.</p>"),
345  this);
346  txt->setWordWrap(true);
347  qwd = txt;
348  }
349 
350  icon = new QIcon();
351  icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal,
352  QIcon::Off);
353  icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected,
354  QIcon::Off);
355  ftw->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString(tr("Hardware")));
357  }
358 
361  icon = new QIcon();
362  icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
363  icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
364  qwd = new ConfigAttitudeWidget(this);
365  ftw->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
366 
367  // Hide OSD if not applicable, else show
370 
371  ftw->setCurrentIndex(lastTabIndex);
372 
373  emit autopilotConnected();
374 }
375 
377 {
378  ftw->setCurrentIndex(i);
379 }
380 
381 void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed)
382 {
383  Q_UNUSED(i);
384  *proceed = true;
385  ConfigTaskWidget *wid = qobject_cast<ConfigTaskWidget *>(ftw->currentWidget());
386  if (!wid) {
387  return;
388  }
389 
390  wid->tabSwitchingAway();
391 
392  // Check if widget is dirty (i.e. has unsaved changes)
393  if (wid->isDirty() && wid->isAutopilotConnected()) {
394  int ans = QMessageBox::warning(this, tr("Unsaved changes"),
395  tr("The tab you are leaving has unsaved changes,"
396  "if you proceed they may be lost."
397  "Do you still want to proceed?"),
398  QMessageBox::Yes, QMessageBox::No);
399  if (ans == QMessageBox::No) {
400  *proceed = false;
401  } else {
402  wid->setDirty(false);
403  }
404  }
405 }
MyTabbedStackWidget * ftw
void setDirty(bool value)
virtual QWidget * getBoardConfiguration(QWidget *=nullptr, bool=true)
Return a custom configuration widget, if one is provided.
Definition: iboardtype.h:150
void tabAboutToChange(int i, bool *)
Core plugin system that manages the plugins, their life cycle and their registered objects...
Definition: pluginmanager.h:53
void currentAboutToShow(int index, bool *proceed)
for i
Definition: OPPlots.m:140
ConfigGadgetWidget(QWidget *parent=nullptr)
virtual bool queryCapabilities(BoardCapabilities capability)=0
Query capabilities of the board.
UAVObjectManager * getObjectManager()
Configure the OSD.
virtual QString getHwUAVO()=0
void insertTab(int index, QWidget *tab, const QIcon &icon, const QString &label)
Configure the integrated radio.
void setCurrentIndex(int index)
bool isAutopilotConnected()
ConfigTaskWidget::isAutopilotConnected Checks if the autopilot is connected.
virtual void tabSwitchingAway()
void setHidden(int index, bool hide)
void resizeEvent(QResizeEvent *event)
void paintEvent(QPaintEvent *event)
void autopilotDisconnected()
void(NAME)
void setIconSize(int size)
QWidget * getWidget(int index)
UAVObject * getObject(const QString &name, quint32 instId=0)
Core::IBoardType * getBoardType()
Get the IBoardType corresponding to the connected board.
Configure the optional modules.
bool isConnected() const