Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
{
settings.setValue(getWindowGeometryKey(), saveGeometry());
// Save the last current view in any case
settings.setValue("CURRENT_VIEW", currentView);
// Save the current window state, but only if a system is connected (else no real number of widgets would be present)
if (UASManager::instance()->getUASList().length() > 0) settings.setValue(getWindowStateKey(), saveState(QGC::applicationVersion()));
// Save the current view only if a UAS is connected
if (UASManager::instance()->getUASList().length() > 0) settings.setValue("CURRENT_VIEW_WITH_UAS_CONNECTED", currentView);
// Save the current power mode
}
settings.setValue("LOW_POWER_MODE", lowPowerMode);
settings.sync();
}
void MainWindow::configureWindowName()
{
QList<QHostAddress> hostAddresses = QNetworkInterface::allAddresses();
QString windowname = qApp->applicationName() + " " + qApp->applicationVersion();
bool prevAddr = false;
windowname.append(" (" + QHostInfo::localHostName() + ": ");
for (int i = 0; i < hostAddresses.size(); i++)
{
// Exclude loopback IPv4 and all IPv6 addresses
if (hostAddresses.at(i) != QHostAddress("127.0.0.1") && !hostAddresses.at(i).toString().contains(":"))
{
if(prevAddr) windowname.append("/");
windowname.append(hostAddresses.at(i).toString());
prevAddr = true;
}
}
windowname.append(")");
setWindowTitle(windowname);
#ifndef Q_WS_MAC
//qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png"));
#endif
}
void MainWindow::startVideoCapture()
{
QString format = "bmp";
QString initialPath = QDir::currentPath() + tr("/untitled.") + format;
QString screenFileName = QFileDialog::getSaveFileName(this, tr("Save As"),
initialPath,
tr("%1 Files (*.%2);;All Files (*)")
.arg(format.toUpper())
.arg(format));
delete videoTimer;
videoTimer = new QTimer(this);
//videoTimer->setInterval(40);
//connect(videoTimer, SIGNAL(timeout()), this, SLOT(saveScreen()));
//videoTimer->stop();
}
void MainWindow::stopVideoCapture()
{
videoTimer->stop();
// TODO Convert raw images to PNG
}
void MainWindow::saveScreen()
{
QPixmap window = QPixmap::grabWindow(this->winId());
QString format = "bmp";
if (!screenFileName.isEmpty())
{
window.save(screenFileName, format.toAscii());
}
}
Michael Carpenter
committed
void MainWindow::enableDockWidgetTitleBars(bool enabled)
{
dockWidgetTitleBarEnabled = enabled;
QSettings settings;
settings.beginGroup("QGC_MAINWINDOW");
settings.setValue("DOCK_WIDGET_TITLEBARS",dockWidgetTitleBarEnabled);
settings.endGroup();
settings.sync();
Michael Carpenter
committed
if (!isAdvancedMode)
{
if (enabled)
{
for (QMap<QDockWidget*,QWidget*>::const_iterator i=dockToTitleBarMap.constBegin();i!=dockToTitleBarMap.constEnd();i++)
{
QLabel *label = new QLabel(this);
label->setText(i.key()->windowTitle());
Michael Carpenter
committed
i.key()->setTitleBarWidget(label);
//label->setEnabled(false);
label->installEventFilter(new DockWidgetTitleBarEventFilter());
Michael Carpenter
committed
}
}
else
{
for (QMap<QDockWidget*,QWidget*>::const_iterator i=dockToTitleBarMap.constBegin();i!=dockToTitleBarMap.constEnd();i++)
{
i.key()->setTitleBarWidget(new QWidget(this));
Michael Carpenter
committed
}
}
}
}
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
void MainWindow::enableAutoReconnect(bool enabled)
{
autoReconnect = enabled;
}
void MainWindow::loadNativeStyle()
{
loadStyle(QGC_MAINWINDOW_STYLE_NATIVE);
}
void MainWindow::loadIndoorStyle()
{
loadStyle(QGC_MAINWINDOW_STYLE_INDOOR);
}
void MainWindow::loadOutdoorStyle()
{
loadStyle(QGC_MAINWINDOW_STYLE_OUTDOOR);
}
void MainWindow::loadStyle(QGC_MAINWINDOW_STYLE style)
{
switch (style) {
case QGC_MAINWINDOW_STYLE_NATIVE: {
// Native mode means setting no style
// so if we were already in native mode
// take no action
// Only if a style was set, remove it.
if (style != currentStyle) {
qApp->setStyleSheet("");
showInfoMessage(tr("Please restart QGroundControl"), tr("Please restart QGroundControl to switch to fully native look and feel. Currently you have loaded Qt's plastique style."));
}
}
break;
case QGC_MAINWINDOW_STYLE_INDOOR:
qApp->setStyle("plastique");
styleFileName = ":files/styles/style-indoor.css";
reloadStylesheet();
break;
case QGC_MAINWINDOW_STYLE_OUTDOOR:
qApp->setStyle("plastique");
styleFileName = ":files/styles/style-outdoor.css";
reloadStylesheet();
break;
}
currentStyle = style;
}
void MainWindow::selectStylesheet()
{
// Let user select style sheet
styleFileName = QFileDialog::getOpenFileName(this, tr("Specify stylesheet"), styleFileName, tr("CSS Stylesheet (*.css);;"));
if (!styleFileName.endsWith(".css"))
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(tr("QGroundControl did lot load a new style"));
msgBox.setInformativeText(tr("No suitable .css file selected. Please select a valid .css file."));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
return;
}
// Load style sheet
reloadStylesheet();
}
void MainWindow::reloadStylesheet()
{
// Load style sheet
QFile* styleSheet = new QFile(styleFileName);
if (!styleSheet->exists())
{
styleSheet = new QFile(":files/styles/style-indoor.css");
}
if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text))
{
QString style = QString(styleSheet->readAll());
style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "files/styles/");
qApp->setStyleSheet(style);
}
else
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(tr("QGroundControl did lot load a new style"));
msgBox.setInformativeText(tr("Stylesheet file %1 was not readable").arg(styleFileName));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
delete styleSheet;
}
/**
* The status message will be overwritten if a new message is posted to this function
*
* @param status message text
* @param timeout how long the status should be displayed
*/
void MainWindow::showStatusMessage(const QString& status, int timeout)
{
statusBar()->showMessage(status, timeout);
}
/**
* The status message will be overwritten if a new message is posted to this function.
* it will be automatically hidden after 5 seconds.
*
* @param status message text
*/
void MainWindow::showStatusMessage(const QString& status)
{
statusBar()->showMessage(status, 20000);
}
void MainWindow::showCriticalMessage(const QString& title, const QString& message)
{
QMessageBox msgBox(this);
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(title);
msgBox.setInformativeText(message);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
void MainWindow::showInfoMessage(const QString& title, const QString& message)
{
QMessageBox msgBox(this);
msgBox.setIcon(QMessageBox::Information);
msgBox.setText(title);
msgBox.setInformativeText(message);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
/**
* @brief Create all actions associated to the main window
*
**/
void MainWindow::connectCommonActions()
{
// Bind together the perspective actions
QActionGroup* perspectives = new QActionGroup(ui.menuPerspectives);
perspectives->addAction(ui.actionEngineersView);
perspectives->addAction(ui.actionMavlinkView);
perspectives->addAction(ui.actionFlightView);
perspectives->addAction(ui.actionSimulation_View);
perspectives->addAction(ui.actionMissionView);
Michael Carpenter
committed
perspectives->addAction(ui.actionConfiguration_2);
perspectives->addAction(ui.actionFirmwareUpdateView);
perspectives->addAction(ui.actionUnconnectedView);
perspectives->setExclusive(true);
// Mark the right one as selected
if (currentView == VIEW_ENGINEER) ui.actionEngineersView->setChecked(true);
if (currentView == VIEW_MAVLINK) ui.actionMavlinkView->setChecked(true);
if (currentView == VIEW_FLIGHT) ui.actionFlightView->setChecked(true);
if (currentView == VIEW_SIMULATION) ui.actionSimulation_View->setChecked(true);
if (currentView == VIEW_MISSION) ui.actionMissionView->setChecked(true);
if (currentView == VIEW_CONFIGURATION) ui.actionConfiguration_2->setChecked(true);
if (currentView == VIEW_FIRMWAREUPDATE) ui.actionFirmwareUpdateView->setChecked(true);
if (currentView == VIEW_UNCONNECTED) ui.actionUnconnectedView->setChecked(true);
// The UAS actions are not enabled without connection to system
ui.actionLiftoff->setEnabled(false);
ui.actionLand->setEnabled(false);
ui.actionEmergency_Kill->setEnabled(false);
ui.actionEmergency_Land->setEnabled(false);
ui.actionShutdownMAV->setEnabled(false);
// Connect actions from ui
connect(ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(addLink()));
Michael Carpenter
committed
connect(ui.actionAdvanced_Mode,SIGNAL(triggered()),this,SLOT(setAdvancedMode()));
// Connect internal actions
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*)));
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
// Unmanned System controls
connect(ui.actionLiftoff, SIGNAL(triggered()), UASManager::instance(), SLOT(launchActiveUAS()));
connect(ui.actionLand, SIGNAL(triggered()), UASManager::instance(), SLOT(returnActiveUAS()));
connect(ui.actionEmergency_Land, SIGNAL(triggered()), UASManager::instance(), SLOT(stopActiveUAS()));
connect(ui.actionEmergency_Kill, SIGNAL(triggered()), UASManager::instance(), SLOT(killActiveUAS()));
connect(ui.actionShutdownMAV, SIGNAL(triggered()), UASManager::instance(), SLOT(shutdownActiveUAS()));
connect(ui.actionConfiguration, SIGNAL(triggered()), UASManager::instance(), SLOT(configureActiveUAS()));
// Views actions
connect(ui.actionFlightView, SIGNAL(triggered()), this, SLOT(loadPilotView()));
connect(ui.actionSimulation_View, SIGNAL(triggered()), this, SLOT(loadSimulationView()));
connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
connect(ui.actionMissionView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView()));
connect(ui.actionConfiguration_2,SIGNAL(triggered()),this,SLOT(loadConfigurationView()));
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView()));
connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView()));
connect(ui.actionReloadStylesheet, SIGNAL(triggered()), this, SLOT(reloadStylesheet()));
connect(ui.actionSelectStylesheet, SIGNAL(triggered()), this, SLOT(selectStylesheet()));
// Help Actions
connect(ui.actionOnline_Documentation, SIGNAL(triggered()), this, SLOT(showHelp()));
connect(ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits()));
connect(ui.actionProject_Roadmap_2, SIGNAL(triggered()), this, SLOT(showRoadMap()));
// Custom widget actions
connect(ui.actionNewCustomWidget, SIGNAL(triggered()), this, SLOT(createCustomWidget()));
connect(ui.actionLoadCustomWidgetFile, SIGNAL(triggered()), this, SLOT(loadCustomWidget()));
// Audio output
ui.actionMuteAudioOutput->setChecked(GAudioOutput::instance()->isMuted());
connect(GAudioOutput::instance(), SIGNAL(mutedChanged(bool)), ui.actionMuteAudioOutput, SLOT(setChecked(bool)));
connect(ui.actionMuteAudioOutput, SIGNAL(triggered(bool)), GAudioOutput::instance(), SLOT(mute(bool)));
// User interaction
// NOTE: Joystick thread is not started and
// configuration widget is not instantiated
// unless it is actually used
// so no ressources spend on this.
ui.actionJoystickSettings->setVisible(true);
// Configuration
// Joystick
connect(ui.actionJoystickSettings, SIGNAL(triggered()), this, SLOT(configure()));
// Application Settings
connect(ui.actionSettings, SIGNAL(triggered()), this, SLOT(showSettings()));
}
void MainWindow::showHelp()
{
if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/users/start")))
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText("Could not open help in browser");
msgBox.setInformativeText("To get to the online help, please open http://qgroundcontrol.org/user_guide in a browser.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
}
void MainWindow::showCredits()
{
if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/credits")))
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText("Could not open credits in browser");
msgBox.setInformativeText("To get to the online help, please open http://qgroundcontrol.org/credits in a browser.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
}
void MainWindow::showRoadMap()
{
if(!QDesktopServices::openUrl(QUrl("http://qgroundcontrol.org/dev/roadmap")))
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText("Could not open roadmap in browser");
msgBox.setInformativeText("To get to the online help, please open http://qgroundcontrol.org/roadmap in a browser.");
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.exec();
}
}
void MainWindow::configure()
{
if (!joystickWidget)
{
if (!joystick->isRunning())
{
joystick->start();
}
joystickWidget = new JoystickWidget(joystick);
}
joystickWidget->show();
}
void MainWindow::showSettings()
{
QGCSettingsWidget* settings = new QGCSettingsWidget(this);
settings->show();
}
void MainWindow::addLink()
{
SerialLink* link = new SerialLink();
// TODO This should be only done in the dialog itself
LinkManager::instance()->add(link);
LinkManager::instance()->addProtocol(link, mavlink);
// Go fishing for this link's configuration window
QList<QAction*> actions = ui.menuNetwork->actions();
const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(link));
const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId());
foreach (QAction* act, actions)
{
if (act->data().toInt() == linkID)
{ // LinkManager::instance()->getLinks().indexOf(link)
act->trigger();
break;
}
}
}
void MainWindow::addLink(LinkInterface *link)
{
// IMPORTANT! KEEP THESE TWO LINES
// THEY MAKE SURE THE LINK IS PROPERLY REGISTERED
// BEFORE LINKING THE UI AGAINST IT
// Register (does nothing if already registered)
LinkManager::instance()->add(link);
LinkManager::instance()->addProtocol(link, mavlink);
// Go fishing for this link's configuration window
QList<QAction*> actions = ui.menuNetwork->actions();
bool found(false);
const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(link));
const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId());
foreach (QAction* act, actions)
{
if (act->data().toInt() == linkID)
{ // LinkManager::instance()->getLinks().indexOf(link)
found = true;
}
}
//UDPLink* udp = dynamic_cast<UDPLink*>(link);
if (!found)
{ // || udp
CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this);
QAction* action = commWidget->getAction();
ui.menuNetwork->addAction(action);
// Error handling
connect(link, SIGNAL(communicationError(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
// Special case for simulationlink
MAVLinkSimulationLink* sim = dynamic_cast<MAVLinkSimulationLink*>(link);
if (sim)
{
connect(ui.actionSimulate, SIGNAL(triggered(bool)), sim, SLOT(connectLink(bool)));
}
}
}
void MainWindow::setActiveUAS(UASInterface* uas)
{
// Enable and rename menu
// ui.menuUnmanned_System->setTitle(uas->getUASName());
// if (!ui.menuUnmanned_System->isEnabled()) ui.menuUnmanned_System->setEnabled(true);
}
void MainWindow::UASSpecsChanged(int uas)
{
UASInterface* activeUAS = UASManager::instance()->getActiveUAS();
if (activeUAS)
{
if (activeUAS->getUASID() == uas)
{
// ui.menuUnmanned_System->setTitle(activeUAS->getUASName());
}
}
else
{
// Last system deleted
// ui.menuUnmanned_System->setTitle(tr("No System"));
// ui.menuUnmanned_System->setEnabled(false);
}
}
void MainWindow::UASCreated(UASInterface* uas)
{
// Check if this is the 2nd system and we need a switch menu
if (UASManager::instance()->getUASList().count() > 1)
// ui.menuConnected_Systems->setEnabled(true);
// Connect the UAS to the full user interface
//if (uas != NULL)
//{
// The pilot, operator and engineer views were not available on startup, enable them now
ui.actionFlightView->setEnabled(true);
ui.actionMissionView->setEnabled(true);
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
ui.actionEngineersView->setEnabled(true);
// The UAS actions are not enabled without connection to system
ui.actionLiftoff->setEnabled(true);
ui.actionLand->setEnabled(true);
ui.actionEmergency_Kill->setEnabled(true);
ui.actionEmergency_Land->setEnabled(true);
ui.actionShutdownMAV->setEnabled(true);
QIcon icon;
// Set matching icon
switch (uas->getSystemType())
{
case MAV_TYPE_GENERIC:
icon = QIcon(":files/images/mavs/generic.svg");
break;
case MAV_TYPE_FIXED_WING:
icon = QIcon(":files/images/mavs/fixed-wing.svg");
break;
case MAV_TYPE_QUADROTOR:
icon = QIcon(":files/images/mavs/quadrotor.svg");
break;
case MAV_TYPE_COAXIAL:
icon = QIcon(":files/images/mavs/coaxial.svg");
break;
case MAV_TYPE_HELICOPTER:
icon = QIcon(":files/images/mavs/helicopter.svg");
break;
case MAV_TYPE_ANTENNA_TRACKER:
icon = QIcon(":files/images/mavs/antenna-tracker.svg");
break;
case MAV_TYPE_GCS:
icon = QIcon(":files/images/mavs/groundstation.svg");
break;
case MAV_TYPE_AIRSHIP:
icon = QIcon(":files/images/mavs/airship.svg");
break;
case MAV_TYPE_FREE_BALLOON:
icon = QIcon(":files/images/mavs/free-balloon.svg");
break;
case MAV_TYPE_ROCKET:
icon = QIcon(":files/images/mavs/rocket.svg");
break;
case MAV_TYPE_GROUND_ROVER:
icon = QIcon(":files/images/mavs/ground-rover.svg");
break;
case MAV_TYPE_SURFACE_BOAT:
icon = QIcon(":files/images/mavs/surface-boat.svg");
break;
case MAV_TYPE_SUBMARINE:
icon = QIcon(":files/images/mavs/submarine.svg");
break;
case MAV_TYPE_HEXAROTOR:
icon = QIcon(":files/images/mavs/hexarotor.svg");
break;
case MAV_TYPE_OCTOROTOR:
icon = QIcon(":files/images/mavs/octorotor.svg");
break;
case MAV_TYPE_TRICOPTER:
icon = QIcon(":files/images/mavs/tricopter.svg");
break;
case MAV_TYPE_FLAPPING_WING:
icon = QIcon(":files/images/mavs/flapping-wing.svg");
break;
case MAV_TYPE_KITE:
icon = QIcon(":files/images/mavs/kite.svg");
break;
default:
icon = QIcon(":files/images/mavs/unknown.svg");
break;
}
// QAction* uasAction = new QAction(icon, tr("Select %1 for control").arg(uas->getUASName()), ui.menuConnected_Systems);
// connect(uas, SIGNAL(systemRemoved()), uasAction, SLOT(deleteLater()));
// connect(uasAction, SIGNAL(triggered()), uas, SLOT(setSelected()));
connect(uas, SIGNAL(systemSpecsChanged(int)), this, SLOT(UASSpecsChanged(int)));
// ui.menuConnected_Systems->addAction(uasAction);
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
// FIXME Should be not inside the mainwindow
if (debugConsoleDockWidget)
{
DebugConsole *debugConsole = dynamic_cast<DebugConsole*>(debugConsoleDockWidget->widget());
if (debugConsole)
{
connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)),
debugConsole, SLOT(receiveTextMessage(int,int,int,QString)));
}
}
// Health / System status indicator
if (infoDockWidget)
{
UASInfoWidget *infoWidget = dynamic_cast<UASInfoWidget*>(infoDockWidget->widget());
if (infoWidget)
{
infoWidget->addUAS(uas);
}
}
// UAS List
if (listDockWidget)
{
UASListWidget *listWidget = dynamic_cast<UASListWidget*>(listDockWidget->widget());
if (listWidget)
{
listWidget->addUAS(uas);
}
}
// HIL
showHILConfigurationWidget(uas);
Michael Carpenter
committed
if (!linechartWidget)
{
linechartWidget = new Linecharts(this);
Michael Carpenter
committed
//linechartWidget->hide();
}
// Line chart
//if (!linechartWidget)
//{
// Center widgets
//linechartWidget->addSystem(uas);
linechartWidget->addSource(mavlinkDecoder);
Michael Carpenter
committed
//addCentralWidget(linechartWidget, tr("Realtime Plot"));
if (dataView->centralWidget() != linechartWidget)
{
dataView->setCentralWidget(linechartWidget);
linechartWidget->show();
}
//dataView->setCentralWidget(linechartWidget);
//linechartWidget->show();
//}
// Load default custom widgets for this autopilot type
loadCustomWidgetsFromDefaults(uas->getSystemTypeName(), uas->getAutopilotTypeName());
if (uas->getAutopilotType() == MAV_AUTOPILOT_PIXHAWK)
{
// Dock widgets
if (!detectionDockWidget)
{
detectionDockWidget = new QDockWidget(tr("Object Recognition"), this);
detectionDockWidget->setWidget( new ObjectDetectionView("files/images/patterns", this) );
detectionDockWidget->setObjectName("OBJECT_DETECTION_DOCK_WIDGET");
Michael Carpenter
committed
//addTool(detectionDockWidget, tr("Object Recognition"), Qt::RightDockWidgetArea);
}
if (!watchdogControlDockWidget)
{
watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
watchdogControlDockWidget->setObjectName("WATCHDOG_CONTROL_DOCKWIDGET");
Michael Carpenter
committed
//addTool(watchdogControlDockWidget, tr("Process Control"), Qt::BottomDockWidgetArea);
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
}
}
// Change the view only if this is the first UAS
// If this is the first connected UAS, it is both created as well as
// the currently active UAS
if (UASManager::instance()->getUASList().size() == 1)
{
// Load last view if setting is present
if (settings.contains("CURRENT_VIEW_WITH_UAS_CONNECTED"))
{
int view = settings.value("CURRENT_VIEW_WITH_UAS_CONNECTED").toInt();
switch (view)
{
case VIEW_ENGINEER:
loadEngineerView();
break;
case VIEW_MAVLINK:
loadMAVLinkView();
break;
case VIEW_FIRMWAREUPDATE:
loadFirmwareUpdateView();
break;
case VIEW_FLIGHT:
loadPilotView();
break;
case VIEW_SIMULATION:
loadSimulationView();
break;
case VIEW_UNCONNECTED:
loadUnconnectedView();
break;
case VIEW_MISSION:
default:
loadOperatorView();
break;
}
}
else
{
loadOperatorView();
}
}
//}
// if (!ui.menuConnected_Systems->isEnabled()) ui.menuConnected_Systems->setEnabled(true);
// if (!ui.menuUnmanned_System->isEnabled()) ui.menuUnmanned_System->setEnabled(true);
// Reload view state in case new widgets were added
loadViewState();
}
void MainWindow::UASDeleted(UASInterface* uas)
{
if (UASManager::instance()->getUASList().count() == 0)
{
// Last system deleted
// ui.menuUnmanned_System->setTitle(tr("No System"));
// ui.menuUnmanned_System->setEnabled(false);
// QAction* act;
// QList<QAction*> actions = ui.menuConnected_Systems->actions();
// foreach (act, actions)
// {
// if (act->text().contains(uas->getUASName()))
// ui.menuConnected_Systems->removeAction(act);
// }
}
/**
* Stores the current view state
*/
void MainWindow::storeViewState()
{
if (!aboutToCloseFlag)
{
// Save current state
Michael Carpenter
committed
SubMainWindow *win = qobject_cast<SubMainWindow*>(centerStack->currentWidget());
QList<QDockWidget*> widgets = win->findChildren<QDockWidget*>();
QString widgetnames = "";
for (int i=0;i<widgets.size();i++)
{
widgetnames += widgets[i]->objectName() + ",";
}
widgetnames = widgetnames.mid(0,widgetnames.length()-1);
settings.setValue(getWindowStateKey() + "WIDGETS",widgetnames);
settings.setValue(getWindowStateKey(), win->saveState(QGC::applicationVersion()));
settings.setValue(getWindowStateKey()+"CENTER_WIDGET", centerStack->currentIndex());
// Although we want save the state of the window, we do not want to change the top-leve state (minimized, maximized, etc)
// therefore this state is stored here and restored after applying the rest of the settings in the new
// perspective.
windowStateVal = this->windowState();
settings.setValue(getWindowGeometryKey(), saveGeometry());
}
}
void MainWindow::loadViewState()
{
// Restore center stack state
int index = settings.value(getWindowStateKey()+"CENTER_WIDGET", -1).toInt();
// The offline plot view is usually the consequence of a logging run, always show the realtime view first
Michael Carpenter
committed
if (centerStack->indexOf(dataView) == index)
{
// Rewrite to realtime plot
Michael Carpenter
committed
//index = centerStack->indexOf(linechartWidget);
}
if (index != -1)
{
centerStack->setCurrentIndex(index);
}
else
{
// Hide custom widgets
if (detectionDockWidget) detectionDockWidget->hide();
if (watchdogControlDockWidget) watchdogControlDockWidget->hide();
// Load defaults
switch (currentView)
{
case VIEW_CONFIGURATION:
Michael Carpenter
committed
centerStack->setCurrentWidget(configView);
break;
case VIEW_ENGINEER:
Michael Carpenter
committed
centerStack->setCurrentWidget(dataView);
case VIEW_FLIGHT:
Michael Carpenter
committed
centerStack->setCurrentWidget(pilotView);
break;
case VIEW_MAVLINK:
Michael Carpenter
committed
centerStack->setCurrentWidget(engineeringView);
break;
case VIEW_FIRMWAREUPDATE:
centerStack->setCurrentWidget(firmwareUpdateWidget);
break;
case VIEW_MISSION:
Michael Carpenter
committed
centerStack->setCurrentWidget(plannerView);
case VIEW_SIMULATION:
Michael Carpenter
committed
centerStack->setCurrentWidget(simView);
case VIEW_UNCONNECTED:
case VIEW_FULL:
default:
Michael Carpenter
committed
//centerStack->setCurrentWidget(mapWidget);
if (controlDockWidget)
{
controlDockWidget->hide();
}
if (listDockWidget)
{
listDockWidget->show();
}
break;
}
}
// Restore the widget positions and size
Michael Carpenter
committed
if (settings.contains(getWindowStateKey() + "WIDGETS"))
{
QString widgetstr = settings.value(getWindowStateKey() + "WIDGETS").toString();
QStringList split = widgetstr.split(",");
foreach (QString widgetname,split)
{
if (widgetname != "")
{
Michael Carpenter
committed
qDebug() << "Loading widget:" << widgetname;
Michael Carpenter
committed
loadDockWidget(widgetname);
}
}
}
if (settings.contains(getWindowStateKey()))
{
Michael Carpenter
committed
SubMainWindow *win = qobject_cast<SubMainWindow*>(centerStack->currentWidget());
//settings.setValue(getWindowStateKey(), win->saveState(QGC::applicationVersion()))
win->restoreState(settings.value(getWindowStateKey()).toByteArray(), QGC::applicationVersion());
Michael Carpenter
committed
void MainWindow::setAdvancedMode()
{
if (!isAdvancedMode)
{
ui.actionAdvanced_Mode->setChecked(true);
isAdvancedMode = true;
Michael Carpenter
committed
settings.setValue("ADVANCED_MODE",true);
Michael Carpenter
committed
for (QMap<QDockWidget*,QWidget*>::const_iterator i=dockToTitleBarMap.constBegin();i!=dockToTitleBarMap.constEnd();i++)
{
//QWidget *widget = i.value();
QWidget *widget = i.key()->titleBarWidget();
i.key()->setTitleBarWidget(i.value());
dockToTitleBarMap[i.key()] = widget;
}
}
else
{
ui.actionAdvanced_Mode->setChecked(false);
isAdvancedMode = false;
Michael Carpenter
committed
settings.setValue("ADVANCED_MODE",false);
Michael Carpenter
committed
for (QMap<QDockWidget*,QWidget*>::const_iterator i=dockToTitleBarMap.constBegin();i!=dockToTitleBarMap.constEnd();i++)
{
//QWidget *widget = i.value();
QWidget *widget = i.key()->titleBarWidget();
i.key()->setTitleBarWidget(i.value());
dockToTitleBarMap[i.key()] = widget;
}
}
}
void MainWindow::loadEngineerView()
{
if (currentView != VIEW_ENGINEER)
{
storeViewState();
currentView = VIEW_ENGINEER;
ui.actionEngineersView->setChecked(true);
loadViewState();
}
}
void MainWindow::loadOperatorView()
{
if (currentView != VIEW_MISSION)
{
storeViewState();
currentView = VIEW_MISSION;
ui.actionMissionView->setChecked(true);
loadViewState();
}
}
void MainWindow::loadConfigurationView()
{
if (currentView != VIEW_CONFIGURATION)
{
storeViewState();
currentView = VIEW_CONFIGURATION;
ui.actionConfiguration_2->setChecked(true);
loadViewState();
}
}
void MainWindow::loadUnconnectedView()
{
if (currentView != VIEW_UNCONNECTED)
{
storeViewState();
currentView = VIEW_UNCONNECTED;
ui.actionUnconnectedView->setChecked(true);
loadViewState();
}
}
void MainWindow::loadPilotView()
{
if (currentView != VIEW_FLIGHT)
{
storeViewState();
currentView = VIEW_FLIGHT;
ui.actionFlightView->setChecked(true);
loadViewState();
}
}
void MainWindow::loadSimulationView()
{
if (currentView != VIEW_SIMULATION)
{
storeViewState();
currentView = VIEW_SIMULATION;
ui.actionSimulation_View->setChecked(true);
loadViewState();
}
}
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
void MainWindow::loadMAVLinkView()
{
if (currentView != VIEW_MAVLINK)
{
storeViewState();
currentView = VIEW_MAVLINK;
ui.actionMavlinkView->setChecked(true);
loadViewState();
}
}
void MainWindow::loadFirmwareUpdateView()
{
if (currentView != VIEW_FIRMWAREUPDATE)
{
storeViewState();
currentView = VIEW_FIRMWAREUPDATE;
ui.actionFirmwareUpdateView->setChecked(true);
loadViewState();
}
}
void MainWindow::loadDataView(QString fileName)
{
// Plot is now selected, now load data from file
Michael Carpenter
committed
if (dataView)
Michael Carpenter
committed
//dataView->setCentralWidget(new QGCDataPlot2D(this));
QGCDataPlot2D *plot = qobject_cast<QGCDataPlot2D*>(dataView->centralWidget());
if (plot)
{
plot->loadFile(fileName);
}
Michael Carpenter
committed
/*QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
if (centerStack)
{
Michael Carpenter
committed
centerStack->setCurrentWidget(dataView);
dataplotWidget->loadFile(fileName);
Michael Carpenter
committed
}*/
}
QList<QAction*> MainWindow::listLinkMenuActions(void)
{
return ui.menuNetwork->actions();
}
#ifdef MOUSE_ENABLED_LINUX
bool MainWindow::x11Event(XEvent *event)
{