Newer
Older
// 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_PILOT) ui.actionPilotsView->setChecked(true);
if (currentView == VIEW_OPERATOR) ui.actionOperatorsView->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()));
// Connect internal actions
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(UASCreated(UASInterface*)));
connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*)));
Mariano Lizarraga
committed
// 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()));
Mariano Lizarraga
committed
// Views actions
Mariano Lizarraga
committed
connect(ui.actionPilotsView, SIGNAL(triggered()), this, SLOT(loadPilotView()));
Mariano Lizarraga
committed
connect(ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
Mariano Lizarraga
committed
connect(ui.actionOperatorsView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView()));
pixhawk
committed
connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView()));
Mariano Lizarraga
committed
connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView()));
connect(ui.actionReloadStylesheet, SIGNAL(triggered()), this, SLOT(reloadStylesheet()));
connect(ui.actionSelectStylesheet, SIGNAL(triggered()), this, SLOT(selectStylesheet()));
Mariano Lizarraga
committed
// Help Actions
connect(ui.actionOnline_Documentation, SIGNAL(triggered()), this, SLOT(showHelp()));
Mariano Lizarraga
committed
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()));
Mariano Lizarraga
committed
}
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();
}
}
if (!joystickWidget)
{
if (!joystick->isRunning())
{
joystick->start();
}
joystickWidget = new JoystickWidget(joystick);
}
joystickWidget->show();
void MainWindow::showSettings()
{
QGCSettingsWidget* settings = new QGCSettingsWidget(this);
settings->show();
}
{
SerialLink* link = new SerialLink();
// TODO This should be only done in the dialog itself
LinkManager::instance()->add(link);
// 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();
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;
}
}
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);
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);
}
// The pilot, operator and engineer views were not available on startup, enable them now
ui.actionOperatorsView->setEnabled(true);
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:
Jessica
committed
icon = QIcon(":files/images/mavs/generic.svg");
break;
case MAV_TYPE_FIXED_WING:
Jessica
committed
icon = QIcon(":files/images/mavs/fixed-wing.svg");
break;
case MAV_TYPE_QUADROTOR:
Jessica
committed
icon = QIcon(":files/images/mavs/quadrotor.svg");
break;
case MAV_TYPE_COAXIAL:
Jessica
committed
icon = QIcon(":files/images/mavs/coaxial.svg");
break;
case MAV_TYPE_HELICOPTER:
Jessica
committed
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:
Jessica
committed
icon = QIcon(":files/images/mavs/groundstation.svg");
break;
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
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:
Jessica
committed
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);
// FIXME Should be not inside the mainwindow
DebugConsole *debugConsole = dynamic_cast<DebugConsole*>(debugConsoleDockWidget->widget());
connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)),
debugConsole, SLOT(receiveTextMessage(int,int,int,QString)));
}
// Health / System status indicator
UASInfoWidget *infoWidget = dynamic_cast<UASInfoWidget*>(infoDockWidget->widget());
// UAS List
UASListWidget *listWidget = dynamic_cast<UASListWidget*>(listDockWidget->widget());
// Line chart
if (!linechartWidget)
// Center widgets
linechartWidget->addSource(mavlinkDecoder);
addCentralWidget(linechartWidget, tr("Realtime Plot"));
// 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);
Jessica
committed
detectionDockWidget->setWidget( new ObjectDetectionView("files/images/patterns", this) );
detectionDockWidget->setObjectName("OBJECT_DETECTION_DOCK_WIDGET");
addTool(detectionDockWidget, tr("Object Recognition"), Qt::RightDockWidgetArea);
}
watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
watchdogControlDockWidget->setObjectName("WATCHDOG_CONTROL_DOCKWIDGET");
addTool(watchdogControlDockWidget, tr("Process Control"), Qt::BottomDockWidgetArea);
}
}
// 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)
{
if (settings.contains("CURRENT_VIEW_WITH_UAS_CONNECTED"))
{
int view = settings.value("CURRENT_VIEW_WITH_UAS_CONNECTED").toInt();
case VIEW_ENGINEER:
loadEngineerView();
break;
case VIEW_MAVLINK:
loadMAVLinkView();
break;
case VIEW_FIRMWAREUPDATE:
loadFirmwareUpdateView();
break;
case VIEW_PILOT:
loadPilotView();
break;
case VIEW_UNCONNECTED:
loadUnconnectedView();
break;
case VIEW_OPERATOR:
default:
loadOperatorView();
break;
}
else
{
Mariano Lizarraga
committed
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()
// Save current state
settings.setValue(getWindowStateKey(), 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
if (centerStack->indexOf(dataplotWidget) == index)
{
// Rewrite to realtime plot
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_ENGINEER:
centerStack->setCurrentWidget(linechartWidget);
controlDockWidget->hide();
listDockWidget->hide();
waypointsDockWidget->hide();
infoDockWidget->hide();
debugConsoleDockWidget->show();
logPlayerDockWidget->show();
mavlinkInspectorWidget->show();
Lorenz Meier
committed
//mavlinkSenderWidget->show();
parametersDockWidget->show();
hsiDockWidget->hide();
headDown1DockWidget->hide();
headDown2DockWidget->hide();
rcViewDockWidget->hide();
headUpDockWidget->hide();
video1DockWidget->hide();
video2DockWidget->hide();
break;
case VIEW_PILOT:
centerStack->setCurrentWidget(hudWidget);
controlDockWidget->hide();
listDockWidget->hide();
waypointsDockWidget->hide();
infoDockWidget->hide();
debugConsoleDockWidget->hide();
logPlayerDockWidget->hide();
mavlinkInspectorWidget->hide();
parametersDockWidget->hide();
hsiDockWidget->show();
headDown1DockWidget->show();
headDown2DockWidget->show();
rcViewDockWidget->hide();
headUpDockWidget->hide();
break;
case VIEW_MAVLINK:
centerStack->setCurrentWidget(protocolWidget);
controlDockWidget->hide();
listDockWidget->hide();
waypointsDockWidget->hide();
infoDockWidget->hide();
debugConsoleDockWidget->hide();
logPlayerDockWidget->hide();
Lorenz Meier
committed
//mavlinkSenderWidget->show();
parametersDockWidget->hide();
hsiDockWidget->hide();
headDown1DockWidget->hide();
headDown2DockWidget->hide();
rcViewDockWidget->hide();
headUpDockWidget->hide();
video1DockWidget->hide();
video2DockWidget->hide();
break;
case VIEW_FIRMWAREUPDATE:
centerStack->setCurrentWidget(firmwareUpdateWidget);
controlDockWidget->hide();
listDockWidget->hide();
waypointsDockWidget->hide();
infoDockWidget->hide();
debugConsoleDockWidget->hide();
logPlayerDockWidget->hide();
Lorenz Meier
committed
//mavlinkSenderWidget->hide();
parametersDockWidget->hide();
hsiDockWidget->hide();
headDown1DockWidget->hide();
headDown2DockWidget->hide();
rcViewDockWidget->hide();
headUpDockWidget->hide();
video1DockWidget->hide();
video2DockWidget->hide();
centerStack->setCurrentWidget(mapWidget);
controlDockWidget->hide();
listDockWidget->show();
waypointsDockWidget->show();
infoDockWidget->hide();
debugConsoleDockWidget->show();
logPlayerDockWidget->show();
parametersDockWidget->hide();
hsiDockWidget->show();
headDown1DockWidget->hide();
headDown2DockWidget->hide();
rcViewDockWidget->hide();
headUpDockWidget->show();
video1DockWidget->hide();
video2DockWidget->hide();
mavlinkInspectorWidget->hide();
break;
case VIEW_UNCONNECTED:
case VIEW_FULL:
default:
centerStack->setCurrentWidget(mapWidget);
waypointsDockWidget->hide();
infoDockWidget->hide();
debugConsoleDockWidget->show();
logPlayerDockWidget->show();
parametersDockWidget->hide();
headDown1DockWidget->hide();
headDown2DockWidget->hide();
rcViewDockWidget->hide();
headUpDockWidget->show();
video1DockWidget->hide();
video2DockWidget->hide();
// Restore the widget positions and size
if (settings.contains(getWindowStateKey()))
{
restoreState(settings.value(getWindowStateKey()).toByteArray(), QGC::applicationVersion());
Mariano Lizarraga
committed
void MainWindow::loadEngineerView()
if (currentView != VIEW_ENGINEER)
{
storeViewState();
currentView = VIEW_ENGINEER;
ui.actionEngineersView->setChecked(true);
loadViewState();
Mariano Lizarraga
committed
void MainWindow::loadOperatorView()
if (currentView != VIEW_OPERATOR)
{
storeViewState();
currentView = VIEW_OPERATOR;
ui.actionOperatorsView->setChecked(true);
loadViewState();
void MainWindow::loadUnconnectedView()
{
if (currentView != VIEW_UNCONNECTED)
{
storeViewState();
currentView = VIEW_UNCONNECTED;
ui.actionUnconnectedView->setChecked(true);
loadViewState();
Mariano Lizarraga
committed
void MainWindow::loadPilotView()
if (currentView != VIEW_PILOT)
{
storeViewState();
currentView = VIEW_PILOT;
ui.actionPilotsView->setChecked(true);
loadViewState();
Mariano Lizarraga
committed
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();
}
}
Mariano Lizarraga
committed
void MainWindow::loadDataView(QString fileName)
{
// Plot is now selected, now load data from file
if (dataplotWidget)
{
dataplotWidget->loadFile(fileName);
}
QStackedWidget *centerStack = dynamic_cast<QStackedWidget*>(centralWidget());
if (centerStack)
{
centerStack->setCurrentWidget(dataplotWidget);
Mariano Lizarraga
committed
}
QList<QAction*> MainWindow::listLinkMenuActions(void)
{