Commit a0166f13 authored by Gus Grubba's avatar Gus Grubba

Made QGCCorePlugin derive from QGCToolBox and expose everything through the...

Made QGCCorePlugin derive from QGCToolBox and expose everything through the same mechanism as everything else.
parent 3f3bfafa
#pragma once
#include <QObject>
/// @file
/// @brief Core Plugin Interface for QGroundControl
/// @author Gus Grubba <mavlink@grubba.com>
// Work In Progress
class QGCApplication;
class IQGCApplication;
class IQGCOptions;
class IQGCQMLSource;
class IQGCCorePlugin
{
public:
IQGCCorePlugin(QObject*) {}
virtual ~IQGCCorePlugin() {}
#if defined (QGC_DYNAMIC_PLUGIN)
virtual bool init (IQGCApplication* pApp) = 0;
#else
virtual bool init (QGCApplication* pApp) = 0;
#endif
virtual IQGCOptions* uiOptions () { return NULL; }
virtual IQGCQMLSource* settingsQML () { return NULL; }
};
#if defined (QGC_DYNAMIC_PLUGIN)
Q_DECLARE_INTERFACE(IQGCCorePlugin, "org.qgroundcontrol.qgccoreplugin")
#endif
#pragma once
#include <QString>
/// @file
/// @brief Core Plugin Interface for QGroundControl
/// @author Gus Grubba <mavlink@grubba.com>
class IQGCQMLSource
{
public:
IQGCQMLSource() {}
virtual ~IQGCQMLSource() {}
virtual QString pageUrl () { return QString(); }
virtual QString pageTitle () { return QString(); }
virtual QString pageIconUrl () { return QString(); }
};
......@@ -34,6 +34,34 @@ exists(user_config.pri):infile(user_config.pri, CONFIG) {
message($$sprintf("Using user-supplied additional config: '%1' specified in user_config.pri", $$fromfile(user_config.pri, CONFIG)))
}
#
# Custom Build
#
# QGC will create a "CUSTOMCLASS" object (exposed by your custom build
# and derived from QGCCorePlugin).
# This is the start of allowing custom Plugins, which will eventually use a
# more defined runtime plugin architecture and not require a QGC project
# file you would have to keep in sync with the upstream repo.
#
# This allows you to ignore the custom build even if the custom build
# is present. It's useful to run "regular" builds to make sure you didn't
# break anything.
contains (CONFIG, QGC_DISABLE_CUSTOM_BUILD) {
message("Disable custom build override")
} else {
exists($$PWD/custom/custom.pri) {
message("Found custom build")
CONFIG += CustomBuild
DEFINES += QGC_CUSTOM_BUILD
# custom.pri must define:
# CUSTOMCLASS = YourIQGCCorePluginDerivation
# CUSTOMHEADER = \"\\\"YourIQGCCorePluginDerivation.h\\\"\"
include($$PWD/custom/custom.pri)
}
}
#
# Plugin configuration
#
......@@ -69,34 +97,6 @@ contains (CONFIG, QGC_DISABLE_PX4_PLUGIN_FACTORY) {
CONFIG += PX4FirmwarePluginFactory
}
#
# Custom Build
#
# QGC will create a "CUSTOMCLASS" object (exposed by your custom build
# and derived from IQGCCorePlugin) and call its IQGCCorePlugin::init() method.
# This is the start of allowing custom Plugins, which will eventually use a
# more defined runtime plugin architecture and not require a QGC project
# file you would have to keep in sync with the upstream repo.
#
# This allows you to ignore the custom build even if the custom build
# is present. It's useful to run "regular" builds to make sure you didn't
# break anything.
contains (CONFIG, QGC_DISABLE_CUSTOM_BUILD) {
message("Disable custom build override")
} else {
exists($$PWD/custom/custom.pri) {
message("Found custom build")
CONFIG += CustomBuild
DEFINES += QGC_CUSTOM_BUILD
# custom.pri must define:
# CUSTOMCLASS = YourIQGCCorePluginDerivation
# CUSTOMHEADER = \"\\\"YourIQGCCorePluginDerivation.h\\\"\"
include($$PWD/custom/custom.pri)
}
}
# Bluetooth
contains (DEFINES, QGC_DISABLE_BLUETOOTH) {
message("Skipping support for Bluetooth (manual override from command line)")
......@@ -273,9 +273,9 @@ DEPENDPATH += \
INCLUDEPATH += .
INCLUDEPATH += \
api \
include/ui \
src \
src/api \
src/AnalyzeView \
src/AutoPilotPlugins \
src/FlightDisplay \
......@@ -336,10 +336,14 @@ FORMS += \
#
HEADERS += \
api/IQGCApplication.h \
api/IQGCCorePlugin.h \
api/IQGCOptions.h \
api/IQGCQMLSource.h \
src/api/QGCCorePlugin.h \
src/api/QGCOptions.h \
src/api/QGCSettings.h \
SOURCES += \
src/api/QGCCorePlugin.cc \
src/api/QGCOptions.cc \
src/api/QGCSettings.cc \
#
# Unit Test specific configuration goes here (requires full debug build with all plugins)
......
......@@ -34,7 +34,7 @@ QGCView {
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property bool _mainIsMap: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, QGroundControl.mainViewIsMap) : true
property bool _mainIsMap: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, QGroundControl.corePlugin.options.mainViewIsMap) : true
property bool _isPipVisible: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false
property real _roll: _activeVehicle ? _activeVehicle.roll.value : _defaultRoll
......
......@@ -20,6 +20,9 @@
#include "ScreenToolsController.h"
#include "VideoManager.h"
#include "QGCToolbox.h"
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
static const char* kVideoSourceKey = "VideoSource";
static const char* kVideoUDPPortKey = "VideoUDPPort";
......@@ -41,34 +44,6 @@ VideoManager::VideoManager(QGCApplication* app)
, _udpPort(5600) //-- Defalut Port 5600 == Solo UDP Port
, _init(false)
{
//-- Get saved settings
#if defined(QGC_GST_STREAMING)
QSettings settings;
#if defined(NO_UDP_VIDEO)
setVideoSource(settings.value(kVideoSourceKey, kRTSPStream).toString());
#else
setVideoSource(settings.value(kVideoSourceKey, kUDPStream).toString());
#endif
//-- Check if core plugin defines its own video requirements
if(qgcApp()->qgcOptions()->definesVideo()) {
if(qgcApp()->qgcOptions()->videoUDPPort()) {
setUdpPort(qgcApp()->qgcOptions()->videoUDPPort());
setVideoSource(kUDPStream);
} else {
setVideoSource(kRTSPStream);
setRtspURL(qgcApp()->qgcOptions()->videoRSTPUrl());
}
} else {
setUdpPort(settings.value(kVideoUDPPortKey, 5600).toUInt());
setRtspURL(settings.value(kVideoRTSPUrlKey, "rtsp://192.168.42.1:554/live").toString()); //-- Example RTSP URL
}
#endif
_init = true;
#if defined(QGC_GST_STREAMING)
_updateVideo();
connect(&_frameTimer, &QTimer::timeout, this, &VideoManager::_updateTimer);
_frameTimer.start(1000);
#endif
}
//-----------------------------------------------------------------------------
......@@ -84,6 +59,34 @@ VideoManager::setToolbox(QGCToolbox *toolbox)
QGCTool::setToolbox(toolbox);
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<VideoManager>("QGroundControl.VideoManager", 1, 0, "VideoManager", "Reference only");
//-- Get saved settings
#if defined(QGC_GST_STREAMING)
QSettings settings;
#if defined(NO_UDP_VIDEO)
setVideoSource(settings.value(kVideoSourceKey, kRTSPStream).toString());
#else
setVideoSource(settings.value(kVideoSourceKey, kUDPStream).toString());
#endif
//-- Check if core plugin defines its own video requirements
if(qgcApp()->toolbox()->corePlugin()->options()->definesVideo()) {
if(qgcApp()->toolbox()->corePlugin()->options()->videoUDPPort()) {
setUdpPort(qgcApp()->toolbox()->corePlugin()->options()->videoUDPPort());
setVideoSource(kUDPStream);
} else {
setVideoSource(kRTSPStream);
setRtspURL(qgcApp()->toolbox()->corePlugin()->options()->videoRSTPUrl());
}
} else {
setUdpPort(settings.value(kVideoUDPPortKey, 5600).toUInt());
setRtspURL(settings.value(kVideoRTSPUrlKey, "rtsp://192.168.42.1:554/live").toString()); //-- Example RTSP URL
}
#endif
_init = true;
#if defined(QGC_GST_STREAMING)
_updateVideo();
connect(&_frameTimer, &QTimer::timeout, this, &VideoManager::_updateTimer);
_frameTimer.start(1000);
#endif
}
//-----------------------------------------------------------------------------
......
......@@ -83,10 +83,6 @@
#include "QGCMapPolygon.h"
#include "ParameterManager.h"
#if defined(QGC_CUSTOM_BUILD)
#include CUSTOMHEADER
#endif
#ifndef NO_SERIAL_LINK
#include "SerialLink.h"
#endif
......@@ -188,15 +184,10 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
, _toolbox(NULL)
, _bluetoothAvailable(false)
, _lastKnownHomePosition(37.803784, -122.462276, 0.0)
, _pQGCOptions(NULL)
, _pCorePlugin(NULL)
{
Q_ASSERT(_app == NULL);
_app = this;
//-- Scan and load plugins
_scanAndLoadPlugins();
// This prevents usage of QQuickWidget to fail since it doesn't support native widget siblings
#ifndef __android__
setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
......@@ -358,9 +349,6 @@ QGCApplication::~QGCApplication()
#endif
shutdownVideoStreaming();
delete _toolbox;
if(_pCorePlugin) {
delete _pCorePlugin;
}
}
void QGCApplication::_initCommon(void)
......@@ -456,14 +444,6 @@ bool QGCApplication::_initForNormalAppBoot(void)
}
settings.sync();
//-- Initialize Core Plugin (if any)
if(_pCorePlugin) {
if(!_pCorePlugin->init(this)) {
return false;
}
}
return true;
}
......@@ -708,41 +688,3 @@ void QGCApplication::setLastKnownHomePosition(QGeoCoordinate& lastKnownHomePosit
settings.setValue(_lastKnownHomePositionAltKey, lastKnownHomePosition.altitude());
_lastKnownHomePosition = lastKnownHomePosition;
}
IQGCOptions* QGCApplication::qgcOptions()
{
return _pQGCOptions;
}
void QGCApplication::_scanAndLoadPlugins()
{
#if defined (QGC_DYNAMIC_PLUGIN)
//-- Look for plugins (Dynamic)
QString filter = "*.core.so";
QString path = QCoreApplication::applicationDirPath();
QDirIterator it(path, QStringList() << filter, QDir::Files);
while(it.hasNext()) {
QString pluginFile = it.next();
QPluginLoader loader(pluginFile);
QObject *plugin = loader.instance();
if(plugin) {
_pCorePlugin = qobject_cast<IQGCCorePlugin*>(plugin);
if(_pCorePlugin) {
_pQGCOptions = _pCorePlugin->uiOptions();
return;
}
} else {
qWarning() << "Plugin" << pluginFile << " not loaded:" << loader.errorString();
}
}
#elif defined (QGC_CUSTOM_BUILD)
//-- Create custom plugin (Static)
_pCorePlugin = (IQGCCorePlugin*) new CUSTOMCLASS(this);
if(_pCorePlugin) {
_pQGCOptions = _pCorePlugin->uiOptions();
return;
}
#endif
//-- No plugins found, use default options
_pQGCOptions = new IQGCOptions;
}
......@@ -35,12 +35,6 @@
#include "UASMessageHandler.h"
#include "FactSystem.h"
//-- Plugin Architecture
#include "IQGCApplication.h"
#include "IQGCCorePlugin.h"
#include "IQGCOptions.h"
#include "IQGCQMLSource.h"
#ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h"
#endif
......@@ -123,11 +117,6 @@ public:
QGeoCoordinate lastKnownHomePosition(void) { return _lastKnownHomePosition; }
void setLastKnownHomePosition(QGeoCoordinate& lastKnownHomePosition);
/// Options (can be overwriten by a core plugin)
IQGCOptions* qgcOptions();
/// Custom core plugin (NULL if none)
IQGCCorePlugin* customCorePlugin() { return _pCorePlugin; }
public slots:
/// You can connect to this slot to show an information message box from a different thread.
void informationMessageBoxOnMainThread(const QString& title, const QString& msg);
......@@ -179,7 +168,6 @@ private slots:
private:
void _loadCurrentStyle ();
QObject* _rootQmlObject ();
void _scanAndLoadPlugins ();
#ifdef __mobile__
QQmlApplicationEngine* _qmlAppEngine;
......@@ -218,9 +206,6 @@ private:
/// Unit Test have access to creating and destroying singletons
friend class UnitTest;
//-- Plugin Architecture
IQGCOptions* _pQGCOptions;
IQGCCorePlugin* _pCorePlugin;
};
/// @brief Returns the QGCApplication object singleton.
......
......@@ -28,6 +28,12 @@
#include "PositionManager.h"
#include "VideoManager.h"
#include "MAVLinkLogManager.h"
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
#if defined(QGC_CUSTOM_BUILD)
#include CUSTOMHEADER
#endif
QGCToolbox::QGCToolbox(QGCApplication* app)
: _audioOutput(NULL)
......@@ -50,7 +56,10 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
, _qgcPositionManager(NULL)
, _videoManager(NULL)
, _mavlinkLogManager(NULL)
, _corePlugin(NULL)
{
//-- Scan and load plugins
_scanAndLoadPlugins(app);
_audioOutput = new GAudioOutput(app);
_factSystem = new FactSystem(app);
_firmwarePluginManager = new FirmwarePluginManager(app);
......@@ -75,6 +84,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app)
void QGCToolbox::setChildToolboxes(void)
{
_corePlugin->setToolbox(this);
_audioOutput->setToolbox(this);
_factSystem->setToolbox(this);
_firmwarePluginManager->setToolbox(this);
......@@ -115,6 +125,39 @@ QGCToolbox::~QGCToolbox()
delete _uasMessageHandler;
delete _followMe;
delete _qgcPositionManager;
delete _corePlugin;
}
void QGCToolbox::_scanAndLoadPlugins(QGCApplication* app)
{
#if defined (QGC_DYNAMIC_PLUGIN)
//-- Look for plugins (Dynamic)
QString filter = "*.core.so";
QString path = QCoreApplication::applicationDirPath();
QDirIterator it(path, QStringList() << filter, QDir::Files);
while(it.hasNext()) {
QString pluginFile = it.next();
QPluginLoader loader(pluginFile);
QObject *plugin = loader.instance();
if(plugin) {
_pCorePlugin = qobject_cast<IQGCCorePlugin*>(plugin);
if(_pCorePlugin) {
_pQGCOptions = _pCorePlugin->uiOptions();
return;
}
} else {
qWarning() << "Plugin" << pluginFile << " not loaded:" << loader.errorString();
}
}
#elif defined (QGC_CUSTOM_BUILD)
//-- Create custom plugin (Static)
_corePlugin = (QGCCorePlugin*) new CUSTOMCLASS(app);
if(_corePlugin) {
return;
}
#endif
//-- No plugins found, use default instance
_corePlugin = new QGCCorePlugin(app);
}
QGCTool::QGCTool(QGCApplication* app)
......
......@@ -32,6 +32,7 @@ class UASMessageHandler;
class QGCPositionManager;
class VideoManager;
class MAVLinkLogManager;
class QGCCorePlugin;
/// This is used to manage all of our top level services/tools
class QGCToolbox {
......@@ -56,6 +57,7 @@ public:
QGCPositionManager* qgcPositionManager(void) { return _qgcPositionManager; }
VideoManager* videoManager(void) { return _videoManager; }
MAVLinkLogManager* mavlinkLogManager(void) { return _mavlinkLogManager; }
QGCCorePlugin* corePlugin(void) { return _corePlugin; }
#ifndef __mobile__
GPSManager* gpsManager(void) { return _gpsManager; }
......@@ -63,6 +65,8 @@ public:
private:
void setChildToolboxes(void);
void _scanAndLoadPlugins(QGCApplication *app);
GAudioOutput* _audioOutput;
FactSystem* _factSystem;
......@@ -84,6 +88,7 @@ private:
QGCPositionManager* _qgcPositionManager;
VideoManager* _videoManager;
MAVLinkLogManager* _mavlinkLogManager;
QGCCorePlugin* _corePlugin;
friend class QGCApplication;
};
......
......@@ -45,6 +45,7 @@ QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app)
, _missionCommandTree(NULL)
, _videoManager(NULL)
, _mavlinkLogManager(NULL)
, _corePlugin(NULL)
, _virtualTabletJoystick(false)
, _baseFontPointSize(0.0)
{
......@@ -73,6 +74,7 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox)
_missionCommandTree = toolbox->missionCommandTree();
_videoManager = toolbox->videoManager();
_mavlinkLogManager = toolbox->mavlinkLogManager();
_corePlugin = toolbox->corePlugin();
}
void QGroundControlQmlGlobal::saveGlobalSetting (const QString& key, const QString& value)
......@@ -353,68 +355,3 @@ QMap<QString, FactMetaData*>& QGroundControlQmlGlobal::nameToMetaDataMap(void) {
return map;
}
bool QGroundControlQmlGlobal::colapseSettings()
{
return qgcApp()->qgcOptions()->colapseSettings();
}
bool QGroundControlQmlGlobal::mainViewIsMap()
{
return qgcApp()->qgcOptions()->mainViewIsMap();
}
bool QGroundControlQmlGlobal::enableVirtualJoystick()
{
return qgcApp()->qgcOptions()->enableVirtualJoystick();
}
bool QGroundControlQmlGlobal::enableAutoConnectOptions()
{
return qgcApp()->qgcOptions()->enableAutoConnectOptions();
}
bool QGroundControlQmlGlobal::enableVideoSourceOptions()
{
return qgcApp()->qgcOptions()->enableVideoSourceOptions();
}
bool QGroundControlQmlGlobal::hasCustomSettings()
{
if(qgcApp()->customCorePlugin()) {
if(qgcApp()->customCorePlugin()->settingsQML()) {
return !qgcApp()->customCorePlugin()->settingsQML()->pageUrl().isEmpty();
}
}
return false;
}
QString QGroundControlQmlGlobal::customSettingsURL()
{
if(qgcApp()->customCorePlugin()) {
if(qgcApp()->customCorePlugin()->settingsQML()) {
return qgcApp()->customCorePlugin()->settingsQML()->pageUrl();
}
}
return QString();
}
QString QGroundControlQmlGlobal::customSettingsTitle()
{
if(qgcApp()->customCorePlugin()) {
if(qgcApp()->customCorePlugin()->settingsQML()) {
return qgcApp()->customCorePlugin()->settingsQML()->pageTitle();
}
}
return QString();
}
QString QGroundControlQmlGlobal::customSettingsLogoUrl()
{
if(qgcApp()->customCorePlugin()) {
if(qgcApp()->customCorePlugin()->settingsQML()) {
return qgcApp()->customCorePlugin()->settingsQML()->pageIconUrl();
}
}
return QString();
}
......@@ -73,6 +73,7 @@ public:
Q_PROPERTY(MissionCommandTree* missionCommandTree READ missionCommandTree CONSTANT)
Q_PROPERTY(VideoManager* videoManager READ videoManager CONSTANT)
Q_PROPERTY(MAVLinkLogManager* mavlinkLogManager READ mavlinkLogManager CONSTANT)
Q_PROPERTY(QGCCorePlugin* corePlugin READ corePlugin CONSTANT)
Q_PROPERTY(qreal zOrderTopMost READ zOrderTopMost CONSTANT) ///< z order for top most items, toolbar, main window sub view
Q_PROPERTY(qreal zOrderWidgets READ zOrderWidgets CONSTANT) ///< z order value to widgets, for example: zoom controls, hud widgetss
......@@ -86,19 +87,6 @@ public:
Q_PROPERTY(bool virtualTabletJoystick READ virtualTabletJoystick WRITE setVirtualTabletJoystick NOTIFY virtualTabletJoystickChanged)
Q_PROPERTY(qreal baseFontPointSize READ baseFontPointSize WRITE setBaseFontPointSize NOTIFY baseFontPointSizeChanged)
//-------------------------------------------------------------------------
//-- Options that can be set by plugins
Q_PROPERTY(bool colapseSettings READ colapseSettings CONSTANT)
Q_PROPERTY(bool mainViewIsMap READ mainViewIsMap CONSTANT)
Q_PROPERTY(bool enableVirtualJoystick READ enableVirtualJoystick CONSTANT)
Q_PROPERTY(bool enableAutoConnectOptions READ enableAutoConnectOptions CONSTANT)
Q_PROPERTY(bool enableVideoSourceOptions READ enableVideoSourceOptions CONSTANT)
Q_PROPERTY(bool hasCustomSettings READ hasCustomSettings CONSTANT)
Q_PROPERTY(QString customSettingsURL READ customSettingsURL CONSTANT)
Q_PROPERTY(QString customSettingsTitle READ customSettingsTitle CONSTANT)
Q_PROPERTY(QString customSettingsLogoUrl READ customSettingsLogoUrl CONSTANT)
//-------------------------------------------------------------------------
// MavLink Protocol
Q_PROPERTY(bool isVersionCheckEnabled READ isVersionCheckEnabled WRITE setIsVersionCheckEnabled NOTIFY isVersionCheckEnabledChanged)
......@@ -183,6 +171,7 @@ public:
MissionCommandTree* missionCommandTree () { return _missionCommandTree; }
VideoManager* videoManager () { return _videoManager; }
MAVLinkLogManager* mavlinkLogManager () { return _mavlinkLogManager; }
QGCCorePlugin* corePlugin () { return _corePlugin; }
qreal zOrderTopMost () { return 1000; }
qreal zOrderWidgets () { return 100; }
......@@ -198,16 +187,6 @@ public:
bool isVersionCheckEnabled () { return _toolbox->mavlinkProtocol()->versionCheckEnabled(); }
int mavlinkSystemID () { return _toolbox->mavlinkProtocol()->getSystemId(); }
bool colapseSettings ();
bool mainViewIsMap ();
bool enableVirtualJoystick ();
bool enableAutoConnectOptions();
bool enableVideoSourceOptions();
bool hasCustomSettings ();
QString customSettingsTitle ();
QString customSettingsURL ();
QString customSettingsLogoUrl ();
QGeoCoordinate lastKnownHomePosition() { return qgcApp()->lastKnownHomePosition(); }
static Fact* offlineEditingFirmwareType (void);
......@@ -264,6 +243,7 @@ private:
MissionCommandTree* _missionCommandTree;
VideoManager* _videoManager;
MAVLinkLogManager* _mavlinkLogManager;
QGCCorePlugin* _corePlugin;
bool _virtualTabletJoystick;
qreal _baseFontPointSize;
......
......@@ -16,7 +16,7 @@
#include "QGroundControlQmlGlobal.h"
#include "ParameterManager.h"
#ifdef __mobile__
#if defined (__ios__) || defined(__android__)
#include "MobileScreenMgr.h"
#endif
......@@ -116,7 +116,7 @@ void MultiVehicleManager::_vehicleHeartbeatInfo(LinkInterface* link, int vehicle
// Mark link as active
link->setActive(true);
#ifdef __mobile__
#if defined (__ios__) || defined(__android__)
if(_vehicles.count() == 1) {
//-- Once a vehicle is connected, keep screen from going off
qCDebug(MultiVehicleManagerLog) << "QAndroidJniObject::keepScreenOn";
......@@ -157,7 +157,7 @@ void MultiVehicleManager::_deleteVehiclePhase1(Vehicle* vehicle)
emit parameterReadyVehicleAvailableChanged(false);
emit vehicleRemoved(vehicle);
#ifdef __mobile__
#if defined (__ios__) || defined(__android__)
if(_vehicles.count() == 0) {
//-- Once no vehicles are connected, we no longer need to keep screen from going off
qCDebug(MultiVehicleManagerLog) << "QAndroidJniObject::restoreScreenOn";
......
......@@ -256,31 +256,17 @@ Rectangle {
visible: !ScreenTools.isShortScreen
}
SubMenuButton {
imageResource: "/res/gear-white.svg"
setupIndicator: false
exclusiveGroup: setupButtonGroup
text: "General"
visible: QGroundControl.colapseSettings
onClicked: panelLoader.setSource("GeneralSettings.qml")
}
SubMenuButton {
imageResource: QGroundControl.customSettingsLogoUrl
setupIndicator: false
exclusiveGroup: setupButtonGroup
text: QGroundControl.customSettingsTitle
visible: QGroundControl.colapseSettings && QGroundControl.hasCustomSettings
onClicked: panelLoader.setSource(QGroundControl.customSettingsURL)
}
SubMenuButton {
imageResource: "/res/waves.svg"
setupIndicator: false
exclusiveGroup: setupButtonGroup
text: "MAVLink"
visible: QGroundControl.colapseSettings
onClicked: panelLoader.setSource("MavlinkSettings.qml")
Repeater {
model: QGroundControl.corePlugin.settings
visible: QGroundControl.corePlugin.options.combineSettingsAndSetup
SubMenuButton {
imageResource: modelData.icon
setupIndicator: false
exclusiveGroup: setupButtonGroup
text: modelData.title
visible: QGroundControl.corePlugin.options.combineSettingsAndSetup
onClicked: panelLoader.setSource(modelData.url)
}
}
SubMenuButton {
......
/****************************************************************************
*
* (c) 2009-2016 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.
*
****************************************************************************/
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
#include "QGCSettings.h"
#include <QtQml>
#include <QQmlEngine>
/// @file
/// @brief Core Plugin Interface for QGroundControl - Default Implementation
/// @author Gus Grubba <mavlink@grubba.com>
class QGCCorePlugin_p
{
public:
QGCCorePlugin_p()
: pGeneral(NULL)
, pCommLinks(NULL)
, pOfflineMaps(NULL)
, pMAVLink(NULL)
, pConsole(NULL)
#if defined(QT_DEBUG)
, pMockLink(NULL)
, pDebug(NULL)
#endif
, defaultOptions(NULL)
{
}
~QGCCorePlugin_p()
{
if(pGeneral)
delete pGeneral;
if(pCommLinks)
delete pCommLinks;
if(pOfflineMaps)
delete pOfflineMaps;
if(pMAVLink)
delete pMAVLink;
if(pConsole)
delete pConsole;
#if defined(QT_DEBUG)
if(pMockLink)
delete pMockLink;
if(pDebug)
delete pDebug;
#endif
if(defaultOptions)
delete defaultOptions;
}
QGCSettings* pGeneral;
QGCSettings* pCommLinks;
QGCSettings* pOfflineMaps;
QGCSettings* pMAVLink;
QGCSettings* pConsole;
#if defined(QT_DEBUG)
QGCSettings* pMockLink;
QGCSettings* pDebug;
#endif
QVariantList settingsList;
QGCOptions* defaultOptions;
};
QGCCorePlugin::~QGCCorePlugin()
{
if(_p) {
delete _p;
}
}
QGCCorePlugin::QGCCorePlugin(QGCApplication *app)
: QGCTool(app)
{
_p = new QGCCorePlugin_p;
}
void QGCCorePlugin::setToolbox(QGCToolbox *toolbox)
{
QGCTool::setToolbox(toolbox);
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<QGCCorePlugin>("QGroundControl.QGCCorePlugin", 1, 0, "QGCCorePlugin", "Reference only");
qmlRegisterUncreatableType<QGCOptions>("QGroundControl.QGCOptions", 1, 0, "QGCOptions", "Reference only");
}
QVariantList &QGCCorePlugin::settings()
{
//-- If this hasn't been overridden, create default set of settings
if(!_p->pGeneral) {
QGCOptions* pOptions = options();
//-- Default Settings
if(pOptions->enabledSettings() & QGCOptions::SETTINGS_GENERAL) {
_p->pGeneral = new QGCSettings(tr("General"),
QUrl::fromUserInput("qrc:/qml/GeneralSettings.qml"),
QUrl::fromUserInput("qrc:/res/gear-white.svg"));
_p->settingsList.append(QVariant::fromValue((QGCSettings*)_p->pGeneral));
}
if(pOptions->enabledSettings() & QGCOptions::SETTINGS_COMM_LINKS) {
_p->pCommLinks = new QGCSettings(tr("Comm Links"),
QUrl::fromUserInput("qrc:/qml/LinkSettings.qml"),
QUrl::fromUserInput("qrc:/res/waves.svg"));
_p->settingsList.append(QVariant::fromValue((QGCSettings*)_p->pCommLinks));
}
if(pOptions->enabledSettings() & QGCOptions::SETTINGS_OFFLINE_MAPS) {
_p->pOfflineMaps = new QGCSettings(tr("Offline Maps"),
QUrl::fromUserInput("qrc:/qml/OfflineMap.qml"),
QUrl::fromUserInput("qrc:/res/waves.svg"));
_p->settingsList.append(QVariant::fromValue((QGCSettings*)_p->pOfflineMaps));
}
if(pOptions->enabledSettings() & QGCOptions::SETTINGS_MAVLINK) {
_p->pMAVLink = new QGCSettings(tr("MAVLink"),
QUrl::fromUserInput("qrc:/qml/MavlinkSettings.qml"),
QUrl::fromUserInput("qrc:/res/waves.svg"));
_p->settingsList.append(QVariant::fromValue((QGCSettings*)_p->pMAVLink));
}
if(pOptions->enabledSettings() & QGCOptions::SETTINGS_CONSOLE) {
_p->pConsole = new QGCSettings(tr("Console"),
QUrl::fromUserInput("qrc:/QGroundControl/Controls/AppMessages.qml"));
_p->settingsList.append(QVariant::fromValue((QGCSettings*)_p->pConsole));
}
#if defined(QT_DEBUG)
//-- These are always present on Debug builds
if(pOptions->enabledSettings() & QGCOptions::SETTINGS_MOCKLINK) {
_p->pMockLink = new QGCSettings(tr("Mock Link"),
QUrl::fromUserInput("qrc:/qml/MockLink.qml"));
_p->settingsList.append(QVariant::fromValue((QGCSettings*)_p->pMockLink));
}
if(pOptions->enabledSettings() & QGCOptions::SETTINGS_DEBUG) {
_p->pDebug = new QGCSettings(tr("Debug"),
QUrl::fromUserInput("qrc:/qml/DebugWindow.qml"));
_p->settingsList.append(QVariant::fromValue((QGCSettings*)_p->pDebug));
}
#endif
}
return _p->settingsList;
}
QGCOptions* QGCCorePlugin::options()
{
if(!_p->defaultOptions) {
_p->defaultOptions = new QGCOptions();
}
return _p->defaultOptions;
}
/****************************************************************************
*
* (c) 2009-2016 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.
*
****************************************************************************/
#pragma once
#include "QGCToolbox.h"
#include <QObject>
#include <QVariantList>
/// @file
/// @brief Core Plugin Interface for QGroundControl
/// @author Gus Grubba <mavlink@grubba.com>
// Work In Progress
class QGCApplication;
class QGCOptions;
class QGCSettings;
class QGCCorePlugin_p;
class QGCCorePlugin : public QGCTool
{
Q_OBJECT
public:
QGCCorePlugin(QGCApplication* app);
~QGCCorePlugin();
Q_PROPERTY(QVariantList settings READ settings CONSTANT)
Q_PROPERTY(QGCOptions* options READ options CONSTANT)
//! The list of settings under the Settings Menu
/*!
@return A list of QGCSettings
*/
virtual QVariantList& settings ();
//! Global options
/*!
@return An instance of QGCOptions
*/
virtual QGCOptions* options ();
// Override from QGCTool
void setToolbox (QGCToolbox *toolbox);
private:
QGCCorePlugin_p* _p;
};
......@@ -7,18 +7,13 @@
*
****************************************************************************/
#include "QGCOptions.h"
/**
* @brief QGC Main Application Interface (used for Dynamic Loaded plugins)
* @author Gus Grubba <mavlink@grubba.com>
*/
/// @file
/// @brief Core Plugin Interface for QGroundControl - Application Options
/// @author Gus Grubba <mavlink@grubba.com>
#pragma once
class IQGCApplication
QGCOptions::QGCOptions(QObject* parent)
: QObject(parent)
{
public:
IQGCApplication() {}
virtual ~IQGCApplication() {}
//-- Not yet implemented
};
}
/****************************************************************************
*
* (c) 2009-2016 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.
*
****************************************************************************/
#pragma once
#include <QObject>
#include <QString>
/// @file
/// @brief Core Plugin Interface for QGroundControl
/// @brief Core Plugin Interface for QGroundControl - Application Options
/// @author Gus Grubba <mavlink@grubba.com>
class IQGCOptions
class QGCOptions : public QObject
{
Q_OBJECT
public:
IQGCOptions() {}
virtual ~IQGCOptions() {}
//! Should QGC colapse its settings menu into one single menu (Settings and Vehicle Setup)?
QGCOptions(QObject* parent = NULL);
enum BaseSettings {
SETTINGS_GENERAL = 1 << 1,
SETTINGS_COMM_LINKS = 1 << 2,
SETTINGS_OFFLINE_MAPS = 1 << 3,
SETTINGS_MAVLINK = 1 << 4,
SETTINGS_CONSOLE = 1 << 5,
SETTINGS_MOCKLINK = 1 << 6,
SETTINGS_DEBUG = 1 << 7,
};
Q_ENUMS(BaseSettings)
Q_PROPERTY(bool combineSettingsAndSetup READ combineSettingsAndSetup CONSTANT)
Q_PROPERTY(bool mainViewIsMap READ mainViewIsMap CONSTANT)
Q_PROPERTY(bool enableVirtualJoystick READ enableVirtualJoystick CONSTANT)
Q_PROPERTY(bool enableAutoConnectOptions READ enableAutoConnectOptions CONSTANT)
Q_PROPERTY(bool enableVideoSourceOptions READ enableVideoSourceOptions CONSTANT)
Q_PROPERTY(int enabledSettings READ enabledSettings CONSTANT)
Q_PROPERTY(bool definesVideo READ definesVideo CONSTANT)
Q_PROPERTY(uint16_t videoUDPPort READ videoUDPPort CONSTANT)
Q_PROPERTY(QString videoRSTPUrl READ videoRSTPUrl CONSTANT)
//! Should QGC hide its settings menu and colapse it into one single menu (Settings and Vehicle Setup)?
/*!
@return true if QGC should consolidate both menus into one.
*/
virtual bool colapseSettings () { return false; }
virtual bool combineSettingsAndSetup () { return false; }
//! Should QGC use Maps as its default main view?
/*!
@return true if QGC should use Maps by default or false to show Video by default.
......@@ -34,6 +69,11 @@ public:
@return false to disable video source options.
*/
virtual bool enableVideoSourceOptions () { return true; }
//! Which settings are enabled?
/*!
@return BaseSettings bitmap of enabled settings
*/
virtual int enabledSettings () { return SETTINGS_GENERAL | SETTINGS_COMM_LINKS | SETTINGS_MAVLINK | SETTINGS_CONSOLE | SETTINGS_MOCKLINK | SETTINGS_DEBUG; }
//! Does your plugin defines its on video source?
/*!
@return true to define your own video source.
......
/****************************************************************************
*
* (c) 2009-2016 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.
*
****************************************************************************/
#include "QGCSettings.h"
/// @file
/// @brief Core Plugin Interface for QGroundControl. Settings element.
/// @author Gus Grubba <mavlink@grubba.com>
QGCSettings::QGCSettings(QString title, QUrl url, QUrl icon)
: _title(title)
, _url(url)
, _icon(icon)
{
}
/****************************************************************************
*
* (c) 2009-2016 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.
*
****************************************************************************/
#pragma once
#include <QObject>
#include <QUrl>
/// @file
/// @brief Core Plugin Interface for QGroundControl. Settings element.
/// @author Gus Grubba <mavlink@grubba.com>
class QGCSettings : public QObject
{
Q_OBJECT
public:
QGCSettings(QString title, QUrl url, QUrl icon = QUrl());
Q_PROPERTY(QString title READ title CONSTANT)
Q_PROPERTY(QUrl url READ url CONSTANT)
Q_PROPERTY(QUrl icon READ icon CONSTANT)
virtual QString title () { return _title; }
virtual QUrl url () { return _url; }
virtual QUrl icon () { return _icon; }
protected:
QString _title;
QUrl _url;
QUrl _icon;
};
......@@ -30,13 +30,13 @@ Rectangle {
readonly property real _buttonHeight: ScreenTools.isTinyScreen ? ScreenTools.defaultFontPixelHeight * 3 : ScreenTools.defaultFontPixelHeight * 2
readonly property real _buttonWidth: ScreenTools.defaultFontPixelWidth * 10
property bool _first: true
QGCPalette { id: qgcPal }
Component.onCompleted: {
//-- Default to General Settings
__rightPanel.source = "GeneralSettings.qml"
_generalButton.checked = true
panelActionGroup.current = _generalButton
}
QGCFlickable {
......@@ -81,90 +81,24 @@ Rectangle {
visible: !ScreenTools.isShortScreen
}
QGCButton {
id: _generalButton
height: _buttonHeight
text: qsTr("General")
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source != "GeneralSettings.qml") {
__rightPanel.source = "GeneralSettings.qml"
}
checked = true
}
}
QGCButton {
height: _buttonHeight
text: qsTr("Comm Links")
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source != "LinkSettings.qml") {
__rightPanel.source = "LinkSettings.qml"
}
checked = true
}
}
QGCButton {
height: _buttonHeight
text: qsTr("Offline Maps")
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source != "OfflineMap.qml") {
__rightPanel.source = "OfflineMap.qml"
}
checked = true
}
}
QGCButton {
height: _buttonHeight
text: qsTr("MAVLink")
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source != "MavlinkSettings.qml") {
__rightPanel.source = "MavlinkSettings.qml"
}
checked = true
}
}
QGCButton {
height: _buttonHeight
text: qsTr("Console")
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source != "QGroundControl/Controls/AppMessages.qml") {
__rightPanel.source = "QGroundControl/Controls/AppMessages.qml"
}
checked = true
}
}
QGCButton {
height: _buttonHeight
text: qsTr("Mock Link")
visible: ScreenTools.isDebug
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source != "MockLink.qml") {
__rightPanel.source = "MockLink.qml"
Repeater {
model: QGroundControl.corePlugin.settings
QGCButton {
height: _buttonHeight
text: modelData.title
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source !== modelData.url) {
__rightPanel.source = modelData.url
}
checked = true
}
checked = true
}
}
QGCButton {
height: _buttonHeight
text: qsTr("Debug")
visible: ScreenTools.isDebug
exclusiveGroup: panelActionGroup
onClicked: {
if(__rightPanel.source != "DebugWindow.qml") {
__rightPanel.source = "DebugWindow.qml"
Component.onCompleted: {
if(_first) {
_first = false
checked = true
}
}
checked = true
}
}
}
......
......@@ -364,7 +364,7 @@ QGCView {
text: qsTr("Virtual Joystick")
checked: QGroundControl.virtualTabletJoystick
onClicked: QGroundControl.virtualTabletJoystick = checked
visible: QGroundControl.enableVirtualJoystick
visible: QGroundControl.corePlugin.options.enableVirtualJoystick
}
//-----------------------------------------------------------------
//-- Map Providers
......@@ -434,7 +434,7 @@ QGCView {
height: autoConnectLabel.height
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: QGroundControl.enableAutoConnectOptions
visible: QGroundControl.corePlugin.options.enableAutoConnectOptions
QGCLabel {
id: autoConnectLabel
text: qsTr("Autoconnect to the following devices:")
......@@ -445,7 +445,7 @@ QGCView {
height: autoConnectCol.height + (ScreenTools.defaultFontPixelHeight * 2)
width: qgcView.width * 0.8
color: qgcPal.windowShade
visible: QGroundControl.enableAutoConnectOptions
visible: QGroundControl.corePlugin.options.enableAutoConnectOptions
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
Column {
......@@ -497,7 +497,7 @@ QGCView {
Item {
width: qgcView.width * 0.8
height: videoLabel.height
visible: QGroundControl.enableVideoSourceOptions
visible: QGroundControl.corePlugin.options.enableVideoSourceOptions
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
......@@ -510,7 +510,7 @@ QGCView {
height: videoCol.height + (ScreenTools.defaultFontPixelHeight * 2)
width: qgcView.width * 0.8
color: qgcPal.windowShade
visible: QGroundControl.enableVideoSourceOptions
visible: QGroundControl.corePlugin.options.enableVideoSourceOptions
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
Column {
......
......@@ -338,7 +338,7 @@ Rectangle {
source: "/res/QGCLogoWhite"
logo: true
onClicked: toolBar.showSettingsView()
visible: !QGroundControl.colapseSettings
visible: !QGroundControl.corePlugin.options.combineSettingsAndSetup
}
QGCToolBarButton {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment