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#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
4#include "MavlinkSettings.h"
5#endif
6#include "FactMetaData.h"
7#include "QGCMAVLink.h"
10#include "JoystickManager.h"
11#include "QGCLoggingCategory.h"
12#include "QGCOptions.h"
13#include "QmlComponentInfo.h"
14#include "QmlObjectListModel.h"
15#include "SettingsManager.h"
16#include "VideoReceiver.h"
17#include "VideoBackend.h"
18#include "SurveyPlanCreator.h"
21#include "SurveyComplexItem.h"
26#include "Vehicle.h"
27#include "BlankPlanCreator.h"
28#include "ComplexMissionItem.h"
30
31#ifdef QGC_CUSTOM_BUILD
32#include CUSTOMHEADER
33#endif
34
35#include <QtCore/QApplicationStatic>
36#include <QtCore/QFile>
37#include <QtQml/QQmlApplicationEngine>
38#include <QtQml/QQmlContext>
39#include <QtQuick/QQuickItem>
40
41QGC_LOGGING_CATEGORY(QGCCorePluginLog, "API.QGCCorePlugin");
42
43#ifndef QGC_CUSTOM_BUILD
44Q_APPLICATION_STATIC(QGCCorePlugin, _qgcCorePluginInstance);
45#endif
46
48 : QObject(parent)
49 , _defaultOptions(new QGCOptions(this))
50 , _emptyCustomMapItems(new QmlObjectListModel(this))
51{
52 qCDebug(QGCCorePluginLog) << this;
53}
54
56{
57 qCDebug(QGCCorePluginLog) << this;
58}
59
61{
62#ifndef QGC_CUSTOM_BUILD
63 return _qgcCorePluginInstance();
64#else
65 return CUSTOMCLASS::instance();
66#endif
67}
68
69const QVariantList &QGCCorePlugin::analyzePages()
70{
71 // Log Viewer is excluded on mobile (Android/iOS) because parsing large log files
72 // (e.g. 900 MB ULog files with 1000+ fields) exhausts the mobile heap, causing
73 // OOM crashes. Proper mobile support requires time-bucketed downsampling and will
74 // be addressed in a future major release.
75#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
76 static const QVariantList analyzeList = {
77#else
78 static const QVariantList analyzeList = {
79 QVariant::fromValue(new QmlComponentInfo(
80 tr("Log Viewer"),
81 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/LogViewer/LogViewerPage.qml")),
82 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkInspector.svg")))),
83#endif
84 QVariant::fromValue(new QmlComponentInfo(
85 tr("Onboard Logs"),
86 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/OnboardLogs/OnboardLogPage.qml")),
87 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/OnboardLogIcon.svg")),
88 nullptr, true /* requiresVehicle */)),
89 QVariant::fromValue(new QmlComponentInfo(
90 tr("Onboard Logs (FTP)"),
91 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/OnboardLogsFtp/OnboardLogFtpPage.qml")),
92 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/OnboardLogIcon.svg")),
93 nullptr, true /* requiresVehicle */)),
94 QVariant::fromValue(new QmlComponentInfo(
95 tr("GeoTag Images"),
96 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/GeoTag/GeoTagPage.qml")),
97 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/GeoTag/GeoTagIcon.svg")))),
98 QVariant::fromValue(new QmlComponentInfo(
99 tr("MAVLink Console"),
100 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/MAVLinkConsole/MAVLinkConsolePage.qml")),
101 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkConsoleIcon.svg")),
102 nullptr, true /* requiresVehicle */)),
103 QVariant::fromValue(new QmlComponentInfo(
104 tr("MAVLink Inspector"),
105 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/MAVLinkInspector/MAVLinkInspectorPage.qml")),
106 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkInspector.svg")),
107 nullptr, true /* requiresVehicle */)),
108 QVariant::fromValue(new QmlComponentInfo(
109 tr("Vibration"),
110 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/Vibration/VibrationPage.qml")),
111 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/VibrationPageIcon")),
112 nullptr, true /* requiresVehicle */)),
113 };
114
115 return analyzeList;
116}
117
119{
120 return _defaultOptions;
121}
122
124{
125 return _emptyCustomMapItems;
126}
127
128void QGCCorePlugin::adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
129{
130#ifdef Q_OS_ANDROID
131 Q_UNUSED(userVisible);
132#endif
133
134 if (settingsGroup == AppSettings::settingsGroup) {
135 if (metaData.name() == AppSettings::indoorPaletteName) {
136 QVariant outdoorPalette;
137#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
138 outdoorPalette = 0;
139#else
140 outdoorPalette = 1;
141#endif
142 metaData.setRawDefaultValue(outdoorPalette);
143 return;
144 }
145#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
146 else if (metaData.name() == MavlinkSettings::telemetrySaveName) {
147 metaData.setRawDefaultValue(false);
148 return;
149 }
150#endif
151#ifndef Q_OS_ANDROID
152 else if (metaData.name() == AppSettings::androidDontSaveToSDCardName) {
153 userVisible = false;
154 return;
155 }
156#endif
157 }
158}
159
161{
162 return tr("WARNING: You are about to enter Advanced Mode. "
163 "If used incorrectly, this may cause your vehicle to malfunction thus voiding your warranty. "
164 "You should do so only if instructed by customer support. "
165 "Are you sure you want to enable Advanced Mode?");
166}
167
169{
170#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
172#else
174#endif
175
176 if (factValueGrid->specificVehicleForCard()) {
177 bool includeFWValues = factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship;
178
179 factValueGrid->setFontSize(defaultFontSize);
180 factValueGrid->appendColumn();
181 factValueGrid->appendColumn();
182
183 int rowIndex = 0;
184 int colIndex = 0;
185
186 // first cell
187 QmlObjectListModel* column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
188 InstrumentValueData* value = column->value<InstrumentValueData*>(rowIndex);
189 value->setFact("Vehicle", "AltitudeRelative");
190 value->setIcon("arrow-thick-up.svg");
191 value->setText(value->fact()->shortDescription());
192 value->setShowUnits(true);
193
194 // second cell
195 column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
196 value = column->value<InstrumentValueData*>(rowIndex);
197 if (includeFWValues) {
198 value->setFact("Vehicle", "AirSpeed");
199 value->setText("AirSpd");
200 value->setShowUnits(true);
201 } else {
202 value->setFact("Vehicle", "GroundSpeed");
203 value->setIcon("arrow-simple-right.svg");
204 value->setText(value->fact()->shortDescription());
205 value->setShowUnits(true);
206 }
207 } else {
208 const bool includeFWValues = ((factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship));
209
210 factValueGrid->setFontSize(defaultFontSize);
211
212 (void) factValueGrid->appendColumn();
213 (void) factValueGrid->appendColumn();
214 (void) factValueGrid->appendColumn();
215 if (includeFWValues) {
216 (void) factValueGrid->appendColumn();
217 }
218 factValueGrid->appendRow();
219
220 int rowIndex = 0;
221 QmlObjectListModel *column = factValueGrid->columns()->value<QmlObjectListModel*>(0);
222
223 InstrumentValueData *value = column->value<InstrumentValueData*>(rowIndex++);
224 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AltitudeRelative"));
225 value->setIcon(QStringLiteral("arrow-thick-up.svg"));
226 value->setText(value->fact()->shortDescription());
227 value->setShowUnits(true);
228
229 value = column->value<InstrumentValueData*>(rowIndex++);
230 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("DistanceToHome"));
231 value->setIcon(QStringLiteral("bookmark copy 3.svg"));
232 value->setText(value->fact()->shortDescription());
233 value->setShowUnits(true);
234
235 rowIndex = 0;
236 column = factValueGrid->columns()->value<QmlObjectListModel*>(1);
237
238 value = column->value<InstrumentValueData*>(rowIndex++);
239 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ClimbRate"));
240 value->setIcon(QStringLiteral("arrow-simple-up.svg"));
241 value->setText(value->fact()->shortDescription());
242 value->setShowUnits(true);
243
244 value = column->value<InstrumentValueData*>(rowIndex++);
245 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("GroundSpeed"));
246 value->setIcon(QStringLiteral("arrow-simple-right.svg"));
247 value->setText(value->fact()->shortDescription());
248 value->setShowUnits(true);
249
250 if (includeFWValues) {
251 rowIndex = 0;
252 column = factValueGrid->columns()->value<QmlObjectListModel*>(2);
253
254 value = column->value<InstrumentValueData*>(rowIndex++);
255 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AirSpeed"));
256 value->setText(QStringLiteral("AirSpd"));
257 value->setShowUnits(true);
258
259 value = column->value<InstrumentValueData*>(rowIndex++);
260 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ThrottlePct"));
261 value->setText(QStringLiteral("Thr"));
262 value->setShowUnits(true);
263 }
264
265 rowIndex = 0;
266 column = factValueGrid->columns()->value<QmlObjectListModel*>(includeFWValues ? 3 : 2);
267
268 value = column->value<InstrumentValueData*>(rowIndex++);
269 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightTime"));
270 value->setIcon(QStringLiteral("timer.svg"));
271 value->setText(value->fact()->shortDescription());
272 value->setShowUnits(false);
273
274 value = column->value<InstrumentValueData*>(rowIndex++);
275 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightDistance"));
276 value->setIcon(QStringLiteral("travel-walk.svg"));
277 value->setText(value->fact()->shortDescription());
278 value->setShowUnits(true);
279 }
280}
281
282QQmlApplicationEngine *QGCCorePlugin::createQmlApplicationEngine(QObject *parent)
283{
284 QQmlApplicationEngine *const qmlEngine = new QQmlApplicationEngine(parent);
285 qmlEngine->addImportPath(QStringLiteral("qrc:/qml"));
286 qmlEngine->rootContext()->setContextProperty(QStringLiteral("joystickManager"), JoystickManager::instance());
287 return qmlEngine;
288}
289
290void QGCCorePlugin::createRootWindow(QQmlApplicationEngine *qmlEngine)
291{
292 qmlEngine->load(QUrl(QStringLiteral("qrc:/qml/QGroundControl/MainWindow.qml")));
293}
294
299
300void *QGCCorePlugin::createVideoSink(QQuickItem *widget, QObject *parent)
301{
302 return VideoBackend::createSink(widget, parent);
303}
304
306{
308}
309
311{
312 static const QVariantList toolBarIndicatorList = QVariantList(
313 {
314 QVariant::fromValue(QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/Toolbar/RTKGPSIndicator.qml"))),
315 }
316 );
317
318 return toolBarIndicatorList;
319}
320
322{
323 QList<int> rgIdsToShow;
324
325 rgIdsToShow.append(firstRunPromptStdIds());
326 rgIdsToShow.append(firstRunPromptCustomIds());
327
328 const QList<int> rgAlreadyShownIds = AppSettings::firstRunPromptsIdsVariantToList(SettingsManager::instance()->appSettings()->firstRunPromptIdsShown()->rawValue());
329 for (int idToRemove: rgAlreadyShownIds) {
330 (void) rgIdsToShow.removeOne(idToRemove);
331 }
332
333 QVariantList rgVarIdsToShow;
334 for (int id: rgIdsToShow) {
335 rgVarIdsToShow.append(id);
336 }
337
338 return rgVarIdsToShow;
339}
340
342{
343 switch (id) {
345 return QStringLiteral("/qml/QGroundControl/FirstRunPromptDialogs/InitialSetupPrompt.qml");
346 default:
347 return QString();
348 }
349}
350
351void QGCCorePlugin::_setShowTouchAreas(bool show)
352{
353 if (show != _showTouchAreas) {
354 _showTouchAreas = show;
355 emit showTouchAreasChanged(show);
356 }
357}
358
359void QGCCorePlugin::_setShowAdvancedUI(bool show)
360{
361 if (show != _showAdvancedUI) {
362 _showAdvancedUI = show;
363 emit showAdvancedUIChanged(show);
364 }
365}
366
368{
369 auto makeEntry = [](const char* canonical, const QString& translated) {
370 QVariantMap entry;
371 entry[QStringLiteral("canonicalName")] = QString(canonical);
372 entry[QStringLiteral("translatedName")] = translated;
373 return entry;
374 };
375
376 QVariantList items;
377 items.append(makeEntry(SurveyComplexItem::canonicalName, SurveyComplexItem::tr(SurveyComplexItem::canonicalName)));
378 items.append(makeEntry(CorridorScanComplexItem::canonicalName, CorridorScanComplexItem::tr(CorridorScanComplexItem::canonicalName)));
379 if (vehicle->multiRotor() || vehicle->vtol()) {
380 items.append(makeEntry(StructureScanComplexItem::canonicalName, StructureScanComplexItem::tr(StructureScanComplexItem::canonicalName)));
381 }
382 // Note: Landing pattern items are not added here — they have their own dedicated button
383 return items;
384}
385
386QList<PlanCreator*> QGCCorePlugin::planCreators(PlanMasterController *planMasterController)
387{
388 return {
389 new SurveyPlanCreator(planMasterController),
390 new CorridorScanPlanCreator(planMasterController),
391 new StructureScanPlanCreator(planMasterController),
392 new BlankPlanCreator(planMasterController),
393 };
394}
395
397 const QString &complexItemType,
398 PlanMasterController *masterController,
399 bool flyView,
400 const QString &kmlOrShpFile)
401{
402 if (complexItemType == SurveyComplexItem::canonicalName || complexItemType == SurveyComplexItem::jsonComplexItemTypeValue) {
403 return new SurveyComplexItem(masterController, flyView, kmlOrShpFile);
404 } else if (complexItemType == CorridorScanComplexItem::canonicalName || complexItemType == CorridorScanComplexItem::jsonComplexItemTypeValue) {
405 return new CorridorScanComplexItem(masterController, flyView, kmlOrShpFile);
406 } else if (complexItemType == StructureScanComplexItem::canonicalName || complexItemType == StructureScanComplexItem::jsonComplexItemTypeValue) {
407 return new StructureScanComplexItem(masterController, flyView, kmlOrShpFile);
409 return new FixedWingLandingComplexItem(masterController, flyView);
410 } else if (complexItemType == VTOLLandingComplexItem::canonicalName || complexItemType == VTOLLandingComplexItem::jsonComplexItemTypeValue) {
411 return new VTOLLandingComplexItem(masterController, flyView);
412 }
413
414 qCWarning(QGCCorePluginLog) << "QGCCorePlugin::createComplexMissionItem - Unknown complex item type:" << complexItemType;
415 return nullptr;
416}
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
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:1761
bool multiRotor() const
Definition Vehicle.cc:1756
void releaseSink(void *sink)
void * createSink(QQuickItem *widget, QObject *parent)
VideoReceiver * createReceiver(QObject *parent)