QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
QGCCorePlugin.cc
Go to the documentation of this file.
1#include "QGCCorePlugin.h"
2#include "AppSettings.h"
3#include "MavlinkSettings.h"
4#include "FactMetaData.h"
5#include "QGCMAVLink.h"
6#ifdef QGC_GST_STREAMING
7#include "GStreamer.h"
8#endif
10#include "InstrumentValueData.h"
11#include "JoystickManager.h"
12#include "MAVLinkMessageType.h"
13#include "QGCLoggingCategory.h"
14#include "QGCOptions.h"
15#include "QmlComponentInfo.h"
16#include "QmlObjectListModel.h"
17#ifdef QGC_QT_STREAMING
19#endif
20#include "SettingsManager.h"
21#include "VideoReceiver.h"
22#include "SurveyPlanCreator.h"
25#include "SurveyComplexItem.h"
30#include "Vehicle.h"
31#include "BlankPlanCreator.h"
32#include "ComplexMissionItem.h"
34
35#ifdef QGC_CUSTOM_BUILD
36#include CUSTOMHEADER
37#endif
38
39#include <QtCore/QApplicationStatic>
40#include <QtCore/QFile>
41#include <QtQml/QQmlApplicationEngine>
42#include <QtQml/QQmlContext>
43#include <QtQuick/QQuickItem>
44
45QGC_LOGGING_CATEGORY(QGCCorePluginLog, "API.QGCCorePlugin");
46
47#ifndef QGC_CUSTOM_BUILD
48Q_APPLICATION_STATIC(QGCCorePlugin, _qgcCorePluginInstance);
49#endif
50
52 : QObject(parent)
53 , _defaultOptions(new QGCOptions(this))
54 , _emptyCustomMapItems(new QmlObjectListModel(this))
55{
56 qCDebug(QGCCorePluginLog) << this;
57}
58
60{
61 qCDebug(QGCCorePluginLog) << this;
62}
63
65{
66#ifndef QGC_CUSTOM_BUILD
67 return _qgcCorePluginInstance();
68#else
69 return CUSTOMCLASS::instance();
70#endif
71}
72
73const QVariantList &QGCCorePlugin::analyzePages()
74{
75 static const QVariantList analyzeList = {
76 QVariant::fromValue(new QmlComponentInfo(
77 tr("Log Viewer"),
78 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/LogViewer/LogViewerPage.qml")),
79 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkInspector.svg")))),
80 QVariant::fromValue(new QmlComponentInfo(
81 tr("Onboard Logs"),
82 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/OnboardLogs/OnboardLogPage.qml")),
83 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/OnboardLogIcon.svg")),
84 nullptr, true /* requiresVehicle */)),
85 QVariant::fromValue(new QmlComponentInfo(
86 tr("Onboard Logs (FTP)"),
87 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/OnboardLogsFtp/OnboardLogFtpPage.qml")),
88 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/OnboardLogIcon.svg")),
89 nullptr, true /* requiresVehicle */)),
90 QVariant::fromValue(new QmlComponentInfo(
91 tr("GeoTag Images"),
92 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/GeoTag/GeoTagPage.qml")),
93 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/GeoTag/GeoTagIcon.svg")))),
94 QVariant::fromValue(new QmlComponentInfo(
95 tr("MAVLink Console"),
96 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/MAVLinkConsole/MAVLinkConsolePage.qml")),
97 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkConsoleIcon.svg")),
98 nullptr, true /* requiresVehicle */)),
99 QVariant::fromValue(new QmlComponentInfo(
100 tr("MAVLink Inspector"),
101 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/MAVLinkInspector/MAVLinkInspectorPage.qml")),
102 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkInspector.svg")),
103 nullptr, true /* requiresVehicle */)),
104 QVariant::fromValue(new QmlComponentInfo(
105 tr("Vibration"),
106 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/Vibration/VibrationPage.qml")),
107 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/VibrationPageIcon")),
108 nullptr, true /* requiresVehicle */)),
109 };
110
111 return analyzeList;
112}
113
115{
116 return _defaultOptions;
117}
118
120{
121 return _emptyCustomMapItems;
122}
123
124void QGCCorePlugin::adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
125{
126#ifdef Q_OS_ANDROID
127 Q_UNUSED(userVisible);
128#endif
129
130 if (settingsGroup == AppSettings::settingsGroup) {
131 if (metaData.name() == AppSettings::indoorPaletteName) {
132 QVariant outdoorPalette;
133#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
134 outdoorPalette = 0;
135#else
136 outdoorPalette = 1;
137#endif
138 metaData.setRawDefaultValue(outdoorPalette);
139 return;
140 }
141#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
142 else if (metaData.name() == MavlinkSettings::telemetrySaveName) {
143 metaData.setRawDefaultValue(false);
144 return;
145 }
146#endif
147#ifndef Q_OS_ANDROID
148 else if (metaData.name() == AppSettings::androidDontSaveToSDCardName) {
149 userVisible = false;
150 return;
151 }
152#endif
153 }
154}
155
157{
158 return tr("WARNING: You are about to enter Advanced Mode. "
159 "If used incorrectly, this may cause your vehicle to malfunction thus voiding your warranty. "
160 "You should do so only if instructed by customer support. "
161 "Are you sure you want to enable Advanced Mode?");
162}
163
165{
166#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
168#else
170#endif
171
172 if (factValueGrid->specificVehicleForCard()) {
173 bool includeFWValues = factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship;
174
175 factValueGrid->setFontSize(defaultFontSize);
176 factValueGrid->appendColumn();
177 factValueGrid->appendColumn();
178
179 int rowIndex = 0;
180 int colIndex = 0;
181
182 // first cell
183 QmlObjectListModel* column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
184 InstrumentValueData* value = column->value<InstrumentValueData*>(rowIndex);
185 value->setFact("Vehicle", "AltitudeRelative");
186 value->setIcon("arrow-thick-up.svg");
187 value->setText(value->fact()->shortDescription());
188 value->setShowUnits(true);
189
190 // second cell
191 column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
192 value = column->value<InstrumentValueData*>(rowIndex);
193 if (includeFWValues) {
194 value->setFact("Vehicle", "AirSpeed");
195 value->setText("AirSpd");
196 value->setShowUnits(true);
197 } else {
198 value->setFact("Vehicle", "GroundSpeed");
199 value->setIcon("arrow-simple-right.svg");
200 value->setText(value->fact()->shortDescription());
201 value->setShowUnits(true);
202 }
203 } else {
204 const bool includeFWValues = ((factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship));
205
206 factValueGrid->setFontSize(defaultFontSize);
207
208 (void) factValueGrid->appendColumn();
209 (void) factValueGrid->appendColumn();
210 (void) factValueGrid->appendColumn();
211 if (includeFWValues) {
212 (void) factValueGrid->appendColumn();
213 }
214 factValueGrid->appendRow();
215
216 int rowIndex = 0;
217 QmlObjectListModel *column = factValueGrid->columns()->value<QmlObjectListModel*>(0);
218
219 InstrumentValueData *value = column->value<InstrumentValueData*>(rowIndex++);
220 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AltitudeRelative"));
221 value->setIcon(QStringLiteral("arrow-thick-up.svg"));
222 value->setText(value->fact()->shortDescription());
223 value->setShowUnits(true);
224
225 value = column->value<InstrumentValueData*>(rowIndex++);
226 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("DistanceToHome"));
227 value->setIcon(QStringLiteral("bookmark copy 3.svg"));
228 value->setText(value->fact()->shortDescription());
229 value->setShowUnits(true);
230
231 rowIndex = 0;
232 column = factValueGrid->columns()->value<QmlObjectListModel*>(1);
233
234 value = column->value<InstrumentValueData*>(rowIndex++);
235 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ClimbRate"));
236 value->setIcon(QStringLiteral("arrow-simple-up.svg"));
237 value->setText(value->fact()->shortDescription());
238 value->setShowUnits(true);
239
240 value = column->value<InstrumentValueData*>(rowIndex++);
241 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("GroundSpeed"));
242 value->setIcon(QStringLiteral("arrow-simple-right.svg"));
243 value->setText(value->fact()->shortDescription());
244 value->setShowUnits(true);
245
246 if (includeFWValues) {
247 rowIndex = 0;
248 column = factValueGrid->columns()->value<QmlObjectListModel*>(2);
249
250 value = column->value<InstrumentValueData*>(rowIndex++);
251 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AirSpeed"));
252 value->setText(QStringLiteral("AirSpd"));
253 value->setShowUnits(true);
254
255 value = column->value<InstrumentValueData*>(rowIndex++);
256 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ThrottlePct"));
257 value->setText(QStringLiteral("Thr"));
258 value->setShowUnits(true);
259 }
260
261 rowIndex = 0;
262 column = factValueGrid->columns()->value<QmlObjectListModel*>(includeFWValues ? 3 : 2);
263
264 value = column->value<InstrumentValueData*>(rowIndex++);
265 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightTime"));
266 value->setIcon(QStringLiteral("timer.svg"));
267 value->setText(value->fact()->shortDescription());
268 value->setShowUnits(false);
269
270 value = column->value<InstrumentValueData*>(rowIndex++);
271 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightDistance"));
272 value->setIcon(QStringLiteral("travel-walk.svg"));
273 value->setText(value->fact()->shortDescription());
274 value->setShowUnits(true);
275 }
276}
277
278QQmlApplicationEngine *QGCCorePlugin::createQmlApplicationEngine(QObject *parent)
279{
280 QQmlApplicationEngine *const qmlEngine = new QQmlApplicationEngine(parent);
281 qmlEngine->addImportPath(QStringLiteral("qrc:/qml"));
282 qmlEngine->rootContext()->setContextProperty(QStringLiteral("joystickManager"), JoystickManager::instance());
283 return qmlEngine;
284}
285
286void QGCCorePlugin::createRootWindow(QQmlApplicationEngine *qmlEngine)
287{
288 qmlEngine->load(QUrl(QStringLiteral("qrc:/qml/QGroundControl/MainWindow.qml")));
289}
290
292{
293#ifdef QGC_GST_STREAMING
294 return GStreamer::createVideoReceiver(parent);
295#elif defined(QGC_QT_STREAMING)
297#else
298 Q_UNUSED(parent);
299 return nullptr;
300#endif
301}
302
303void *QGCCorePlugin::createVideoSink(QQuickItem *widget, QObject *parent)
304{
305#ifdef QGC_GST_STREAMING
306 return GStreamer::createVideoSink(widget, parent);
307#elif defined(QGC_QT_STREAMING)
308 return QtMultimediaReceiver::createVideoSink(widget, parent);
309#else
310 Q_UNUSED(widget); Q_UNUSED(parent);
311 return nullptr;
312#endif
313}
315{
316#ifdef QGC_GST_STREAMING
318#elif defined(QGC_QT_STREAMING)
320#else
321 Q_UNUSED(sink);
322#endif
323}
324
326{
327 static const QVariantList toolBarIndicatorList = QVariantList(
328 {
329 QVariant::fromValue(QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/Toolbar/RTKGPSIndicator.qml"))),
330 }
331 );
332
333 return toolBarIndicatorList;
334}
335
337{
338 QList<int> rgIdsToShow;
339
340 rgIdsToShow.append(firstRunPromptStdIds());
341 rgIdsToShow.append(firstRunPromptCustomIds());
342
343 const QList<int> rgAlreadyShownIds = AppSettings::firstRunPromptsIdsVariantToList(SettingsManager::instance()->appSettings()->firstRunPromptIdsShown()->rawValue());
344 for (int idToRemove: rgAlreadyShownIds) {
345 (void) rgIdsToShow.removeOne(idToRemove);
346 }
347
348 QVariantList rgVarIdsToShow;
349 for (int id: rgIdsToShow) {
350 rgVarIdsToShow.append(id);
351 }
352
353 return rgVarIdsToShow;
354}
355
357{
358 switch (id) {
360 return QStringLiteral("/qml/QGroundControl/FirstRunPromptDialogs/InitialSetupPrompt.qml");
361 default:
362 return QString();
363 }
364}
365
366void QGCCorePlugin::_setShowTouchAreas(bool show)
367{
368 if (show != _showTouchAreas) {
369 _showTouchAreas = show;
370 emit showTouchAreasChanged(show);
371 }
372}
373
374void QGCCorePlugin::_setShowAdvancedUI(bool show)
375{
376 if (show != _showAdvancedUI) {
377 _showAdvancedUI = show;
378 emit showAdvancedUIChanged(show);
379 }
380}
381
383{
384 auto makeEntry = [](const char* canonical, const QString& translated) {
385 QVariantMap entry;
386 entry[QStringLiteral("canonicalName")] = QString(canonical);
387 entry[QStringLiteral("translatedName")] = translated;
388 return entry;
389 };
390
391 QVariantList items;
392 items.append(makeEntry(SurveyComplexItem::canonicalName, SurveyComplexItem::tr(SurveyComplexItem::canonicalName)));
393 items.append(makeEntry(CorridorScanComplexItem::canonicalName, CorridorScanComplexItem::tr(CorridorScanComplexItem::canonicalName)));
394 if (vehicle->multiRotor() || vehicle->vtol()) {
395 items.append(makeEntry(StructureScanComplexItem::canonicalName, StructureScanComplexItem::tr(StructureScanComplexItem::canonicalName)));
396 }
397 // Note: Landing pattern items are not added here — they have their own dedicated button
398 return items;
399}
400
401QList<PlanCreator*> QGCCorePlugin::planCreators(PlanMasterController *planMasterController)
402{
403 return {
404 new SurveyPlanCreator(planMasterController),
405 new CorridorScanPlanCreator(planMasterController),
406 new StructureScanPlanCreator(planMasterController),
407 new BlankPlanCreator(planMasterController),
408 };
409}
410
412 const QString &complexItemType,
413 PlanMasterController *masterController,
414 bool flyView,
415 const QString &kmlOrShpFile)
416{
417 if (complexItemType == SurveyComplexItem::canonicalName || complexItemType == SurveyComplexItem::jsonComplexItemTypeValue) {
418 return new SurveyComplexItem(masterController, flyView, kmlOrShpFile);
419 } else if (complexItemType == CorridorScanComplexItem::canonicalName || complexItemType == CorridorScanComplexItem::jsonComplexItemTypeValue) {
420 return new CorridorScanComplexItem(masterController, flyView, kmlOrShpFile);
421 } else if (complexItemType == StructureScanComplexItem::canonicalName || complexItemType == StructureScanComplexItem::jsonComplexItemTypeValue) {
422 return new StructureScanComplexItem(masterController, flyView, kmlOrShpFile);
424 return new FixedWingLandingComplexItem(masterController, flyView);
425 } else if (complexItemType == VTOLLandingComplexItem::canonicalName || complexItemType == VTOLLandingComplexItem::jsonComplexItemTypeValue) {
426 return new VTOLLandingComplexItem(masterController, flyView);
427 }
428
429 qCWarning(QGCCorePluginLog) << "QGCCorePlugin::createComplexMissionItem - Unknown complex item type:" << complexItemType;
430 return nullptr;
431}
Q_APPLICATION_STATIC(QGCCorePlugin, _qgcCorePluginInstance)
#define QGC_LOGGING_CATEGORY(name, categoryStr)
static QList< int > firstRunPromptsIdsVariantToList(const QVariant &firstRunPromptIds)
static constexpr const char * canonicalName
static constexpr const char * jsonComplexItemTypeValue
Holds the meta data associated with a Fact.
void setRawDefaultValue(const QVariant &rawDefaultValue)
QString name() const
QmlObjectListModel * columns(void) const
void setFontSize(FontSize fontSize)
Q_INVOKABLE QmlObjectListModel * appendColumn(void)
Vehicle * specificVehicleForCard(void) const
QGCMAVLinkTypes::VehicleClass_t vehicleClass(void) const
Q_INVOKABLE void appendRow(void)
static constexpr const char * jsonComplexItemTypeValue
static constexpr const char * canonicalName
Q_INVOKABLE void setFact(const QString &factGroupName, const QString &factName)
static JoystickManager * instance()
Master controller for mission, fence, rally.
Extension mechanism for generic, non-firmware-specific customization of QGC.
virtual ComplexMissionItem * createComplexMissionItem(const QString &complexItemType, PlanMasterController *masterController, bool flyView, const QString &kmlOrShpFile=QString())
QGCCorePlugin(QObject *parent=nullptr)
virtual QVariantList complexMissionItemNames(Vehicle *vehicle)
void showTouchAreasChanged(bool showTouchAreas)
virtual ~QGCCorePlugin()
virtual void * createVideoSink(QQuickItem *widget, QObject *parent)
Allows the plugin to override the creation of VideoSink.
virtual void factValueGridCreateDefaultSettings(FactValueGrid *factValueGrid)
void showAdvancedUIChanged(bool showAdvancedUI)
virtual QList< int > firstRunPromptStdIds()
virtual const QVariantList & toolBarIndicators()
virtual QList< int > firstRunPromptCustomIds()
virtual Q_INVOKABLE QString firstRunPromptResource(int id) const
Returns the resource which contains the specified first run prompt for display.
static constexpr int kInitialSetupPromptId
virtual QGCOptions * options()
virtual QQmlApplicationEngine * createQmlApplicationEngine(QObject *parent)
virtual const QVariantList & analyzePages()
virtual QString showAdvancedUIMessage() const
virtual void createRootWindow(QQmlApplicationEngine *qmlEngine)
Allows the plugin to override the creation of the root (native) window.
virtual VideoReceiver * createVideoReceiver(QObject *parent)
Allows the plugin to override the creation of VideoReceiver.
virtual void releaseVideoSink(void *sink)
Allows the plugin to override the release of VideoSink.
Q_INVOKABLE QVariantList firstRunPromptsToShow()
Returns the list of first run prompt ids which need to be displayed according to current settings.
virtual const QmlObjectListModel * customMapItems()
Allows custom builds to add custom items to the FlightMap. Objects put into QmlObjectListModel should...
virtual QList< PlanCreator * > planCreators(PlanMasterController *planMasterController)
virtual void adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
static QGCCorePlugin * instance()
Represents a Qml component which can be loaded from a resource.
T value(int index) const
static VideoReceiver * createVideoReceiver(QObject *parent)
static void releaseVideoSink(void *sink)
static void * createVideoSink(QQuickItem *widget, QObject *parent=nullptr)
QString settingsGroup() const
static SettingsManager * instance()
static constexpr const char * canonicalName
static constexpr const char * jsonComplexItemTypeValue
static constexpr const char * jsonComplexItemTypeValue
static constexpr const char * canonicalName
static constexpr const char * canonicalName
static constexpr const char * jsonComplexItemTypeValue
bool vtol() const
Definition Vehicle.cc:1763
bool multiRotor() const
Definition Vehicle.cc:1758
VideoReceiver * createVideoReceiver(QObject *parent)
Definition GStreamer.cc:904
void releaseVideoSink(void *sink)
Definition GStreamer.cc:897
void * createVideoSink(QQuickItem *, QObject *)
Definition GStreamer.cc:858