Newer
Older
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2013 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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 <QSplashScreen>
#include <QGCHilLink.h>
#include <QGCHilConfiguration.h>
#include <QGCHilFlightGearConfiguration.h>
#include "dockwidgettitlebareventfilter.h"
#include "QGC.h"
#include "MAVLinkSimulationLink.h"
#include "SerialLink.h"
#include "UDPLink.h"
#include "MAVLinkProtocol.h"
#include "CommConfigurationWindow.h"
#include "QGCWaypointListMulti.h"
#include "MainWindow.h"
#include "JoystickWidget.h"
#include "GAudioOutput.h"
#include "QGCToolWidget.h"
#include "QGCMAVLinkLogPlayer.h"
#include "QGCSettingsWidget.h"
#include "QGCMapTool.h"
#include "MAVLinkDecoder.h"
#include "QGCMAVLinkMessageSender.h"
#include "QGCRGBDView.h"
#include "QGCFirmwareUpdate.h"
#include "QGCStatusBar.h"
Michael Carpenter
committed
#include "UASQuickView.h"
Michael Carpenter
committed
#include "UASActionsWidget.h"
#include "QGCTabbedInfoView.h"
#include "UASRawStatusView.h"
dongfang
committed
#include "PrimaryFlightDisplay.h"
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifdef QGC_OSG_ENABLED
#include "Q3DWidgetFactory.h"
#endif
// FIXME Move
#include "PxQuadMAV.h"
#include "SlugsMAV.h"
#include "LogCompressor.h"
MainWindow* MainWindow::instance(QSplashScreen* screen)
{
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()
**/
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
currentView(VIEW_FLIGHT),
currentStyle(QGC_MAINWINDOW_STYLE_INDOOR),
aboutToCloseFlag(false),
changingViewsFlag(false),
centerStackActionGroup(new QActionGroup(this)),
styleFileName(QCoreApplication::applicationDirPath() + "/style-indoor.css"),
autoReconnect(false),
lowPowerMode(false)
{
Michael Carpenter
committed
this->setAttribute(Qt::WA_DeleteOnClose);
Michael Carpenter
committed
dockWidgetTitleBarEnabled = true;
Michael Carpenter
committed
isAdvancedMode = false;
emit initStatusChanged("Loading UI Settings..");
loadSettings();
emit initStatusChanged("Loading Style.");
loadStyle(currentStyle);
Michael Carpenter
committed
if (settings.contains("ADVANCED_MODE"))
{
isAdvancedMode = settings.value("ADVANCED_MODE").toBool();
}
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_MISSION &&
currentViewCandidate != VIEW_FLIGHT &&
currentViewCandidate != VIEW_FULL)
{
currentView = currentViewCandidate;
}
}
settings.sync();
emit initStatusChanged("Setting up user interface.");
// Setup user interface
ui.setupUi(this);
hide();
// We only need this menu if we have more than one system
Lorenz Meier
committed
// ui.menuConnected_Systems->setEnabled(false);
// Set dock options
setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);
configureWindowName();
// Setup corners
setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
// Setup UI state machines
Lorenz Meier
committed
centerStackActionGroup->setExclusive(true);
centerStack = new QStackedWidget(this);
setCentralWidget(centerStack);
// Load Toolbar
toolBar = new QGCToolBar(this);
this->addToolBar(toolBar);
// Add actions for average users (displayed next to each other)
actions << ui.actionFlightView;
actions << ui.actionMissionView;
Michael Carpenter
committed
//actions << ui.actionConfiguration_2;
actions << ui.actionHardwareConfig;
actions << ui.actionSoftwareConfig;
// Add actions for advanced users (displayed in dropdown under "advanced")
QList<QAction*> advancedActions;
advancedActions << ui.actionSimulation_View;
advancedActions << ui.actionEngineersView;
toolBar->setPerspectiveChangeAdvancedActions(advancedActions);
customStatusBar = new QGCStatusBar(this);
setStatusBar(customStatusBar);
statusBar()->setSizeGripEnabled(true);
Michael Carpenter
committed
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
emit initStatusChanged("Building common widgets.");
buildCommonWidgets();
connectCommonWidgets();
emit initStatusChanged("Building common actions.");
// Create actions
connectCommonActions();
// Populate link menu
emit initStatusChanged("Populating 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
emit initStatusChanged("Initializing joystick interface.");
joystickWidget = 0;
joystick = new JoystickInput();
#ifdef MOUSE_ENABLED_WIN
emit initStatusChanged("Initializing 3D mouse interface.");
mouseInput = new Mouse3DInput(this);
mouse = new Mouse6dofInput(mouseInput);
#endif //MOUSE_ENABLED_WIN
#if MOUSE_ENABLED_LINUX
emit initStatusChanged("Initializing 3D mouse interface.");
mouse = new Mouse6dofInput(this);
Matthias Krebs
committed
connect(this, SIGNAL(x11EventOccured(XEvent*)), mouse, SLOT(handleX11Event(XEvent*)));
#endif //MOUSE_ENABLED_LINUX
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
// 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();
emit initStatusChanged("Restoring last view state.");
// Restore the window setup
loadViewState();
emit initStatusChanged("Restoring last window size.");
// 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();
resize(screenWidth, screenHeight - 80);
show();
}
else
{
resize(screenWidth*0.67f, qMin(screenHeight, (int)(screenWidth*0.67f*0.67f)));
show();
}
}
connect(&windowNameUpdateTimer, SIGNAL(timeout()), this, SLOT(configureWindowName()));
windowNameUpdateTimer.start(15000);
emit initStatusChanged("Done.");
show();
}
MainWindow::~MainWindow()
{
if (mavlink)
{
delete mavlink;
mavlink = NULL;
}
Lorenz Meier
committed
// if (simulationLink)
// {
// simulationLink->deleteLater();
// simulationLink = NULL;
// }
if (joystick)
{
joystick->shutdown();
joystick->wait(5000);
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
delete joystick;
joystick = NULL;
}
// 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;
dockWidget = NULL;
}
else if (dynamic_cast<QWidget*>(*i))
{
delete dynamic_cast<QWidget*>(*i);
*i = NULL;
}
}
// Delete all UAS objects
Michael Carpenter
committed
if (debugConsole)
{
delete debugConsole;
}
for (int i=0;i<commsWidgetList.size();i++)
{
commsWidgetList[i]->deleteLater();
}
}
void MainWindow::resizeEvent(QResizeEvent * event)
{
if (width() > 1200)
{
toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
}
else
{
toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
}
QMainWindow::resizeEvent(event);
}
QString MainWindow::getWindowStateKey()
{
Michael Carpenter
committed
if (UASManager::instance()->getActiveUAS())
{
return QString::number(currentView)+"_windowstate_" + UASManager::instance()->getActiveUAS()->getAutopilotTypeName();
}
else
Lorenz Meier
committed
return QString::number(currentView)+"_windowstate";
}
QString MainWindow::getWindowGeometryKey()
{
//return QString::number(currentView)+"_geometry";
return "_geometry";
}
void MainWindow::buildCustomWidget()
{
// 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)
{
Michael Carpenter
committed
QSettings settings;
settings.beginGroup("QGC_MAINWINDOW");
/*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);
Michael Carpenter
committed
ui.menuTools->addAction(showAction);*/
// Load dock widget location (default is bottom)
Qt::DockWidgetArea location = static_cast <Qt::DockWidgetArea>(tool->getDockWidgetArea(currentView));
Michael Carpenter
committed
//addDockWidget(location, dock);
//dock->hide();
int view = settings.value(QString("TOOL_PARENT_") + tool->objectName(),-1).toInt();
//settings.setValue(QString("TOOL_PARENT_") + "UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size()),currentView);
settings.endGroup();
Michael Carpenter
committed
switch (view)
{
case VIEW_ENGINEER:
Lorenz Meier
committed
dock = createDockWidget(engineeringView,tool,tool->getTitle(),tool->objectName(),(VIEW_SECTIONS)view,location);
Michael Carpenter
committed
break;
case VIEW_FLIGHT:
dock = createDockWidget(pilotView,tool,tool->getTitle(),tool->objectName(),(VIEW_SECTIONS)view,location);
Michael Carpenter
committed
break;
case VIEW_SIMULATION:
dock = createDockWidget(simView,tool,tool->getTitle(),tool->objectName(),(VIEW_SECTIONS)view,location);
Michael Carpenter
committed
break;
case VIEW_MISSION:
dock = createDockWidget(plannerView,tool,tool->getTitle(),tool->objectName(),(VIEW_SECTIONS)view,location);
Michael Carpenter
committed
break;
Lorenz Meier
committed
case VIEW_MAVLINK:
dock = createDockWidget(mavlinkView,tool,tool->getTitle(),tool->objectName(),(VIEW_SECTIONS)view,location);
break;
Michael Carpenter
committed
default:
dock = createDockWidget(centerStack->currentWidget(),tool,tool->getTitle(),tool->objectName(),(VIEW_SECTIONS)view,location);
Michael Carpenter
committed
break;
}
// XXX temporary "fix"
dock->hide();
Michael Carpenter
committed
//createDockWidget(0,tool,tool->getTitle(),tool->objectName(),view,location);
}
}
}
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);
// Log player
logPlayer = new QGCMAVLinkLogPlayer(mavlink, customStatusBar);
customStatusBar->setLogPlayer(logPlayer);
Michael Carpenter
committed
// Center widgets
if (!plannerView)
{
plannerView = new SubMainWindow(this);
plannerView->setCentralWidget(new QGCMapTool(this));
//mapWidget = new QGCMapTool(this);
addCentralWidget(plannerView, "Maps");
}
//pilotView
if (!pilotView)
{
pilotView = new SubMainWindow(this);
pilotView->setObjectName("VIEW_FLIGHT");
pilotView->setCentralWidget(new QGCMapTool(this));
Michael Carpenter
committed
addCentralWidget(pilotView, "Pilot");
}
if (!configView)
{
configView = new SubMainWindow(this);
Michael Carpenter
committed
configView->setObjectName("VIEW_HARDWARE_CONFIG");
configView->setCentralWidget(new ApmHardwareConfig(this));
addCentralWidget(configView,"Hardware");
centralWidgetToDockWidgetsMap[VIEW_HARDWARE_CONFIG] = QMap<QString,QWidget*>();
Michael Carpenter
committed
}
Michael Carpenter
committed
if (!softwareConfigView)
{
softwareConfigView = new SubMainWindow(this);
softwareConfigView->setObjectName("VIEW_SOFTWARE_CONFIG");
softwareConfigView->setCentralWidget(new ApmSoftwareConfig(this));
addCentralWidget(softwareConfigView,"Software");
centralWidgetToDockWidgetsMap[VIEW_SOFTWARE_CONFIG] = QMap<QString,QWidget*>();
}
Michael Carpenter
committed
if (!engineeringView)
{
engineeringView = new SubMainWindow(this);
engineeringView->setObjectName("VIEW_ENGINEER");
Lorenz Meier
committed
engineeringView->setCentralWidget(new QGCDataPlot2D(this));
addCentralWidget(engineeringView,tr("Logfile Plot"));
Michael Carpenter
committed
}
Lorenz Meier
committed
if (!mavlinkView)
Michael Carpenter
committed
{
Lorenz Meier
committed
mavlinkView = new SubMainWindow(this);
mavlinkView->setObjectName("VIEW_MAVLINK");
mavlinkView->setCentralWidget(new XMLCommProtocolWidget(this));
addCentralWidget(mavlinkView,tr("Mavlink Generator"));
Michael Carpenter
committed
}
if (!simView)
{
simView = new SubMainWindow(this);
simView->setObjectName("VIEW_SIMULATOR");
simView->setCentralWidget(new QGCMapTool(this));
addCentralWidget(simView,tr("Simulation View"));
}
Michael Carpenter
committed
QAction* tempAction = ui.menuTools->addAction(tr("Control"));
tempAction->setCheckable(true);
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
Lorenz Meier
committed
createDockWidget(simView,new UASControlWidget(this),tr("Control"),"UNMANNED_SYSTEM_CONTROL_DOCKWIDGET",VIEW_SIMULATION,Qt::LeftDockWidgetArea);
Lorenz Meier
committed
createDockWidget(plannerView,new UASListWidget(this),tr("Unmanned Systems"),"UNMANNED_SYSTEM_LIST_DOCKWIDGET",VIEW_MISSION,Qt::LeftDockWidgetArea);
createDockWidget(plannerView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_MISSION,Qt::BottomDockWidgetArea);
Lorenz Meier
committed
{
//createDockWidget(plannerView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_MISSION,Qt::BottomDockWidgetArea);
QAction* tempAction = ui.menuTools->addAction(tr("Mission Plan"));
tempAction->setCheckable(true);
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
menuToDockNameMap[tempAction] = "WAYPOINT_LIST_DOCKWIDGET";
Lorenz Meier
committed
}
Lorenz Meier
committed
createDockWidget(simView,new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",VIEW_SIMULATION,Qt::BottomDockWidgetArea);
createDockWidget(engineeringView,new QGCMAVLinkInspector(mavlink,this),tr("MAVLink Inspector"),"MAVLINK_INSPECTOR_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea);
Michael Carpenter
committed
Lorenz Meier
committed
createDockWidget(engineeringView,new ParameterInterface(this),tr("Onboard Parameters"),"PARAMETER_INTERFACE_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea);
createDockWidget(simView,new ParameterInterface(this),tr("Onboard Parameters"),"PARAMETER_INTERFACE_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea);
Michael Carpenter
committed
Lorenz Meier
committed
{
Michael Carpenter
committed
QAction* tempAction = ui.menuTools->addAction(tr("Status Details"));
Michael Carpenter
committed
menuToDockNameMap[tempAction] = "UAS_STATUS_DETAILS_DOCKWIDGET";
Michael Carpenter
committed
tempAction->setCheckable(true);
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
Lorenz Meier
committed
}
{
Michael Carpenter
committed
if (!debugConsole)
{
debugConsole = new DebugConsole();
debugConsole->setWindowTitle("Communications Console");
debugConsole->hide();
Michael Carpenter
committed
QAction* tempAction = ui.menuTools->addAction(tr("Communication Console"));
//menuToDockNameMap[tempAction] = "COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET";
tempAction->setCheckable(true);
connect(tempAction,SIGNAL(triggered(bool)),debugConsole,SLOT(setShown(bool)));
}
Lorenz Meier
committed
}
createDockWidget(simView,new HSIDisplay(this),tr("Horizontal Situation"),"HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET",VIEW_SIMULATION,Qt::BottomDockWidgetArea);
Michael Carpenter
committed
//FIXME: memory of acceptList will never be freed again
QStringList* acceptList = new QStringList();
acceptList->append("-3.3,ATTITUDE.roll,rad,+3.3,s");
acceptList->append("-3.3,ATTITUDE.pitch,deg,+3.3,s");
acceptList->append("-3.3,ATTITUDE.yaw,deg,+3.3,s");
//FIXME: memory of acceptList2 will never be freed again
QStringList* acceptList2 = new QStringList();
acceptList2->append("0,RAW_PRESSURE.pres_abs,hPa,65500");
//HDDisplay* hdDisplay = new HDDisplay(acceptList, "Flight Display", this);
//hdDisplay->addSource(mavlinkDecoder);
//createDockWidget(pilotView,hdDisplay,tr("Flight Display"),"HEAD_DOWN_DISPLAY_1_DOCKWIDGET",VIEW_FLIGHT,Qt::RightDockWidgetArea);
//HDDisplay* hdDisplay2 = new HDDisplay(acceptList2, "Actuator Status", this);
//hdDisplay2->addSource(mavlinkDecoder);
//createDockWidget(pilotView,hdDisplay2,tr("Actuator Status"),"HEAD_DOWN_DISPLAY_2_DOCKWIDGET",VIEW_FLIGHT,Qt::RightDockWidgetArea);
Lorenz Meier
committed
QAction* tempAction = ui.menuTools->addAction(tr("Flight Display"));
tempAction->setCheckable(true);
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
menuToDockNameMap[tempAction] = "HEAD_DOWN_DISPLAY_1_DOCKWIDGET";
Lorenz Meier
committed
QAction* tempAction = ui.menuTools->addAction(tr("Actuator Status"));
tempAction->setCheckable(true);
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
menuToDockNameMap[tempAction] = "HEAD_DOWN_DISPLAY_2_DOCKWIDGET";
{
Lorenz Meier
committed
QAction* tempAction = ui.menuTools->addAction(tr("Radio Control"));
tempAction->setCheckable(true);
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
}
Michael Carpenter
committed
createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5);
createDockWidget(engineeringView,new HUD(320,240,this),tr("Video Downlink"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_ENGINEER,Qt::RightDockWidgetArea,this->width()/1.5);
createDockWidget(simView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_SIMULATION,Qt::RightDockWidgetArea,this->width()/1.5);
createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8);
Michael Carpenter
committed
// Create the APM Toolbar
APMToolBar *apmToolBar = new APMToolBar(this);
apmToolBar->setFlightViewAction(ui.actionFlightView);
apmToolBar->setFlightPlanViewAction(ui.actionMissionView);
apmToolBar->setHardwareViewAction(ui.actionHardwareConfig);
apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig);
apmToolBar->setSimulationViewAction(ui.actionSimulation_View);
apmToolBar->setTerminalViewAction(ui.actionSimulation_View);
createDockWidget(pilotView,apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70);
Michael Carpenter
committed
QGCTabbedInfoView *infoview = new QGCTabbedInfoView(this);
infoview->addSource(mavlinkDecoder);
Michael Carpenter
committed
createDockWidget(pilotView,infoview,tr("Info View"),"UAS_INFO_INFOVIEW_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea);
dongfang
committed
//createDockWidget(pilotView,new HUD(320,240,this),tr("Head Up Display"),"HEAD_UP_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8);
// createDockWidget(pilotView,new UASQuickView(this),tr("Quick View"),"UAS_INFO_QUICKVIEW_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea);
// createDockWidget(pilotView,new HSIDisplay(this),tr("Horizontal Situation"),"HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea);
// pilotView->setTabPosition(Qt::LeftDockWidgetArea,QTabWidget::North);
// pilotView->tabifyDockWidget((QDockWidget*)centralWidgetToDockWidgetsMap[VIEW_FLIGHT]["HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET"],(QDockWidget*)centralWidgetToDockWidgetsMap[VIEW_FLIGHT]["UAS_INFO_QUICKVIEW_DOCKWIDGET"]);
//UASRawStatusView *view = new UASRawStatusView();
//view->setDecoder(mavlinkDecoder);
//view->show();
//hddisplay->addSource(mavlinkDecoder);
Michael Carpenter
committed
//createDockWidget(pilotView,new HSIDisplay(this),tr("Horizontal Situation"),"HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea);
//pilotView->setTabPosition(Qt::LeftDockWidgetArea,QTabWidget::North);
//pilotView->tabifyDockWidget((QDockWidget*)centralWidgetToDockWidgetsMap[VIEW_FLIGHT]["HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET"],(QDockWidget*)centralWidgetToDockWidgetsMap[VIEW_FLIGHT]["UAS_INFO_QUICKVIEW_DOCKWIDGET"]);
Michael Carpenter
committed
//createDockWidget(pilotView,new UASActionsWidget(this),tr("Actions"),"UNMANNED_SYSTEM_ACTION_DOCKWIDGET",VIEW_FLIGHT,Qt::RightDockWidgetArea);
// Custom widgets, added last to all menus and layouts
buildCustomWidget();
Michael Carpenter
committed
/*if (!protocolWidget)
{
protocolWidget = new XMLCommProtocolWidget(this);
addCentralWidget(protocolWidget, "Mavlink Generator");
Michael Carpenter
committed
}*/
Lorenz Meier
committed
// if (!firmwareUpdateWidget)
// {
// firmwareUpdateWidget = new QGCFirmwareUpdate(this);
// addCentralWidget(firmwareUpdateWidget, "Firmware Update");
// }
Michael Carpenter
committed
/*if (!hudWidget)
{
hudWidget = new HUD(320, 240, this);
addCentralWidget(hudWidget, tr("Head Up Display"));
Michael Carpenter
committed
}*/
Michael Carpenter
committed
/*if (!configWidget)
{
configWidget = new QGCVehicleConfig(this);
addCentralWidget(configWidget, tr("Vehicle Configuration"));
Michael Carpenter
committed
}*/
Michael Carpenter
committed
/*if (!dataplotWidget)
{
dataplotWidget = new QGCDataPlot2D(this);
addCentralWidget(dataplotWidget, tr("Logfile Plot"));
Michael Carpenter
committed
}*/
#ifdef QGC_OSG_ENABLED
if (!_3DWidget)
{
_3DWidget = Q3DWidgetFactory::get("PIXHAWK", this);
addCentralWidget(_3DWidget, tr("Local 3D"));
}
#endif
#if (defined _MSC_VER) | (defined Q_OS_MAC)
if (!gEarthWidget)
{
gEarthWidget = new QGCGoogleEarthView(this);
addCentralWidget(gEarthWidget, tr("Google Earth"));
}
#endif
}
Michael Carpenter
committed
void MainWindow::addTool(SubMainWindow *parent,VIEW_SECTIONS view,QDockWidget* widget, const QString& title, Qt::DockWidgetArea area)
Michael Carpenter
committed
QList<QAction*> actionlist = ui.menuTools->actions();
bool found = false;
QAction *targetAction;
Michael Carpenter
committed
for (int i=0;i<actionlist.size();i++)
{
if (actionlist[i]->text() == title)
{
found = true;
targetAction = actionlist[i];
Michael Carpenter
committed
}
}
if (!found)
{
QAction* tempAction = ui.menuTools->addAction(title);
tempAction->setCheckable(true);
Michael Carpenter
committed
menuToDockNameMap[tempAction] = widget->objectName();
Michael Carpenter
committed
if (!centralWidgetToDockWidgetsMap.contains(view))
{
centralWidgetToDockWidgetsMap[view] = QMap<QString,QWidget*>();
}
Michael Carpenter
committed
centralWidgetToDockWidgetsMap[view][widget->objectName()]= widget;
Michael Carpenter
committed
connect(tempAction,SIGNAL(triggered(bool)),this, SLOT(showTool(bool)));
connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool)));
tempAction->setChecked(widget->isVisible());
}
else
{
if (!menuToDockNameMap.contains(targetAction))
{
Michael Carpenter
committed
menuToDockNameMap[targetAction] = widget->objectName();
//menuToDockNameMap[targetAction] = title;
}
if (!centralWidgetToDockWidgetsMap.contains(view))
{
centralWidgetToDockWidgetsMap[view] = QMap<QString,QWidget*>();
}
Michael Carpenter
committed
centralWidgetToDockWidgetsMap[view][widget->objectName()]= widget;
connect(widget, SIGNAL(visibilityChanged(bool)), targetAction, SLOT(setChecked(bool)));
}
Michael Carpenter
committed
parent->addDockWidget(area,widget);
QDockWidget* MainWindow::createDockWidget(QWidget *parent,QWidget *child,QString title,QString objectname,VIEW_SECTIONS view,Qt::DockWidgetArea area,int minwidth,int minheight)
{
Michael Carpenter
committed
//if (child->objectName() == "")
//{
Lorenz Meier
committed
child->setObjectName(objectname);
Michael Carpenter
committed
//}
QDockWidget *widget = new QDockWidget(title,this);
Michael Carpenter
committed
if (!isAdvancedMode)
{
Michael Carpenter
committed
if (dockWidgetTitleBarEnabled)
{
dockToTitleBarMap[widget] = widget->titleBarWidget();
QLabel *label = new QLabel(this);
label->setText(title);
widget->setTitleBarWidget(label);
label->installEventFilter(new DockWidgetTitleBarEventFilter());
Michael Carpenter
committed
}
else
{
dockToTitleBarMap[widget] = widget->titleBarWidget();
widget->setTitleBarWidget(new QWidget(this));
}
Michael Carpenter
committed
}
else
{
Michael Carpenter
committed
QLabel *label = new QLabel(this);
label->setText(title);
dockToTitleBarMap[widget] = label;
label->installEventFilter(new DockWidgetTitleBarEventFilter());
label->hide();
Michael Carpenter
committed
}
Michael Carpenter
committed
widget->setObjectName(child->objectName());
widget->setWidget(child);
if (minheight != 0 || minwidth != 0)
{
widget->setMinimumHeight(minheight);
widget->setMinimumWidth(minwidth);
}
addTool(qobject_cast<SubMainWindow*>(parent),view,widget,title,area);
}
Michael Carpenter
committed
void MainWindow::loadDockWidget(QString name)
{
if (centralWidgetToDockWidgetsMap[currentView].contains(name))
{
return;
}
Michael Carpenter
committed
if (name.startsWith("HIL_CONFIG"))
{
//It's a HIL widget.
showHILConfigurationWidget(UASManager::instance()->getActiveUAS());
}
else if (name == "UNMANNED_SYSTEM_CONTROL_DOCKWIDGET")
Michael Carpenter
committed
{
createDockWidget(centerStack->currentWidget(),new UASControlWidget(this),tr("Control"),"UNMANNED_SYSTEM_CONTROL_DOCKWIDGET",currentView,Qt::LeftDockWidgetArea);
}
else if (name == "UNMANNED_SYSTEM_LIST_DOCKWIDGET")
{
createDockWidget(centerStack->currentWidget(),new UASListWidget(this),tr("Unmanned Systems"),"UNMANNED_SYSTEM_LIST_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
}
else if (name == "WAYPOINT_LIST_DOCKWIDGET")
{
createDockWidget(centerStack->currentWidget(),new QGCWaypointListMulti(this),tr("Mission Plan"),"WAYPOINT_LIST_DOCKWIDGET",currentView,Qt::BottomDockWidgetArea);
}
else if (name == "MAVLINK_INSPECTOR_DOCKWIDGET")
{
createDockWidget(centerStack->currentWidget(),new QGCMAVLinkInspector(mavlink,this),tr("MAVLink Inspector"),"MAVLINK_INSPECTOR_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
}
else if (name == "PARAMETER_INTERFACE_DOCKWIDGET")
{
createDockWidget(centerStack->currentWidget(),new ParameterInterface(this),tr("Onboard Parameters"),"PARAMETER_INTERFACE_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
}
else if (name == "UAS_STATUS_DETAILS_DOCKWIDGET")
{
createDockWidget(centerStack->currentWidget(),new UASInfoWidget(this),tr("Status Details"),"UAS_STATUS_DETAILS_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
}
else if (name == "COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET")
{
Michael Carpenter
committed
//This is now a permanently detached window.
//centralWidgetToDockWidgetsMap[currentView][name] = console;
//createDockWidget(centerStack->currentWidget(),new DebugConsole(this),tr("Communication Console"),"COMMUNICATION_DEBUG_CONSOLE_DOCKWIDGET",currentView,Qt::BottomDockWidgetArea);
Michael Carpenter
committed
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
}
else if (name == "HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET")
{
createDockWidget(centerStack->currentWidget(),new HSIDisplay(this),tr("Horizontal Situation"),"HORIZONTAL_SITUATION_INDICATOR_DOCKWIDGET",currentView,Qt::BottomDockWidgetArea);
}
else if (name == "HEAD_DOWN_DISPLAY_1_DOCKWIDGET")
{
//FIXME: memory of acceptList will never be freed again
QStringList* acceptList = new QStringList();
acceptList->append("-3.3,ATTITUDE.roll,rad,+3.3,s");
acceptList->append("-3.3,ATTITUDE.pitch,deg,+3.3,s");
acceptList->append("-3.3,ATTITUDE.yaw,deg,+3.3,s");
HDDisplay *hddisplay = new HDDisplay(acceptList,"Flight Display",this);
hddisplay->addSource(mavlinkDecoder);
createDockWidget(centerStack->currentWidget(),hddisplay,tr("Flight Display"),"HEAD_DOWN_DISPLAY_1_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
}
else if (name == "HEAD_DOWN_DISPLAY_2_DOCKWIDGET")
{
//FIXME: memory of acceptList2 will never be freed again
QStringList* acceptList2 = new QStringList();
acceptList2->append("0,RAW_PRESSURE.pres_abs,hPa,65500");
HDDisplay *hddisplay = new HDDisplay(acceptList2,"Actuator Status",this);
hddisplay->addSource(mavlinkDecoder);
createDockWidget(centerStack->currentWidget(),hddisplay,tr("Actuator Status"),"HEAD_DOWN_DISPLAY_2_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
}
else if (name == "Radio Control")
{
qDebug() << "Error loading window:" << name << "Unknown window type";
//createDockWidget(centerStack->currentWidget(),hddisplay,tr("Actuator Status"),"HEADS_DOWN_DISPLAY_2_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
}
dongfang
committed
else if (name == "PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET")
Michael Carpenter
committed
{
dongfang
committed
// createDockWidget(centerStack->currentWidget(),new HUD(320,240,this),tr("Head Up Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
createDockWidget(centerStack->currentWidget(),new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"HEAD_UP_DISPLAY_DOCKWIDGET",currentView,Qt::RightDockWidgetArea);
Michael Carpenter
committed
}
Michael Carpenter
committed
else if (name == "UAS_INFO_QUICKVIEW_DOCKWIDGET")
{
createDockWidget(centerStack->currentWidget(),new UASQuickView(this),tr("Quick View"),"UAS_INFO_QUICKVIEW_DOCKWIDGET",currentView,Qt::LeftDockWidgetArea);
}
else if (name == "APM_TOOLBAR_DOCKWIDGET")
{
// Add Our new 'toolbar'
// Create the APM Toolbar
APMToolBar *apmToolBar = new APMToolBar(this);
apmToolBar->setFlightViewAction(ui.actionFlightView);
apmToolBar->setFlightPlanViewAction(ui.actionMissionView);
apmToolBar->setHardwareViewAction(ui.actionHardwareConfig);
apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig);
apmToolBar->setSimulationViewAction(ui.actionSimulation_View);
apmToolBar->setTerminalViewAction(ui.actionSimulation_View);
createDockWidget(centerStack->currentWidget(),apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",currentView,Qt::TopDockWidgetArea,this->width(), 70);
Michael Carpenter
committed
else
{
Michael Carpenter
committed
if (customWidgetNameToFilenameMap.contains(name))
{
loadCustomWidget(customWidgetNameToFilenameMap[name],currentView);
//customWidgetNameToFilenameMap.remove(name);
}
else
{
qDebug() << "Error loading window:" << name;
}
Michael Carpenter
committed
}
}
void MainWindow::showTool(bool show)
{
Michael Carpenter
committed
//Called when a menu item is clicked on, regardless of view.
QAction* act = qobject_cast<QAction *>(sender());
Michael Carpenter
committed
if (menuToDockNameMap.contains(act))
{
QString name = menuToDockNameMap[act];
if (centralWidgetToDockWidgetsMap.contains(currentView))
{
if (centralWidgetToDockWidgetsMap[currentView].contains(name))
{
if (show)
{
centralWidgetToDockWidgetsMap[currentView][name]->show();
}
else
{
centralWidgetToDockWidgetsMap[currentView][name]->hide();
}
Michael Carpenter
committed
}
else if (show)
Michael Carpenter
committed
{
Michael Carpenter
committed
loadDockWidget(name);
Michael Carpenter
committed
}
}
}
//QWidget* widget = qVariantValue<QWidget *>(act->data());
//widget->setVisible(show);
}
/*void addToolByName(QString name,SubMainWindow parent,const QString& title, Qt::DockWidgetArea area)
{
if (name == "Control")
{
QDockWidget *widget = new QDockWidget(tr("Control"),this);
dockToTitleBarMap[widget] = widget->titleBarWidget();
widget->setObjectName("UNMANNED_SYSTEM_CONTROL_DOCKWIDGET");
widget->setWidget(new UASControlWidget(this));
addTool(parent,VIEW_SIMULATION,widget,tr("Control"),area);
}
}*/
void MainWindow::addCentralWidget(QWidget* widget, const QString& title)
{
// Check if this widget already has been added
if (centerStack->indexOf(widget) == -1)
{
centerStack->addWidget(widget);
Lorenz Meier
committed
// QAction* tempAction = ui.menuMain->addAction(title);
Lorenz Meier
committed
// 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)));
Lorenz Meier
committed
// tempAction->setChecked(widget->isVisible());
}
}
void MainWindow::showCentralWidget()
{
QAction* act = qobject_cast<QAction *>(sender());
QWidget* widget = qVariantValue<QWidget *>(act->data());
centerStack->setCurrentWidget(widget);
}
void MainWindow::showHILConfigurationWidget(UASInterface* uas)
{
// Add simulation configuration widget
UAS* mav = dynamic_cast<UAS*>(uas);
if (mav && !hilDocks.contains(mav->getUASID()))
//QGCToolWidget* tool = new QGCToolWidget("Unnamed Tool " + QString::number(ui.menuTools->actions().size()));
//createDockWidget(centerStack->currentWidget(),tool,"Unnamed Tool " + QString::number(ui.menuTools->actions().size()),"UNNAMED_TOOL_" + QString::number(ui.menuTools->actions().size())+"DOCK",currentView,Qt::BottomDockWidgetArea);
QGCHilConfiguration* hconf = new QGCHilConfiguration(mav, this);
QString hilDockName = tr("HIL Config %1").arg(uas->getUASName());
Lorenz Meier
committed
QDockWidget* hilDock = createDockWidget(simView, hconf,hilDockName, hilDockName.toUpper().replace(" ", "_"),VIEW_SIMULATION,Qt::LeftDockWidgetArea);
hilDocks.insert(mav->getUASID(), hilDock);
Lorenz Meier
committed
// if (currentView != VIEW_SIMULATION)
// hilDock->hide();
// else
// hilDock->show();
}
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (isVisible()) storeViewState();
aboutToCloseFlag = true;
Michael Carpenter
committed
storeSettings();
mavlink->storeSettings();
UASManager::instance()->storeSettings();
QMainWindow::closeEvent(event);
}
/**
* Connect the signals and slots of the common window widgets
*/
void MainWindow::connectCommonWidgets()
{
if (infoDockWidget && infoDockWidget->widget())
{
connect(mavlink, SIGNAL(receiveLossChanged(int, float)),
infoDockWidget->widget(), SLOT(updateSendLoss(int, float)));
}
}