Newer
Older
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2011 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief Implementation of class MainWindow
* @author Lorenz Meier <mail@qgroundcontrol.org>
*/
#include <QSettings>
#include <QDockWidget>
#include <QNetworkInterface>
#include <QMessageBox>
#include <QDebug>
#include <QTimer>
#include <QHostInfo>
#include "MAVLinkSimulationLink.h"
#include "SerialLink.h"
#include "UDPLink.h"
#include "MAVLinkProtocol.h"
#include "CommConfigurationWindow.h"
#include "QGCWaypointListMulti.h"
lm
committed
#include "QGCToolWidget.h"
#include "QGCMAVLinkLogPlayer.h"
#include "QGCSettingsWidget.h"
#include "Q3DWidgetFactory.h"
#include "LogCompressor.h"
static MainWindow* _instance = 0;
if(_instance == 0)
{
_instance = new MainWindow();
if (screen) connect(_instance, SIGNAL(initStatusChanged(QString)), screen, SLOT(showMessage(QString)));
/* Set the application as parent to ensure that this object
* will be destroyed when the main application exits */
//_instance->setParent(qApp);
}
return _instance;
/**
* Create new mainwindow. The constructor instantiates all parts of the user
* interface. It does NOT show the mainwindow. To display it, call the show()
* method.
*
* @see QMainWindow::show()
**/
Mariano Lizarraga
committed
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
currentView(VIEW_UNCONNECTED),
Lorenz Meier
committed
currentStyle(QGC_MAINWINDOW_STYLE_INDOOR),
aboutToCloseFlag(false),
changingViewsFlag(false),
centerStackActionGroup(new QActionGroup(this)),
styleFileName(QCoreApplication::applicationDirPath() + "/style-indoor.css"),
autoReconnect(false),
lm
committed
lowPowerMode(false)
loadSettings();
if (!settings.contains("CURRENT_VIEW"))
{
// Set this view as default view
settings.setValue("CURRENT_VIEW", currentView);
}
else
{
// LOAD THE LAST VIEW
VIEW_SECTIONS currentViewCandidate = (VIEW_SECTIONS) settings.value("CURRENT_VIEW", currentView).toInt();
if (currentViewCandidate != VIEW_ENGINEER &&
currentViewCandidate != VIEW_OPERATOR &&
currentViewCandidate != VIEW_PILOT &&
currentViewCandidate != VIEW_FULL)
{
settings.sync();
lm
committed
loadStyle(currentStyle);
lm
committed
// Set dock options
setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);
statusBar()->setSizeGripEnabled(true);
configureWindowName();
// Setup corners
setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
lm
committed
// Setup UI state machines
centerStackActionGroup->setExclusive(true);
lm
committed
centerStack = new QStackedWidget(this);
setCentralWidget(centerStack);
// Load Toolbar
toolBar = new QGCToolBar(this);
this->addToolBar(toolBar);
// Add actions
toolBar->addPerspectiveChangeAction(ui.actionOperatorsView);
toolBar->addPerspectiveChangeAction(ui.actionEngineersView);
toolBar->addPerspectiveChangeAction(ui.actionPilotsView);
Mariano Lizarraga
committed
buildCommonWidgets();
connectCommonWidgets();
Mariano Lizarraga
committed
Mariano Lizarraga
committed
connectCommonActions();
// Populate link menu
QList<LinkInterface*> links = LinkManager::instance()->getLinks();
foreach(LinkInterface* link, links)
{
this->addLink(link);
}
connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*)));
// Connect user interface devices
lm
committed
joystickWidget = 0;
joystick = new JoystickInput();
// Connect link
if (autoReconnect)
{
SerialLink* link = new SerialLink();
// Add to registry
LinkManager::instance()->add(link);
LinkManager::instance()->addProtocol(link, mavlink);
link->connect();
}
// Set low power mode
enableLowPowerMode(lowPowerMode);
// Initialize window state
windowStateVal = windowState();
// Restore the window setup
loadViewState();
// Restore the window position and size
if (settings.contains(getWindowGeometryKey()))
{
// Restore the window geometry
restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
show();
}
else
{
// Adjust the size
const int screenWidth = QApplication::desktop()->width();
const int screenHeight = QApplication::desktop()->height();
if (screenWidth < 1200)
{
showFullScreen();
}
else
{
resize(screenWidth*0.67f, qMin(screenHeight, (int)(screenWidth*0.67f*0.67f)));
show();
}
}
lm
committed
connect(&windowNameUpdateTimer, SIGNAL(timeout()), this, SLOT(configureWindowName()));
windowNameUpdateTimer.start(15000);
delete mavlink;
// Get and delete all dockwidgets and contained
// widgets
QObjectList childList( this->children() );
QObjectList::iterator i;
QDockWidget* dockWidget;
for (i = childList.begin(); i != childList.end(); ++i)
{
dockWidget = dynamic_cast<QDockWidget*>(*i);
if (dockWidget)
{
// Remove dock widget from main window
// removeDockWidget(dockWidget);
// delete dockWidget->widget();
else
{
delete dynamic_cast<QObject*>(*i);
}
if (height() < 800)
{
}
else
{
ui.statusBar->setSizeGripEnabled(true);
if (width() > 1200)
{
toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
}
else
{
toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
}
QMainWindow::resizeEvent(event);
QString MainWindow::getWindowStateKey()
{
return QString::number(currentView)+"_windowstate";
}
QString MainWindow::getWindowGeometryKey()
{
//return QString::number(currentView)+"_geometry";
return "_geometry";
// Create custom widgets
QList<QGCToolWidget*> widgets = QGCToolWidget::createWidgetsFromSettings(this);
if (widgets.size() > 0)
{
ui.menuTools->addSeparator();
}
for(int i = 0; i < widgets.size(); ++i)
{
// Check if this widget already has a parent, do not create it in this case
QGCToolWidget* tool = widgets.at(i);
QDockWidget* dock = dynamic_cast<QDockWidget*>(tool->parentWidget());
if (!dock)
QDockWidget* dock = new QDockWidget(tool->windowTitle(), this);
dock->setObjectName(tool->objectName()+"_DOCK");
dock->setWidget(tool);
connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
QAction* showAction = new QAction(widgets.at(i)->windowTitle(), this);
showAction->setCheckable(true);
connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool)));
connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool)));
widgets.at(i)->setMainMenuAction(showAction);
ui.menuTools->addAction(showAction);
// Load dock widget location (default is bottom)
Qt::DockWidgetArea location = static_cast <Qt::DockWidgetArea>(tool->getDockWidgetArea(currentView));
addDockWidget(location, dock);
Mariano Lizarraga
committed
void MainWindow::buildCommonWidgets()
{
//TODO: move protocol outside UI
mavlink = new MAVLinkProtocol();
connect(mavlink, SIGNAL(protocolStatusMessage(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
// Add generic MAVLink decoder
mavlinkDecoder = new MAVLinkDecoder(mavlink, this);
Mariano Lizarraga
committed
// Dock widgets
if (!controlDockWidget)
{
controlDockWidget = new QDockWidget(tr("Control"), this);
controlDockWidget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET");
controlDockWidget->setWidget( new UASControlWidget(this) );
addTool(controlDockWidget, tr("Control"), Qt::LeftDockWidgetArea);
}
Mariano Lizarraga
committed
if (!listDockWidget)
{
listDockWidget = new QDockWidget(tr("Unmanned Systems"), this);
listDockWidget->setWidget( new UASListWidget(this) );
listDockWidget->setObjectName("UNMANNED_SYSTEMS_LIST_DOCKWIDGET");
addTool(listDockWidget, tr("Unmanned Systems"), Qt::RightDockWidgetArea);
}
Mariano Lizarraga
committed
if (!waypointsDockWidget)
{
waypointsDockWidget = new QDockWidget(tr("Mission Plan"), this);
waypointsDockWidget->setWidget( new QGCWaypointListMulti(this) );
waypointsDockWidget->setObjectName("WAYPOINT_LIST_DOCKWIDGET");
addTool(waypointsDockWidget, tr("Mission Plan"), Qt::BottomDockWidgetArea);
}
Mariano Lizarraga
committed
if (!infoDockWidget)
{
infoDockWidget = new QDockWidget(tr("Status Details"), this);
infoDockWidget->setWidget( new UASInfoWidget(this) );
infoDockWidget->setObjectName("UAS_STATUS_DETAILS_DOCKWIDGET");
addTool(infoDockWidget, tr("Status Details"), Qt::RightDockWidgetArea);
}
Mariano Lizarraga
committed
if (!debugConsoleDockWidget)
{
debugConsoleDockWidget = new QDockWidget(tr("Communication Console"), this);
debugConsoleDockWidget->setWidget( new DebugConsole(this) );
debugConsoleDockWidget->setObjectName("COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET");
DebugConsole *debugConsole = dynamic_cast<DebugConsole*>(debugConsoleDockWidget->widget());
connect(mavlinkDecoder, SIGNAL(textMessageReceived(int, int, int, const QString)), debugConsole, SLOT(receiveTextMessage(int, int, int, const QString)));
addTool(debugConsoleDockWidget, tr("Communication Console"), Qt::BottomDockWidgetArea);
}
Mariano Lizarraga
committed
if (!logPlayerDockWidget)
{
logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this);
logPlayer = new QGCMAVLinkLogPlayer(mavlink, this);
toolBar->setLogPlayer(logPlayer);
logPlayerDockWidget->setWidget(logPlayer);
logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET");
addTool(logPlayerDockWidget, tr("MAVLink Log Replay"), Qt::RightDockWidgetArea);
}
if (!mavlinkInspectorWidget)
{
mavlinkInspectorWidget = new QDockWidget(tr("MAVLink Message Inspector"), this);
mavlinkInspectorWidget->setWidget( new QGCMAVLinkInspector(mavlink, this) );
mavlinkInspectorWidget->setObjectName("MAVLINK_INSPECTOR_DOCKWIDGET");
addTool(mavlinkInspectorWidget, tr("MAVLink Inspector"), Qt::RightDockWidgetArea);
//FIXME: memory of acceptList will never be freed again
QStringList* acceptList = new QStringList();
acceptList->append("-105,roll deg,deg,+105,s");
acceptList->append("-105,pitch deg,deg,+105,s");
acceptList->append("-105,heading deg,deg,+105,s");
//FIXME: memory of acceptList2 will never be freed again
QStringList* acceptList2 = new QStringList();
Mariano Lizarraga
committed
if (!parametersDockWidget) {
parametersDockWidget = new QDockWidget(tr("Calibration and Onboard Parameters"), this);
parametersDockWidget->setWidget( new ParameterInterface(this) );
parametersDockWidget->setObjectName("PARAMETER_INTERFACE_DOCKWIDGET");
addTool(parametersDockWidget, tr("Calibration and Parameters"), Qt::RightDockWidgetArea);
}
if (!hsiDockWidget) {
hsiDockWidget = new QDockWidget(tr("Horizontal Situation Indicator"), this);
hsiDockWidget->setWidget( new HSIDisplay(this) );
hsiDockWidget->setObjectName("HORIZONTAL_SITUATION_INDICATOR_DOCK_WIDGET");
addTool(hsiDockWidget, tr("Horizontal Situation"), Qt::BottomDockWidgetArea);
}
if (!headDown1DockWidget) {
headDown1DockWidget = new QDockWidget(tr("Flight Display"), this);
HDDisplay* hdDisplay = new HDDisplay(acceptList, "Flight Display", this);
hdDisplay->addSource(mavlinkDecoder);
headDown1DockWidget->setWidget(hdDisplay);
headDown1DockWidget->setObjectName("HEAD_DOWN_DISPLAY_1_DOCK_WIDGET");
addTool(headDown1DockWidget, tr("Flight Display"), Qt::RightDockWidgetArea);
}
if (!headDown2DockWidget) {
headDown2DockWidget = new QDockWidget(tr("Actuator Status"), this);
HDDisplay* hdDisplay = new HDDisplay(acceptList2, "Actuator Status", this);
hdDisplay->addSource(mavlinkDecoder);
headDown2DockWidget->setWidget(hdDisplay);
headDown2DockWidget->setObjectName("HEAD_DOWN_DISPLAY_2_DOCK_WIDGET");
addTool(headDown2DockWidget, tr("Actuator Status"), Qt::RightDockWidgetArea);
}
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
if (!rcViewDockWidget) {
rcViewDockWidget = new QDockWidget(tr("Radio Control"), this);
rcViewDockWidget->setWidget( new QGCRemoteControlView(this) );
rcViewDockWidget->setObjectName("RADIO_CONTROL_CHANNELS_DOCK_WIDGET");
addTool(rcViewDockWidget, tr("Radio Control"), Qt::BottomDockWidgetArea);
}
if (!headUpDockWidget) {
headUpDockWidget = new QDockWidget(tr("HUD"), this);
headUpDockWidget->setWidget( new HUD(320, 240, this));
headUpDockWidget->setObjectName("HEAD_UP_DISPLAY_DOCK_WIDGET");
addTool(headUpDockWidget, tr("Head Up Display"), Qt::RightDockWidgetArea);
}
if (!video1DockWidget) {
video1DockWidget = new QDockWidget(tr("Video Stream 1"), this);
HUD* video1 = new HUD(160, 120, this);
video1->enableHUDInstruments(false);
video1->enableVideo(true);
// FIXME select video stream as well
video1DockWidget->setWidget(video1);
video1DockWidget->setObjectName("VIDEO_STREAM_1_DOCK_WIDGET");
addTool(video1DockWidget, tr("Video Stream 1"), Qt::LeftDockWidgetArea);
}
if (!video2DockWidget) {
video2DockWidget = new QDockWidget(tr("Video Stream 2"), this);
HUD* video2 = new HUD(160, 120, this);
video2->enableHUDInstruments(false);
video2->enableVideo(true);
// FIXME select video stream as well
video2DockWidget->setWidget(video2);
video2DockWidget->setObjectName("VIDEO_STREAM_2_DOCK_WIDGET");
addTool(video2DockWidget, tr("Video Stream 2"), Qt::LeftDockWidgetArea);
}
// Custom widgets, added last to all menus and layouts
buildCustomWidget();
// Center widgets
if (!mapWidget)
{
mapWidget = new QGCMapTool(this);
addCentralWidget(mapWidget, "Maps");
}
if (!protocolWidget)
{
protocolWidget = new XMLCommProtocolWidget(this);
addCentralWidget(protocolWidget, "Mavlink Generator");
}
hudWidget = new HUD(320, 240, this);
addCentralWidget(hudWidget, tr("Head Up Display"));
dataplotWidget = new QGCDataPlot2D(this);
addCentralWidget(dataplotWidget, tr("Logfile Plot"));
}
Mariano Lizarraga
committed
pixhawk
committed
#ifdef QGC_OSG_ENABLED
pixhawk
committed
_3DWidget = Q3DWidgetFactory::get("PIXHAWK");
addCentralWidget(_3DWidget, tr("Local 3D"));
}
pixhawk
committed
#endif
#if (defined _MSC_VER) | (defined Q_OS_MAC)
gEarthWidget = new QGCGoogleEarthView(this);
addCentralWidget(gEarthWidget, tr("Google Earth"));
}
pixhawk
committed
#endif
void MainWindow::addTool(QDockWidget* widget, const QString& title, Qt::DockWidgetArea area)
QAction* tempAction = ui.menuTools->addAction(title);
Mariano Lizarraga
committed
QVariant var;
var.setValue((QWidget*)widget);
tempAction->setData(var);
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool)));
tempAction->setChecked(widget->isVisible());
addDockWidget(area, widget);
Mariano Lizarraga
committed
}
void MainWindow::showTool(bool show)
QAction* act = qobject_cast<QAction *>(sender());
QWidget* widget = qVariantValue<QWidget *>(act->data());
widget->setVisible(show);
Mariano Lizarraga
committed
}
Mariano Lizarraga
committed
void MainWindow::addCentralWidget(QWidget* widget, const QString& title)
// Check if this widget already has been added
if (centerStack->indexOf(widget) == -1)
{
centerStack->addWidget(widget);
QAction* tempAction = ui.menuMain->addAction(title);
tempAction->setCheckable(true);
QVariant var;
var.setValue((QWidget*)widget);
tempAction->setData(var);
centerStackActionGroup->addAction(tempAction);
connect(tempAction,SIGNAL(triggered()),this, SLOT(showCentralWidget()));
connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool)));
tempAction->setChecked(widget->isVisible());
Mariano Lizarraga
committed
}
}
void MainWindow::showCentralWidget()
QAction* act = qobject_cast<QAction *>(sender());
QWidget* widget = qVariantValue<QWidget *>(act->data());
centerStack->setCurrentWidget(widget);
Mariano Lizarraga
committed
}
void MainWindow::closeEvent(QCloseEvent *event)
{
storeSettings();
mavlink->storeSettings();
Mariano Lizarraga
committed
/**
* Connect the signals and slots of the common window widgets
*/
Mariano Lizarraga
committed
void MainWindow::connectCommonWidgets()
{
if (infoDockWidget && infoDockWidget->widget()) {
connect(mavlink, SIGNAL(receiveLossChanged(int, float)),
infoDockWidget->widget(), SLOT(updateSendLoss(int, float)));
}
lm
committed
}
Mariano Lizarraga
committed
lm
committed
void MainWindow::createCustomWidget()
{
QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool", dock);
// This is the first widget
ui.menuTools->addSeparator();
}
connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
lm
committed
dock->setWidget(tool);
Mariano Lizarraga
committed
QAction* showAction = new QAction(tool->getTitle(), this);
showAction->setCheckable(true);
connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool)));
connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool)));
tool->setMainMenuAction(showAction);
ui.menuTools->addAction(showAction);
this->addDockWidget(Qt::BottomDockWidgetArea, dock);
dock->setVisible(true);
}
void MainWindow::loadCustomWidget()
{
QString widgetFileExtension(".qgw");
QString fileName = QFileDialog::getOpenFileName(this, tr("Specify Widget File Name"), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), tr("QGroundControl Widget (*%1);;").arg(widgetFileExtension));
if (fileName != "") loadCustomWidget(fileName);
void MainWindow::loadCustomWidget(const QString& fileName, bool singleinstance)
{
QGCToolWidget* tool = new QGCToolWidget("", this);
if (tool->loadSettings(fileName, true) || !singleinstance)
{
// Add widget to UI
QDockWidget* dock = new QDockWidget(tool->getTitle(), this);
connect(tool, SIGNAL(destroyed()), dock, SLOT(deleteLater()));
dock->setWidget(tool);
tool->setParent(dock);
QAction* showAction = new QAction(tool->getTitle(), this);
showAction->setCheckable(true);
connect(dock, SIGNAL(visibilityChanged(bool)), showAction, SLOT(setChecked(bool)));
connect(showAction, SIGNAL(triggered(bool)), dock, SLOT(setVisible(bool)));
tool->setMainMenuAction(showAction);
ui.menuTools->addAction(showAction);
this->addDockWidget(Qt::BottomDockWidgetArea, dock);
dock->setVisible(true);
}
Mariano Lizarraga
committed
}
void MainWindow::loadCustomWidgetsFromDefaults(const QString& systemType, const QString& autopilotType)
{
QString defaultsDir = qApp->applicationDirPath() + "/files/" + autopilotType.toLower() + "/" + systemType.toLower() + "/widgets/";
Mariano Lizarraga
committed
QDir widgets(defaultsDir);
QStringList files = widgets.entryList();
if (files.count() == 0)
{
qDebug() << "No default custom widgets for system " << systemType << "autopilot" << autopilotType << " found";
qDebug() << "Tried with path: " << defaultsDir;
showStatusMessage(tr("Did not find any custom widgets in %1").arg(defaultsDir));
Mariano Lizarraga
committed
// Load all custom widgets found in the AP folder
for(int i = 0; i < files.count(); ++i)
QString file = files[i];
if (file.endsWith(".qgw"))
{
// Will only be loaded if not already a custom widget with
// the same name is present
loadCustomWidget(defaultsDir+"/"+file, true);
showStatusMessage(tr("Loaded custom widget %1").arg(defaultsDir+"/"+file));
Mariano Lizarraga
committed
}
void MainWindow::loadSettings()
{
QSettings settings;
settings.beginGroup("QGC_MAINWINDOW");
autoReconnect = settings.value("AUTO_RECONNECT", autoReconnect).toBool();
currentStyle = (QGC_MAINWINDOW_STYLE)settings.value("CURRENT_STYLE", currentStyle).toInt();
lowPowerMode = settings.value("LOW_POWER_MODE", lowPowerMode).toBool();
settings.endGroup();
}
void MainWindow::storeSettings()
{
QSettings settings;
settings.beginGroup("QGC_MAINWINDOW");
settings.setValue("AUTO_RECONNECT", autoReconnect);
settings.setValue("CURRENT_STYLE", currentStyle);
settings.endGroup();
if (!aboutToCloseFlag && isVisible())
{
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;
Mariano Lizarraga
committed
windowname.append(" (" + QHostInfo::localHostName() + ": ");
Mariano Lizarraga
committed
for (int i = 0; i < hostAddresses.size(); i++)
{
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;
}
}
Mariano Lizarraga
committed
Mariano Lizarraga
committed
Mariano Lizarraga
committed
#ifndef Q_WS_MAC
//qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png"));
Mariano Lizarraga
committed
#endif
}
{
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();
{
videoTimer->stop();
// TODO Convert raw images to PNG
}
{
QPixmap window = QPixmap::grabWindow(this->winId());
QString format = "bmp";
if (!screenFileName.isEmpty())
{
window.save(screenFileName, format.toAscii());
}
}
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."));
case QGC_MAINWINDOW_STYLE_INDOOR:
qApp->setStyle("plastique");
styleFileName = ":/images/style-mission.css";
reloadStylesheet();
break;
case QGC_MAINWINDOW_STYLE_OUTDOOR:
qApp->setStyle("plastique");
styleFileName = ":/images/style-outdoor.css";
reloadStylesheet();
break;
}
currentStyle = style;
}
void MainWindow::selectStylesheet()
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;
}
reloadStylesheet();
}
void MainWindow::reloadStylesheet()
{
// Load style sheet
QFile* styleSheet = new QFile(styleFileName);
styleSheet = new QFile(":/images/style-mission.css");
}
if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text)) {
QString style = QString(styleSheet->readAll());
style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/");
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)
/**
* 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)
}
void MainWindow::showCriticalMessage(const QString& title, const QString& message)
{
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)
{
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
*
**/
Mariano Lizarraga
committed
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.actionPilotsView);
perspectives->addAction(ui.actionOperatorsView);
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_PILOT) ui.actionPilotsView->setChecked(true);
if (currentView == VIEW_OPERATOR) ui.actionOperatorsView->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
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();
}