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"
MainWindow* MainWindow::instance()
{
static MainWindow* _instance = 0;
if(_instance == 0)
{
_instance = new MainWindow();
/* 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),
toolsMenuActions(),
currentView(VIEW_UNCONNECTED),
aboutToCloseFlag(false),
changingViewsFlag(false),
styleFileName(QCoreApplication::applicationDirPath() + "/style-indoor.css"),
autoReconnect(false),
currentStyle(QGC_MAINWINDOW_STYLE_INDOOR),
lowPowerMode(false),
centerStackActionGroup(this)
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();
// Setup UI state machines
centerStackActionGroup.setExclusive(true);
centerStack = new QStackedWidget(this);
setCentralWidget(centerStack);
Mariano Lizarraga
committed
buildCommonWidgets();
connectCommonWidgets();
Mariano Lizarraga
committed
configureWindowName();
loadStyle(currentStyle);
Mariano Lizarraga
committed
Mariano Lizarraga
committed
connectCommonActions();
// Set dock options
setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);
Mariano Lizarraga
committed
// Load mavlink view as default widget set
//loadMAVLinkView();
// Restore the window setup
if (settings.contains(getWindowStateKey()))
{
loadViewState();
}
if (settings.contains(getWindowGeometryKey()))
{
// Restore the window geometry
restoreGeometry(settings.value(getWindowGeometryKey()).toByteArray());
}
else
{
// Adjust the size
adjustSize();
}
// 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 flighgear test link
// FIXME MOVE INTO UAV OBJECT
fgLink = new QGCFlightGearLink();
fgLink->connectSimulation();
// Load Toolbar
toolBar = new QGCToolBar(this);
this->addToolBar(toolBar);
// Add actions
toolBar->addPerspectiveChangeAction(ui.actionOperatorsView);
toolBar->addPerspectiveChangeAction(ui.actionEngineersView);
toolBar->addPerspectiveChangeAction(ui.actionPilotsView);
// 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();
show();
// Store settings
storeSettings();
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();
delete dockWidget;
}
else
{
delete dynamic_cast<QObject*>(*i);
}
/**
* Set default settings for this AP type.
*/
void MainWindow::setDefaultSettingsForAp()
{
// Check if the settings exist, instantiate defaults if necessary
// // UNCONNECTED VIEW DEFAULT
//// QString centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_MAP, VIEW_UNCONNECTED);
// if (!settings.contains(centralKey)) {
// settings.setValue(centralKey,true);
// // ENABLE UAS LIST
//// settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_UAS_LIST, VIEW_UNCONNECTED), true);
// // ENABLE COMMUNICATION CONSOLE
//// settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_DEBUG_CONSOLE, VIEW_UNCONNECTED), true);
// }
// // OPERATOR VIEW DEFAULT
//// centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_MAP, VIEW_OPERATOR);
// if (!settings.contains(centralKey)) {
//// settings.setValue(centralKey,true);
// // ENABLE UAS LIST
//// settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_UAS_LIST,VIEW_OPERATOR), true);
// // ENABLE HUD TOOL WIDGET
//// settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HUD,VIEW_OPERATOR), true);
// // ENABLE WAYPOINTS
//// settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_WAYPOINTS,VIEW_OPERATOR), true);
// }
// // ENGINEER VIEW DEFAULT
// centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_LINECHART, VIEW_ENGINEER);
// if (!settings.contains(centralKey)) {
// settings.setValue(centralKey,true);
// // Enable Parameter widget
// settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_PARAMETERS,VIEW_ENGINEER), true);
// }
// // MAVLINK VIEW DEFAULT
// centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_PROTOCOL, VIEW_MAVLINK);
// if (!settings.contains(centralKey)) {
// settings.setValue(centralKey,true);
// }
// // PILOT VIEW DEFAULT
// centralKey = buildMenuKey(SUB_SECTION_CHECKED, CENTRAL_HUD, VIEW_PILOT);
// if (!settings.contains(centralKey)) {
// settings.setValue(centralKey,true);
// // Enable Flight display
// settings.setValue(buildMenuKey(SUB_SECTION_CHECKED,MainWindow::MENU_HDD_1,VIEW_PILOT), true);
// }
void MainWindow::resizeEvent(QResizeEvent * event)
{
Q_UNUSED(event);
if (height() < 800)
{
}
else
{
ui.statusBar->setSizeGripEnabled(true);
QString MainWindow::getWindowStateKey()
{
return QString::number(currentView)+"_windowstate";
}
QString MainWindow::getWindowGeometryKey()
{
//return QString::number(currentView)+"_geometry";
return "_geometry";
void MainWindow::buildCustomWidget()
{
// Show custom widgets only if UAS is connected
if (UASManager::instance()->getActiveUAS() != NULL)
{
// Create custom widgets
QList<QGCToolWidget*> widgets = QGCToolWidget::createWidgetsFromSettings(this);
if (widgets.size() > 0)
{
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);
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");
addTool(debugConsoleDockWidget, tr("Communication Console"), Qt::BottomDockWidgetArea);
}
Mariano Lizarraga
committed
if (!logPlayerDockWidget)
{
logPlayerDockWidget = new QDockWidget(tr("MAVLink Log Player"), this);
logPlayerDockWidget->setWidget( new QGCMAVLinkLogPlayer(mavlink, this) );
logPlayerDockWidget->setObjectName("MAVLINK_LOG_PLAYER_DOCKWIDGET");
addTool(logPlayerDockWidget, tr("MAVLink Log Replay"), Qt::RightDockWidgetArea);
}
Mariano Lizarraga
committed
// Center widgets
if (!mapWidget)
{
addCentralWidget(mapWidget, "Maps");
}
Mariano Lizarraga
committed
if (!protocolWidget)
{
protocolWidget = new XMLCommProtocolWidget(this);
addCentralWidget(protocolWidget, "Mavlink Generator");
}
if (!dataplotWidget)
{
addCentralWidget(dataplotWidget, "Logfile Plot");
//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");
acceptList->append("-60,rollspeed d/s,deg/s,+60,s");
acceptList->append("-60,pitchspeed d/s,deg/s,+60,s");
acceptList->append("-60,yawspeed d/s,deg/s,+60,s");
acceptList->append("0,airspeed,m/s,30");
acceptList->append("0,groundspeed,m/s,30");
acceptList->append("0,climbrate,m/s,30");
acceptList->append("0,throttle,%,100");
Mariano Lizarraga
committed
//FIXME: memory of acceptList2 will never be freed again
QStringList* acceptList2 = new QStringList();
acceptList2->append("900,servo #1,us,2100,s");
acceptList2->append("900,servo #2,us,2100,s");
acceptList2->append("900,servo #3,us,2100,s");
acceptList2->append("900,servo #4,us,2100,s");
acceptList2->append("900,servo #5,us,2100,s");
acceptList2->append("900,servo #6,us,2100,s");
acceptList2->append("900,servo #7,us,2100,s");
acceptList2->append("900,servo #8,us,2100,s");
//acceptList2->append("-2048,accel. x,raw,2048,s");
//acceptList2->append("-2048,accel. y,raw,2048,s");
//acceptList2->append("-2048,accel. z,raw,2048,s");
Mariano Lizarraga
committed
hudWidget = new HUD(320, 240, this);
addCentralWidget(hudWidget, tr("Head Up Display"));
}
Mariano Lizarraga
committed
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
}
#if (defined _MSC_VER) | (defined Q_OS_MAC)
gEarthWidget = new QGCGoogleEarthView(this);
addCentralWidget(gEarthWidget, tr("Google Earth"));
}
Mariano Lizarraga
committed
pixhawk
committed
#endif
detectionDockWidget = new QDockWidget(tr("Object Recognition"), this);
detectionDockWidget->setWidget( new ObjectDetectionView("images/patterns", this) );
detectionDockWidget->setObjectName("OBJECT_DETECTION_DOCK_WIDGET");
addTool(detectionDockWidget, tr("Object Recognition"), Qt::RightDockWidgetArea);
}
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);
}
Mariano Lizarraga
committed
watchdogControlDockWidget = new QDockWidget(tr("Process Control"), this);
watchdogControlDockWidget->setWidget( new WatchdogControl(this) );
watchdogControlDockWidget->setObjectName("WATCHDOG_CONTROL_DOCKWIDGET");
addTool(watchdogControlDockWidget, tr("Process Control"), Qt::BottomDockWidgetArea);
}
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);
}
headDown1DockWidget = new QDockWidget(tr("Flight Display"), this);
headDown1DockWidget->setWidget( new HDDisplay(acceptList, "Flight Display", this) );
headDown1DockWidget->setObjectName("HEAD_DOWN_DISPLAY_1_DOCK_WIDGET");
addTool(headDown1DockWidget, tr("Flight Display"), Qt::RightDockWidgetArea);
}
headDown2DockWidget = new QDockWidget(tr("Actuator Status"), this);
headDown2DockWidget->setWidget( new HDDisplay(acceptList2, "Actuator Status", this) );
headDown2DockWidget->setObjectName("HEAD_DOWN_DISPLAY_2_DOCK_WIDGET");
addTool(headDown2DockWidget, tr("Actuator Status"), Qt::RightDockWidgetArea);
}
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);
}
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);
}
pixhawk
committed
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);
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);
}
pixhawk
committed
// Custom widgets, added last to all menus and layouts
buildCustomWidget();
// Dialogue widgets
//FIXME: free memory in destructor
Mariano Lizarraga
committed
}
Mariano Lizarraga
committed
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)));
}
// //TODO temporaly debug
// if (slugsHilSimWidget && slugsHilSimWidget->widget()) {
// connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)),
// slugsHilSimWidget->widget(), SLOT(activeUasSet(UASInterface*)));
// }
lm
committed
}
Mariano Lizarraga
committed
lm
committed
void MainWindow::createCustomWidget()
{
QDockWidget* dock = new QDockWidget("Unnamed Tool", this);
QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool", dock);
if (QGCToolWidget::instances()->size() < 2) {
// 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);
// dock->setObjectName();
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);
}
else
{
return;
Mariano Lizarraga
committed
}
void MainWindow::loadCustomWidgetsFromDefaults(const QString& systemType, const QString& autopilotType)
{
QString defaultsDir = qApp->applicationDirPath() + "/files/" + systemType.toLower() + "/" + autopilotType.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;
}
// 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
qDebug() << "Tried to load file: " << file;
loadCustomWidget(defaultsDir+"/"+file, true);
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();
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*)));