Newer
Older
/****************************************************************************
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
dogmaphobic
committed
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#include <QFile>
#include <QFlags>
#include <QPixmap>
#include <QDesktopWidget>
#include <QPainter>
#include <QStyleFactory>
#include <QAction>
#ifdef QGC_ENABLE_BLUETOOTH
#include <QBluetoothLocalDevice>
#endif
#include "VideoStreaming.h"
#include "QGC.h"
#include "UDPLink.h"
#include "LinkManager.h"
#include "UASMessageHandler.h"
#include "QGCLoggingCategory.h"
#include "ViewWidgetController.h"
#include "ParameterEditorController.h"
#include "QGCFileDialogController.h"
#include "SyslinkComponentController.h"
#include "AutoPilotPlugin.h"
#include "VehicleComponent.h"
#include "MultiVehicleManager.h"
#include "Vehicle.h"
#include "JoystickManager.h"
#include "QmlObjectListModel.h"
Gus Grubba
committed
#include "QGCGeoBoundingCube.h"
#include "PlanMasterController.h"
#include "AppMessages.h"
#include "SimulatedPosition.h"
#include "PositionManager.h"
#include "FollowMe.h"
#include "MissionCommandTree.h"
#include "ParameterManager.h"
#include "VisualMissionItem.h"
#include "EditPositionDialogController.h"
#include "FactValueSliderListModel.h"
#include "MavlinkConsoleController.h"
#include "GeoTagController.h"
#if defined(QGC_ENABLE_PAIRING)
#include "PairingManager.h"
#endif
#ifndef __mobile__
#include "FirmwareUpgradeController.h"
#endif
#include "SerialLink.h"
#ifdef QGC_RTLAB_ENABLED
#endif
#ifdef Q_OS_LINUX
#ifndef __mobile__
#include <unistd.h>
#include <sys/types.h>
#endif
#endif
class FinishVideoInitialization : public QRunnable
{
public:
FinishVideoInitialization(VideoManager* manager)
: _manager(manager)
{}
void run () {
_manager->_initVideo();
}
private:
VideoManager* _manager;
};
QGCApplication* QGCApplication::_app = nullptr;
const char* QGCApplication::_deleteAllSettingsKey = "DeleteAllSettingsNextBoot";
const char* QGCApplication::_settingsVersionKey = "SettingsVersion";
// Mavlink status structures for entire app
mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS];
static QObject* screenToolsControllerSingletonFactory(QQmlEngine*, QJSEngine*)
ScreenToolsController* screenToolsController = new ScreenToolsController;
return screenToolsController;
static QObject* qgroundcontrolQmlGlobalSingletonFactory(QQmlEngine*, QJSEngine*)
{
// We create this object as a QGCTool even though it isn't in the toolbox
QGroundControlQmlGlobal* qmlGlobal = new QGroundControlQmlGlobal(qgcApp(), qgcApp()->toolbox());
qmlGlobal->setToolbox(qgcApp()->toolbox());
return qmlGlobal;
static QObject* shapeFileHelperSingletonFactory(QQmlEngine*, QJSEngine*)
QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
if (!_runningUnitTests) {
if (getuid() == 0) {
_exitWithError(QString(
tr("You are running %1 as root. "
"You should not do this since it will cause other issues with %1."
"%1 will now exit.<br/><br/>"
"If you are having serial port issues on Ubuntu, execute the following commands to fix most issues:<br/>"
"<pre>sudo usermod -a -G dialout $USER<br/>"
"sudo apt-get remove modemmanager</pre>").arg(qgcApp()->applicationName())));
return;
}
// Determine if we have the correct permissions to access USB serial devices
QFile permFile("/etc/group");
if(permFile.open(QIODevice::ReadOnly)) {
while(!permFile.atEnd()) {
QString line = permFile.readLine();
if (line.contains("dialout") && !line.contains(getenv("USER"))) {
permFile.close();
_exitWithError(QString(
tr("The current user does not have the correct permissions to access serial devices. "
"You should also remove modemmanager since it also interferes.<br/><br/>"
"If you are using Ubuntu, execute the following commands to fix these issues:<br/>"
"<pre>sudo usermod -a -G dialout $USER<br/>"
"sudo apt-get remove modemmanager</pre>")));
return;
// Setup for network proxy support
QNetworkProxyFactory::setUseSystemConfiguration(true);
bool fClearSettingsOptions = false; // Clear stored settings
bool logging = false; // Turn on logging
QString loggingOptions;
{ "--clear-settings", &fClearSettingsOptions, nullptr },
{ "--logging", &logging, &loggingOptions },
{ "--fake-mobile", &_fakeMobile, nullptr },
{ "--log-output", &_logOutput, nullptr },
// Add additional command line option flags here
};
ParseCmdLineOptions(argc, argv, rgCmdLineOptions, sizeof(rgCmdLineOptions)/sizeof(rgCmdLineOptions[0]), false);
dogmaphobic
committed
// Set up timer for delayed missing fact display
_missingParamsDelayedDisplayTimer.setSingleShot(true);
_missingParamsDelayedDisplayTimer.setInterval(_missingParamsDelayedDisplayTimerTimeout);
connect(&_missingParamsDelayedDisplayTimer, &QTimer::timeout, this, &QGCApplication::_missingParamsDisplay);
if (_runningUnitTests) {
// We don't want unit tests to use the same QSettings space as the normal app. So we tweak the app
// name. Also we want to run unit tests with clean settings every time.
setApplicationName(QString("%1_unittest").arg(QGC_APPLICATION_NAME));
} else {
setApplicationName(QGC_APPLICATION_NAME);
}
setOrganizationName(QGC_ORG_NAME);
setOrganizationDomain(QGC_ORG_DOMAIN);
dogmaphobic
committed
this->setApplicationVersion(QString(GIT_VERSION));
dogmaphobic
committed
// Set settings format
QSettings::setDefaultFormat(QSettings::IniFormat);
QSettings settings;
qDebug() << "Settings location" << settings.fileName() << "Is writable?:" << settings.isWritable();
if (!settings.isWritable()) {
qWarning() << "Setings location is not writable";
}
// The setting will delete all settings on this boot
fClearSettingsOptions |= settings.contains(_deleteAllSettingsKey);
dogmaphobic
committed
// Unit tests run with clean settings
dogmaphobic
committed
if (fClearSettingsOptions) {
// User requested settings to be cleared on command line
settings.clear();
QDir paramDir(ParameterManager::parameterCacheDir());
paramDir.removeRecursively();
paramDir.mkpath(paramDir.absolutePath());
// Determine if upgrade message for settings version bump is required. Check and clear must happen before toolbox is started since
// that will write some settings.
if (settings.contains(_settingsVersionKey)) {
if (settings.value(_settingsVersionKey).toInt() != QGC_SETTINGS_VERSION) {
_settingsUpgraded = true;
}
} else if (settings.allKeys().count()) {
// Settings version key is missing and there are settings. This is an upgrade scenario.
settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION);
if (fClearCache) {
QDir dir(ParameterManager::parameterCacheDir());
dir.removeRecursively();
// Set up our logging filters
QGCLoggingCategoryRegister::instance()->setFilterRulesFromSettings(loggingOptions);
// Initialize Bluetooth
#ifdef QGC_ENABLE_BLUETOOTH
QBluetoothLocalDevice localDevice;
if (localDevice.isValid())
{
_bluetoothAvailable = true;
}
#endif
if (settings.contains(AppSettings::gstDebugLevelName)) {
gstDebugLevel = settings.value(AppSettings::gstDebugLevelName).toInt();
// Initialize Video Streaming
initializeVideoStreaming(argc, argv, gstDebugLevel);
#ifndef __mobile__
_gpsRtkFactGroup = new GPSRTKFactGroup(this);
GPSManager *gpsManager = _toolbox->gpsManager();
if (gpsManager) {
connect(gpsManager, &GPSManager::onConnect, this, &QGCApplication::_onGPSConnect);
connect(gpsManager, &GPSManager::onDisconnect, this, &QGCApplication::_onGPSDisconnect);
connect(gpsManager, &GPSManager::surveyInStatus, this, &QGCApplication::_gpsSurveyInStatus);
connect(gpsManager, &GPSManager::satelliteUpdate, this, &QGCApplication::_gpsNumSatellites);
}
#endif /* __mobile__ */
void QGCApplication::_exitWithError(QString errorMessage)
{
_error = true;
QQmlApplicationEngine* pEngine = new QQmlApplicationEngine(this);
pEngine->addImportPath("qrc:/qml");
pEngine->rootContext()->setContextProperty("errorMessage", errorMessage);
pEngine->load(QUrl(QStringLiteral("qrc:/qml/ExitWithErrorWindow.qml")));
// Exit main application when last window is closed
connect(this, &QGCApplication::lastWindowClosed, this, QGCApplication::quit);
}
void QGCApplication::setLanguage()
{
_locale = QLocale::system();
qDebug() << "System reported locale:" << _locale << _locale.name();
int langID = toolbox()->settingsManager()->appSettings()->language()->rawValue().toInt();
if(langID) {
switch(langID) {
case 1:
if(_locale == QLocale::Korean) {
qDebug() << "Loading Korean fonts" << _locale.name();
if(QFontDatabase::addApplicationFont(":/fonts/NanumGothic-Regular") < 0) {
qWarning() << "Could not load /fonts/NanumGothic-Regular font";
}
if(QFontDatabase::addApplicationFont(":/fonts/NanumGothic-Bold") < 0) {
qWarning() << "Could not load /fonts/NanumGothic-Bold font";
}
}
qDebug() << "Loading localization for" << _locale.name();
_app->removeTranslator(&_QGCTranslator);
_app->removeTranslator(&_QGCTranslatorQt);
if(_QGCTranslatorQt.load("qt_" + _locale.name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
_app->installTranslator(&_QGCTranslatorQt);
} else {
qDebug() << "Qt localization for" << _locale.name() << "is not present";
if(_QGCTranslator.load(_locale, QLatin1String("qgc_"), "", ":/i18n")) {
QLocale::setDefault(_locale);
_app->installTranslator(&_QGCTranslator);
qDebug() << "Error loading application localization for" << _locale.name();
}
if(_qmlAppEngine)
_qmlAppEngine->retranslate();
Gus Grubba
committed
void QGCApplication::_shutdown()
// Close out all Qml before we delete toolbox. This way we don't get all sorts of null reference complaints from Qml.
delete _qmlAppEngine;
QGCApplication::~QGCApplication()
{
// Place shutdown code in _shutdown
Gus Grubba
committed
void QGCApplication::_initCommon()
static const char* kRefOnly = "Reference only";
static const char* kQGCControllers = "QGroundControl.Controllers";
static const char* kQGCVehicle = "QGroundControl.Vehicle";
dogmaphobic
committed
qmlRegisterType<QGCPalette> ("QGroundControl.Palette", 1, 0, "QGCPalette");
qmlRegisterType<QGCMapPalette> ("QGroundControl.Palette", 1, 0, "QGCMapPalette");
qmlRegisterUncreatableType<Vehicle> (kQGCVehicle, 1, 0, "Vehicle", kRefOnly);
qmlRegisterUncreatableType<MissionManager> (kQGCVehicle, 1, 0, "MissionManager", kRefOnly);
qmlRegisterUncreatableType<ParameterManager> (kQGCVehicle, 1, 0, "ParameterManager", kRefOnly);
qmlRegisterUncreatableType<VehicleObjectAvoidance> (kQGCVehicle, 1, 0, "VehicleObjectAvoidance", kRefOnly);
qmlRegisterUncreatableType<QGCCameraManager> (kQGCVehicle, 1, 0, "QGCCameraManager", kRefOnly);
qmlRegisterUncreatableType<QGCCameraControl> (kQGCVehicle, 1, 0, "QGCCameraControl", kRefOnly);
qmlRegisterUncreatableType<QGCVideoStreamInfo> (kQGCVehicle, 1, 0, "QGCVideoStreamInfo", kRefOnly);
qmlRegisterUncreatableType<LinkInterface> (kQGCVehicle, 1, 0, "LinkInterface", kRefOnly);
qmlRegisterUncreatableType<MissionController> (kQGCControllers, 1, 0, "MissionController", kRefOnly);
qmlRegisterUncreatableType<GeoFenceController> (kQGCControllers, 1, 0, "GeoFenceController", kRefOnly);
qmlRegisterUncreatableType<RallyPointController> (kQGCControllers, 1, 0, "RallyPointController", kRefOnly);
qmlRegisterUncreatableType<MissionItem> (kQGroundControl, 1, 0, "MissionItem", kRefOnly);
qmlRegisterUncreatableType<VisualMissionItem> (kQGroundControl, 1, 0, "VisualMissionItem", kRefOnly);
qmlRegisterUncreatableType<CoordinateVector> (kQGroundControl, 1, 0, "CoordinateVector", kRefOnly);
qmlRegisterUncreatableType<QmlObjectListModel> (kQGroundControl, 1, 0, "QmlObjectListModel", kRefOnly);
qmlRegisterUncreatableType<MissionCommandTree> (kQGroundControl, 1, 0, "MissionCommandTree", kRefOnly);
qmlRegisterUncreatableType<CameraCalc> (kQGroundControl, 1, 0, "CameraCalc", kRefOnly);
qmlRegisterUncreatableType<LogReplayLink> (kQGroundControl, 1, 0, "LogReplayLink", kRefOnly);
qmlRegisterType<LogReplayLinkController> (kQGroundControl, 1, 0, "LogReplayLinkController");
#if defined(QGC_ENABLE_MAVLINK_INSPECTOR)
qmlRegisterUncreatableType<MAVLinkChartController> (kQGroundControl, 1, 0, "MAVLinkChart", kRefOnly);
#endif
qmlRegisterUncreatableType<PairingManager> (kQGroundControl, 1, 0, "PairingManager", kRefOnly);
qmlRegisterUncreatableType<AutoPilotPlugin> ("QGroundControl.AutoPilotPlugin", 1, 0, "AutoPilotPlugin", kRefOnly);
qmlRegisterUncreatableType<VehicleComponent> ("QGroundControl.AutoPilotPlugin", 1, 0, "VehicleComponent", kRefOnly);
qmlRegisterUncreatableType<JoystickManager> ("QGroundControl.JoystickManager", 1, 0, "JoystickManager", kRefOnly);
qmlRegisterUncreatableType<Joystick> ("QGroundControl.JoystickManager", 1, 0, "Joystick", kRefOnly);
qmlRegisterUncreatableType<QGCPositionManager> ("QGroundControl.QGCPositionManager", 1, 0, "QGCPositionManager", kRefOnly);
qmlRegisterUncreatableType<FactValueSliderListModel>("QGroundControl.FactControls", 1, 0, "FactValueSliderListModel", kRefOnly);
qmlRegisterUncreatableType<QGCMapPolygon> ("QGroundControl.FlightMap", 1, 0, "QGCMapPolygon", kRefOnly);
qmlRegisterUncreatableType<QGCGeoBoundingCube> ("QGroundControl.FlightMap", 1, 0, "QGCGeoBoundingCube", kRefOnly);
qmlRegisterUncreatableType<TrajectoryPoints> ("QGroundControl.FlightMap", 1, 0, "TrajectoryPoints", kRefOnly);
qmlRegisterType<QGCMapCircle> ("QGroundControl.FlightMap", 1, 0, "QGCMapCircle");
Gus Grubba
committed
qmlRegisterType<ParameterEditorController> (kQGCControllers, 1, 0, "ParameterEditorController");
qmlRegisterType<ESP8266ComponentController> (kQGCControllers, 1, 0, "ESP8266ComponentController");
qmlRegisterType<ScreenToolsController> (kQGCControllers, 1, 0, "ScreenToolsController");
qmlRegisterType<PlanMasterController> (kQGCControllers, 1, 0, "PlanMasterController");
qmlRegisterType<ValuesWidgetController> (kQGCControllers, 1, 0, "ValuesWidgetController");
qmlRegisterType<QGCFileDialogController> (kQGCControllers, 1, 0, "QGCFileDialogController");
qmlRegisterType<RCChannelMonitorController> (kQGCControllers, 1, 0, "RCChannelMonitorController");
qmlRegisterType<JoystickConfigController> (kQGCControllers, 1, 0, "JoystickConfigController");
qmlRegisterType<LogDownloadController> (kQGCControllers, 1, 0, "LogDownloadController");
qmlRegisterType<SyslinkComponentController> (kQGCControllers, 1, 0, "SyslinkComponentController");
qmlRegisterType<EditPositionDialogController> (kQGCControllers, 1, 0, "EditPositionDialogController");
#ifndef NO_SERIAL_LINK
qmlRegisterType<FirmwareUpgradeController> (kQGCControllers, 1, 0, "FirmwareUpgradeController");
qmlRegisterType<GeoTagController> (kQGCControllers, 1, 0, "GeoTagController");
qmlRegisterType<MavlinkConsoleController> (kQGCControllers, 1, 0, "MavlinkConsoleController");
#if defined(QGC_ENABLE_MAVLINK_INSPECTOR)
qmlRegisterType<MAVLinkInspectorController> (kQGCControllers, 1, 0, "MAVLinkInspectorController");
qmlRegisterSingletonType<QGroundControlQmlGlobal> ("QGroundControl", 1, 0, "QGroundControl", qgroundcontrolQmlGlobalSingletonFactory);
qmlRegisterSingletonType<ScreenToolsController> ("QGroundControl.ScreenToolsController", 1, 0, "ScreenToolsController", screenToolsControllerSingletonFactory);
qmlRegisterSingletonType<ShapeFileHelper> ("QGroundControl.ShapeFileHelper", 1, 0, "ShapeFileHelper", shapeFileHelperSingletonFactory);
Gus Grubba
committed
bool QGCApplication::_initForNormalAppBoot()
if(QFontDatabase::addApplicationFont(":/fonts/opensans") < 0) {
qWarning() << "Could not load /fonts/opensans font";
}
if(QFontDatabase::addApplicationFont(":/fonts/opensans-demibold") < 0) {
qWarning() << "Could not load /fonts/opensans-demibold font";
dogmaphobic
committed
_qmlAppEngine = toolbox()->corePlugin()->createRootWindow(this);
dogmaphobic
committed
QQuickWindow* rootWindow = (QQuickWindow*)qgcApp()->mainRootWindow();
if (rootWindow) {
rootWindow->scheduleRenderJob (new FinishVideoInitialization (toolbox()->videoManager()),
QQuickWindow::BeforeSynchronizingStage);
}
// Safe to show popup error messages now that main window is created
UASMessageHandler* msgHandler = qgcApp()->toolbox()->uasMessageHandler();
if (msgHandler) {
msgHandler->showErrorsInToolbar();
}
dogmaphobic
committed
// Now that main window is up check for lost log files
connect(this, &QGCApplication::checkForLostLogFiles, toolbox()->mavlinkProtocol(), &MAVLinkProtocol::checkForLostLogFiles);
dogmaphobic
committed
// Load known link configurations
toolbox()->linkManager()->loadLinkConfigurationList();
dogmaphobic
committed
// Probe for joysticks
toolbox()->joystickManager()->init();
showMessage(QString(tr("The format for %1 saved settings has been modified. "
"Your saved settings have been reset to defaults.")).arg(applicationName()));
// Connect links with flag AutoconnectLink
toolbox()->linkManager()->startAutoConnectedLinks();
showMessage(tr("The Offline Map Cache database has been upgraded. "
"Your old map cache sets have been reset."));
Gus Grubba
committed
bool QGCApplication::_initForUnitTests()
void QGCApplication::deleteAllSettingsNextBoot(void)
{
QSettings settings;
settings.setValue(_deleteAllSettingsKey, true);
}
void QGCApplication::clearDeleteAllSettingsNextBoot(void)
{
QSettings settings;
settings.remove(_deleteAllSettingsKey);
}
/// @brief Returns the QGCApplication object singleton.
QGCApplication* qgcApp(void)
{
Gus Grubba
committed
void QGCApplication::informationMessageBoxOnMainThread(const QString& /*title*/, const QString& msg)
Gus Grubba
committed
void QGCApplication::warningMessageBoxOnMainThread(const QString& /*title*/, const QString& msg)
Gus Grubba
committed
void QGCApplication::criticalMessageBoxOnMainThread(const QString& /*title*/, const QString& msg)
void QGCApplication::saveTelemetryLogOnMainThread(QString tempLogfile)
// The vehicle is gone now and we are shutting down so we need to use a message box for errors to hold shutdown and show the error
if (_checkTelemetrySavePath(true /* useMessageBox */)) {
QString saveDirPath = _toolbox->settingsManager()->appSettings()->telemetrySavePath();
QDir saveDir(saveDirPath);
QString nameFormat("%1%2.%3");
QString dtFormat("yyyy-MM-dd hh-mm-ss");
int tryIndex = 1;
QString saveFileName = nameFormat.arg(
QDateTime::currentDateTime().toString(dtFormat)).arg(QStringLiteral("")).arg(toolbox()->settingsManager()->appSettings()->telemetryFileExtension);
while (saveDir.exists(saveFileName)) {
saveFileName = nameFormat.arg(
QDateTime::currentDateTime().toString(dtFormat)).arg(QStringLiteral(".%1").arg(tryIndex++)).arg(toolbox()->settingsManager()->appSettings()->telemetryFileExtension);
}
QString saveFilePath = saveDir.absoluteFilePath(saveFileName);
QFile tempFile(tempLogfile);
if (!tempFile.copy(saveFilePath)) {
QString error = tr("Unable to save telemetry log. Error copying telemetry to '%1': '%2'.").arg(saveFilePath).arg(tempFile.errorString());
showMessage(error);
Gus Grubba
committed
void QGCApplication::checkTelemetrySavePathOnMainThread()
{
// This is called with an active vehicle so don't pop message boxes which holds ui thread
_checkTelemetrySavePath(false /* useMessageBox */);
}
Gus Grubba
committed
bool QGCApplication::_checkTelemetrySavePath(bool /*useMessageBox*/)
QString saveDirPath = _toolbox->settingsManager()->appSettings()->telemetrySavePath();
if (saveDirPath.isEmpty()) {
QString error = tr("Unable to save telemetry log. Application save directory is not set.");
return false;
}
QDir saveDir(saveDirPath);
if (!saveDir.exists()) {
QString error = tr("Unable to save telemetry log. Telemetry save directory \"%1\" does not exist.").arg(saveDirPath);
return false;
}
return true;
}
void QGCApplication::reportMissingParameter(int componentId, const QString& name)
QPair<int, QString> missingParam(componentId, name);
if (!_missingParams.contains(missingParam)) {
_missingParams.append(missingParam);
}
/// Called when the delay timer fires to show the missing parameters warning
void QGCApplication::_missingParamsDisplay(void)
for (QPair<int, QString>& missingParam: _missingParams) {
QString param = QStringLiteral("%1:%2").arg(missingParam.first).arg(missingParam.second);
showMessage(tr("Parameters are missing from firmware. You may be running a version of firmware QGC does not work correctly with or your firmware has a bug in it. Missing params: %1").arg(params));
if(_qmlAppEngine && _qmlAppEngine->rootObjects().size())
return _qmlAppEngine->rootObjects()[0];
return nullptr;
void QGCApplication::showMessage(const QString& message)
if (message.startsWith(QStringLiteral("PreArm")) || message.startsWith(QStringLiteral("preflight"), Qt::CaseInsensitive)) {
QObject* rootQmlObject = _rootQmlObject();
if (rootQmlObject) {
QVariant varReturn;
QVariant varMessage = QVariant::fromValue(message);
QMetaObject::invokeMethod(_rootQmlObject(), "showMessage", Q_RETURN_ARG(QVariant, varReturn), Q_ARG(QVariant, varMessage));
} else if (runningUnitTests()) {
// Unit tests can run without UI
qDebug() << "QGCApplication::showMessage unittest" << message;
} else {
qWarning() << "Internal error";
}
QQuickItem* QGCApplication::mainRootWindow()
Gus Grubba
committed
{
_mainRootWindow = reinterpret_cast<QQuickItem*>(_rootQmlObject());
Gus Grubba
committed
}
Gus Grubba
committed
}
void QGCApplication::showSetupView()
if(_rootQmlObject()) {
QMetaObject::invokeMethod(_rootQmlObject(), "showSetupView");
}
Gus Grubba
committed
void QGCApplication::qmlAttemptWindowClose()
if(_rootQmlObject()) {
QMetaObject::invokeMethod(_rootQmlObject(), "attemptWindowClose");
}
bool QGCApplication::isInternetAvailable()
{
if(_toolbox->settingsManager()->appSettings()->checkInternet()->rawValue().toBool())
return getQGCMapEngine()->isInternetActive();
return true;
Gus Grubba
committed
void QGCApplication::_checkForNewVersion()
{
#ifndef __mobile__
if (!_runningUnitTests) {
if (_parseVersionText(applicationVersion(), _majorVersion, _minorVersion, _buildVersion)) {
QString versionCheckFile = toolbox()->corePlugin()->stableVersionCheckFileUrl();
if (!versionCheckFile.isEmpty()) {
_currentVersionDownload = new QGCFileDownload(this);
connect(_currentVersionDownload, &QGCFileDownload::downloadFinished, this, &QGCApplication::_currentVersionDownloadFinished);
connect(_currentVersionDownload, &QGCFileDownload::error, this, &QGCApplication::_currentVersionDownloadError);
_currentVersionDownload->download(versionCheckFile);
}
}
}
#endif
}
Gus Grubba
committed
void QGCApplication::_currentVersionDownloadFinished(QString /*remoteFile*/, QString localFile)
QFile versionFile(localFile);
if (versionFile.open(QIODevice::ReadOnly)) {
QTextStream textStream(&versionFile);
QString version = textStream.readLine();
qDebug() << version;
int majorVersion, minorVersion, buildVersion;
if (_parseVersionText(version, majorVersion, minorVersion, buildVersion)) {
if (_majorVersion < majorVersion ||
(_majorVersion == majorVersion && _minorVersion < minorVersion) ||
(_majorVersion == majorVersion && _minorVersion == minorVersion && _buildVersion < buildVersion)) {
//-- TODO
///QGCMessageBox::information(tr("New Version Available"), tr("There is a newer version of %1 available. You can download it from %2.").arg(applicationName()).arg(toolbox()->corePlugin()->stableDownloadLocation()));
Gus Grubba
committed
void QGCApplication::_currentVersionDownloadError(QString /*errorMsg*/)
{
_currentVersionDownload->deleteLater();
}
bool QGCApplication::_parseVersionText(const QString& versionString, int& majorVersion, int& minorVersion, int& buildVersion)
{
QRegularExpression regExp("v(\\d+)\\.(\\d+)\\.(\\d+)");
QRegularExpressionMatch match = regExp.match(versionString);
if (match.hasMatch() && match.lastCapturedIndex() == 3) {
majorVersion = match.captured(1).toInt();
minorVersion = match.captured(2).toInt();
buildVersion = match.captured(3).toInt();
return true;
}
return false;
}
void QGCApplication::_onGPSConnect()
{
_gpsRtkFactGroup->connected()->setRawValue(true);
}
void QGCApplication::_onGPSDisconnect()
{
_gpsRtkFactGroup->connected()->setRawValue(false);
}
void QGCApplication::_gpsSurveyInStatus(float duration, float accuracyMM, double latitude, double longitude, float altitude, bool valid, bool active)
{
_gpsRtkFactGroup->currentDuration()->setRawValue(duration);
_gpsRtkFactGroup->currentAccuracy()->setRawValue(static_cast<double>(accuracyMM) / 1000.0);
_gpsRtkFactGroup->currentLatitude()->setRawValue(latitude);
_gpsRtkFactGroup->currentLongitude()->setRawValue(longitude);
_gpsRtkFactGroup->currentAltitude()->setRawValue(altitude);
_gpsRtkFactGroup->valid()->setRawValue(valid);
_gpsRtkFactGroup->active()->setRawValue(active);
}
void QGCApplication::_gpsNumSatellites(int numSatellites)
{
_gpsRtkFactGroup->numSatellites()->setRawValue(numSatellites);
}
QString QGCApplication::cachedParameterMetaDataFile(void)
{
QSettings settings;
QDir parameterDir = QFileInfo(settings.fileName()).dir();
return parameterDir.filePath(QStringLiteral("ParameterFactMetaData.xml"));
}
QString QGCApplication::cachedAirframeMetaDataFile(void)
{
QSettings settings;
QDir airframeDir = QFileInfo(settings.fileName()).dir();
return airframeDir.filePath(QStringLiteral("PX4AirframeFactMetaData.xml"));
}