QGCCorePlugin.cc 15.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
/****************************************************************************
 *
 *   (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.
 *
 ****************************************************************************/

10
#include "QGCApplication.h"
11
12
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
13
#include "QmlComponentInfo.h"
14
#include "FactMetaData.h"
Don Gagne's avatar
Don Gagne committed
15
#include "SettingsManager.h"
16
#include "AppMessages.h"
17
#include "QmlObjectListModel.h"
18
#include "VideoManager.h"
19
#include "VideoReceiver.h"
Don Gagne's avatar
   
Don Gagne committed
20
#include "QGCLoggingCategory.h"
21
#include "QGCCameraManager.h"
22
23
24
25
26
27
28
29
30
31
32
33
34
35

#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()
    {
    }
36

37
38
39
40
41
42
43
44
    ~QGCCorePlugin_p()
    {
        if(pGeneral)
            delete pGeneral;
        if(pCommLinks)
            delete pCommLinks;
        if(pOfflineMaps)
            delete pOfflineMaps;
45
46
47
48
#if defined(QGC_GST_TAISYNC_ENABLED)
        if(pTaisync)
            delete pTaisync;
#endif
49
50
51
52
#if defined(QGC_GST_MICROHARD_ENABLED)
        if(pMicrohard)
            delete pMicrohard;
#endif
Gus Grubba's avatar
Gus Grubba committed
53
#if defined(QGC_AIRMAP_ENABLED)
Gus Grubba's avatar
Gus Grubba committed
54
55
        if(pAirmap)
            delete pAirmap;
Gus Grubba's avatar
Gus Grubba committed
56
#endif
57
58
59
60
61
62
63
64
65
        if(pMAVLink)
            delete pMAVLink;
        if(pConsole)
            delete pConsole;
#if defined(QT_DEBUG)
        if(pMockLink)
            delete pMockLink;
        if(pDebug)
            delete pDebug;
66
67
        if(pQmlTest)
            delete pQmlTest;
68
69
70
71
#endif
        if(defaultOptions)
            delete defaultOptions;
    }
72

73
74
75
76
77
78
    QmlComponentInfo* pGeneral                  = nullptr;
    QmlComponentInfo* pCommLinks                = nullptr;
    QmlComponentInfo* pOfflineMaps              = nullptr;
#if defined(QGC_GST_TAISYNC_ENABLED)
    QmlComponentInfo* pTaisync                  = nullptr;
#endif
79
80
81
#if defined(QGC_GST_MICROHARD_ENABLED)
    QmlComponentInfo* pMicrohard                = nullptr;
#endif
Gus Grubba's avatar
Gus Grubba committed
82
#if defined(QGC_AIRMAP_ENABLED)
83
    QmlComponentInfo* pAirmap                   = nullptr;
Gus Grubba's avatar
Gus Grubba committed
84
#endif
85
86
87
    QmlComponentInfo* pMAVLink                  = nullptr;
    QmlComponentInfo* pConsole                  = nullptr;
    QmlComponentInfo* pHelp                     = nullptr;
88
#if defined(QT_DEBUG)
89
90
    QmlComponentInfo* pMockLink                 = nullptr;
    QmlComponentInfo* pDebug                    = nullptr;
91
    QmlComponentInfo* pQmlTest                  = nullptr;
92
#endif
93

94
95
96
97
98
99
100
101
    QmlComponentInfo*   valuesPageWidgetInfo    = nullptr;
    QmlComponentInfo*   cameraPageWidgetInfo    = nullptr;
    QmlComponentInfo*   videoPageWidgetInfo     = nullptr;
    QmlComponentInfo*   healthPageWidgetInfo    = nullptr;
    QmlComponentInfo*   vibrationPageWidgetInfo = nullptr;

    QGCOptions*         defaultOptions          = nullptr;
    QVariantList        settingsList;
102
103
104
    QVariantList        instrumentPageWidgetList;

    QmlObjectListModel _emptyCustomMapItems;
105
106
107
108
109
110
111
112
113
};

QGCCorePlugin::~QGCCorePlugin()
{
    if(_p) {
        delete _p;
    }
}

114
115
QGCCorePlugin::QGCCorePlugin(QGCApplication *app, QGCToolbox* toolbox)
    : QGCTool(app, toolbox)
116
    , _showTouchAreas(false)
117
    , _showAdvancedUI(true)
118
119
120
121
122
123
{
    _p = new QGCCorePlugin_p;
}

void QGCCorePlugin::setToolbox(QGCToolbox *toolbox)
{
DonLakeFlyer's avatar
DonLakeFlyer committed
124
125
126
127
    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");
128
129
130
131
132
133
134
135
136
137
138
139
    //-- Handle Camera and Video Changes
    connect(toolbox->multiVehicleManager(), &MultiVehicleManager::activeVehicleChanged, this, &QGCCorePlugin::_activeVehicleChanged);
}

void QGCCorePlugin::_activeVehicleChanged(Vehicle* activeVehicle)
{
    if(activeVehicle != _activeVehicle) {
        if(_activeVehicle) {
            disconnect(_activeVehicle, &Vehicle::dynamicCamerasChanged, this, &QGCCorePlugin::_dynamicCamerasChanged);
        }
        if(_dynamicCameras) {
            disconnect(_dynamicCameras, &QGCCameraManager::currentCameraChanged, this, &QGCCorePlugin::_currentCameraChanged);
140
            _dynamicCameras = nullptr;
141
142
        }
        _activeVehicle = activeVehicle;
143
144
145
        if(_activeVehicle) {
            connect(_activeVehicle, &Vehicle::dynamicCamerasChanged, this, &QGCCorePlugin::_dynamicCamerasChanged);
        }
146
147
148
149
150
    }
}

void QGCCorePlugin::_dynamicCamerasChanged()
{
151
152
153
154
    if(_currentCamera) {
        disconnect(_currentCamera, &QGCCameraControl::autoStreamChanged, this, &QGCCorePlugin::_autoStreamChanged);
        _currentCamera = nullptr;
    }
155
156
    if(_activeVehicle) {
        _dynamicCameras = _activeVehicle->dynamicCameras();
157
158
159
        if(_dynamicCameras) {
            connect(_dynamicCameras, &QGCCameraManager::currentCameraChanged, this, &QGCCorePlugin::_currentCameraChanged);
        }
160
161
162
163
    }
}

void QGCCorePlugin::_currentCameraChanged()
164
165
166
167
168
169
170
171
172
173
174
175
176
177
{
    if(_dynamicCameras) {
        QGCCameraControl* cp = _dynamicCameras->currentCameraInstance();
        if(_currentCamera) {
            disconnect(_currentCamera, &QGCCameraControl::autoStreamChanged, this, &QGCCorePlugin::_autoStreamChanged);
        }
        if(_currentCamera != cp) {
            _currentCamera = cp;
            connect(_currentCamera, &QGCCameraControl::autoStreamChanged, this, &QGCCorePlugin::_autoStreamChanged);
        }
    }
}

void QGCCorePlugin::_autoStreamChanged()
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
{
    _resetInstrumentPages();
    emit instrumentPagesChanged();
}

void QGCCorePlugin::_resetInstrumentPages()
{
    if (_p->valuesPageWidgetInfo) {
        _p->valuesPageWidgetInfo->deleteLater();
        _p->valuesPageWidgetInfo = nullptr;
    }
    if(_p->cameraPageWidgetInfo) {
        _p->cameraPageWidgetInfo->deleteLater();
        _p->cameraPageWidgetInfo = nullptr;
    }
#if defined(QGC_GST_STREAMING)
    if(_p->videoPageWidgetInfo) {
        _p->videoPageWidgetInfo->deleteLater();
        _p->videoPageWidgetInfo = nullptr;
    }
#endif
    if(_p->healthPageWidgetInfo) {
        _p->healthPageWidgetInfo->deleteLater();
        _p->healthPageWidgetInfo = nullptr;
    }
    if(_p->vibrationPageWidgetInfo) {
        _p->vibrationPageWidgetInfo->deleteLater();
        _p->vibrationPageWidgetInfo = nullptr;
    }
    _p->instrumentPageWidgetList.clear();
208
209
}

210
QVariantList &QGCCorePlugin::settingsPages()
211
212
{
    if(!_p->pGeneral) {
213
        _p->pGeneral = new QmlComponentInfo(tr("General"),
214
215
216
            QUrl::fromUserInput("qrc:/qml/GeneralSettings.qml"),
            QUrl::fromUserInput("qrc:/res/gear-white.svg"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pGeneral)));
217
        _p->pCommLinks = new QmlComponentInfo(tr("Comm Links"),
218
219
220
            QUrl::fromUserInput("qrc:/qml/LinkSettings.qml"),
            QUrl::fromUserInput("qrc:/res/waves.svg"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pCommLinks)));
221
        _p->pOfflineMaps = new QmlComponentInfo(tr("Offline Maps"),
222
223
224
            QUrl::fromUserInput("qrc:/qml/OfflineMap.qml"),
            QUrl::fromUserInput("qrc:/res/waves.svg"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pOfflineMaps)));
225
226
227
228
229
230
#if defined(QGC_GST_TAISYNC_ENABLED)
        _p->pTaisync = new QmlComponentInfo(tr("Taisync"),
            QUrl::fromUserInput("qrc:/qml/TaisyncSettings.qml"),
            QUrl::fromUserInput(""));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pTaisync)));
#endif
231
232
233
234
235
236
#if defined(QGC_GST_MICROHARD_ENABLED)
        _p->pMicrohard = new QmlComponentInfo(tr("Microhard"),
            QUrl::fromUserInput("qrc:/qml/MicrohardSettings.qml"),
            QUrl::fromUserInput(""));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pMicrohard)));
#endif
Gus Grubba's avatar
Gus Grubba committed
237
#if defined(QGC_AIRMAP_ENABLED)
Gus Grubba's avatar
Gus Grubba committed
238
        _p->pAirmap = new QmlComponentInfo(tr("AirMap"),
239
240
241
            QUrl::fromUserInput("qrc:/qml/AirmapSettings.qml"),
            QUrl::fromUserInput(""));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pAirmap)));
Gus Grubba's avatar
Gus Grubba committed
242
#endif
243
        _p->pMAVLink = new QmlComponentInfo(tr("MAVLink"),
244
245
246
            QUrl::fromUserInput("qrc:/qml/MavlinkSettings.qml"),
            QUrl::fromUserInput("qrc:/res/waves.svg"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pMAVLink)));
247
        _p->pConsole = new QmlComponentInfo(tr("Console"),
248
249
            QUrl::fromUserInput("qrc:/qml/QGroundControl/Controls/AppMessages.qml"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pConsole)));
Don Gagne's avatar
   
Don Gagne committed
250
        _p->pHelp = new QmlComponentInfo(tr("Help"),
251
252
            QUrl::fromUserInput("qrc:/qml/HelpSettings.qml"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pHelp)));
DonLakeFlyer's avatar
DonLakeFlyer committed
253
#if defined(QT_DEBUG)
254
        //-- These are always present on Debug builds
255
        _p->pMockLink = new QmlComponentInfo(tr("Mock Link"),
256
257
            QUrl::fromUserInput("qrc:/qml/MockLink.qml"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pMockLink)));
258
        _p->pDebug = new QmlComponentInfo(tr("Debug"),
259
260
            QUrl::fromUserInput("qrc:/qml/DebugWindow.qml"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pDebug)));
261
262
263
        _p->pQmlTest = new QmlComponentInfo(tr("Palette Test"),
            QUrl::fromUserInput("qrc:/qml/QmlTest.qml"));
        _p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pQmlTest)));
DonLakeFlyer's avatar
DonLakeFlyer committed
264
#endif
265
266
267
268
    }
    return _p->settingsList;
}

269
QVariantList& QGCCorePlugin::instrumentPages()
270
271
{
    if (!_p->valuesPageWidgetInfo) {
Gus Grubba's avatar
Gus Grubba committed
272
273
274
        _p->valuesPageWidgetInfo    = new QmlComponentInfo(tr("Values"),    QUrl::fromUserInput("qrc:/qml/ValuePageWidget.qml"));
        _p->cameraPageWidgetInfo    = new QmlComponentInfo(tr("Camera"),    QUrl::fromUserInput("qrc:/qml/CameraPageWidget.qml"));
#if defined(QGC_GST_STREAMING)
275
        if(!_currentCamera || !_currentCamera->autoStream()) {
276
277
278
            //-- Video Page Widget only available if using manual video streaming
            _p->videoPageWidgetInfo = new QmlComponentInfo(tr("Video Stream"), QUrl::fromUserInput("qrc:/qml/VideoPageWidget.qml"));
        }
Gus Grubba's avatar
Gus Grubba committed
279
280
#endif
        _p->healthPageWidgetInfo    = new QmlComponentInfo(tr("Health"),    QUrl::fromUserInput("qrc:/qml/HealthPageWidget.qml"));
281
        _p->vibrationPageWidgetInfo = new QmlComponentInfo(tr("Vibration"), QUrl::fromUserInput("qrc:/qml/VibrationPageWidget.qml"));
282
283
284

        _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->valuesPageWidgetInfo));
        _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->cameraPageWidgetInfo));
Gus Grubba's avatar
Gus Grubba committed
285
286
287
#if defined(QGC_GST_STREAMING)
        _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->videoPageWidgetInfo));
#endif
288
289
290
291
292
293
        _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->healthPageWidgetInfo));
        _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->vibrationPageWidgetInfo));
    }
    return _p->instrumentPageWidgetList;
}

294
int QGCCorePlugin::defaultSettings()
295
296
297
298
{
    return 0;
}

299
300
301
302
303
304
305
306
QGCOptions* QGCCorePlugin::options()
{
    if(!_p->defaultOptions) {
        _p->defaultOptions = new QGCOptions();
    }
    return _p->defaultOptions;
}

Don Gagne's avatar
Don Gagne committed
307
308
309
bool QGCCorePlugin::overrideSettingsGroupVisibility(QString name)
{
    Q_UNUSED(name);
310

Don Gagne's avatar
Don Gagne committed
311
312
313
    // Always show all
    return true;
}
314

315
bool QGCCorePlugin::adjustSettingMetaData(const QString& settingsGroup, FactMetaData& metaData)
316
{
317
318
    if (settingsGroup != AppSettings::settingsGroup) {
        // All changes refer to AppSettings
Gus Grubba's avatar
Gus Grubba committed
319
320
321
322
323
324
325
326
#if !defined(QGC_ENABLE_PAIRING)
        //-- If we don't support pairing, disable it.
        if (metaData.name() == AppSettings::usePairingName) {
            metaData.setRawDefaultValue(false);
            //-- And hide the option
            return false;
        }
#endif
327
328
329
        return true;
    }

330
    //-- Default Palette
Don Gagne's avatar
Don Gagne committed
331
332
333
334
335
336
337
338
    if (metaData.name() == AppSettings::indoorPaletteName) {
        QVariant outdoorPalette;
#if defined (__mobile__)
        outdoorPalette = 0;
#else
        outdoorPalette = 1;
#endif
        metaData.setRawDefaultValue(outdoorPalette);
339
340
341
342
343
        return true;
    //-- Auto Save Telemetry Logs
    } else if (metaData.name() == AppSettings::telemetrySaveName) {
#if defined (__mobile__)
        metaData.setRawDefaultValue(false);
344
        return true;
345
346
347
#else
        metaData.setRawDefaultValue(true);
        return true;
348
349
350
351
352
353
354
#endif
#if defined(__ios__)
    } else if (metaData.name() == AppSettings::savePathName) {
        QString appName = qgcApp()->applicationName();
        QDir rootDir = QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
        metaData.setRawDefaultValue(rootDir.filePath(appName));
        return false;
355
#endif
Don Gagne's avatar
Don Gagne committed
356
    }
357
    return true; // Show setting in ui
358
}
DonLakeFlyer's avatar
DonLakeFlyer committed
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

void QGCCorePlugin::setShowTouchAreas(bool show)
{
    if (show != _showTouchAreas) {
        _showTouchAreas = show;
        emit showTouchAreasChanged(show);
    }
}

void QGCCorePlugin::setShowAdvancedUI(bool show)
{
    if (show != _showAdvancedUI) {
        _showAdvancedUI = show;
        emit showAdvancedUIChanged(show);
    }
}
375
376
377
378
379
380

void QGCCorePlugin::paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo)
{
    Q_UNUSED(colorName);
    Q_UNUSED(colorInfo);
}
381

382
QString QGCCorePlugin::showAdvancedUIMessage() const
383
384
385
386
387
388
{
    return tr("WARNING: You are about to enter Advanced Mode. "
              "If used incorrectly, this may cause your vehicle to malfunction thus voiding your warranty. "
              "You should do so only if instructed by customer support. "
              "Are you sure you want to enable Advanced Mode?");
}
389
390
391
392
393
394

void QGCCorePlugin::valuesWidgetDefaultSettings(QStringList& largeValues, QStringList& smallValues)
{
    Q_UNUSED(smallValues);
    largeValues << "Vehicle.altitudeRelative" << "Vehicle.groundSpeed" << "Vehicle.flightTime";
}
395
396
397
398
399
400
401

QQmlApplicationEngine* QGCCorePlugin::createRootWindow(QObject *parent)
{
    QQmlApplicationEngine* pEngine = new QQmlApplicationEngine(parent);
    pEngine->addImportPath("qrc:/qml");
    pEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
    pEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
402
    pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainRootWindow.qml")));
403
404
    return pEngine;
}
405
406
407
408
409
410
411
412
413

bool QGCCorePlugin::mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlink_message_t message)
{
    Q_UNUSED(vehicle);
    Q_UNUSED(link);
    Q_UNUSED(message);

    return true;
}
414

415
QmlObjectListModel* QGCCorePlugin::customMapItems()
416
417
418
{
    return &_p->_emptyCustomMapItems;
}
419

420
421
422
423
424
VideoManager* QGCCorePlugin::createVideoManager(QGCApplication *app, QGCToolbox *toolbox)
{
    return new VideoManager(app, toolbox);
}

425
426
427
428
VideoReceiver* QGCCorePlugin::createVideoReceiver(QObject* parent)
{
    return new VideoReceiver(parent);
}
Don Gagne's avatar
   
Don Gagne committed
429

430
bool QGCCorePlugin::guidedActionsControllerLogging() const
Don Gagne's avatar
   
Don Gagne committed
431
432
433
{
    return GuidedActionsControllerLog().isDebugEnabled();
}
Don Gagne's avatar
   
Don Gagne committed
434

435
QString QGCCorePlugin::stableVersionCheckFileUrl() const
Don Gagne's avatar
   
Don Gagne committed
436
437
438
439
440
441
442
443
{
#ifdef QGC_CUSTOM_BUILD
    // Custom builds must override to turn on and provide their own location
    return QString();
#else
    return QString("https://s3-us-west-2.amazonaws.com/qgroundcontrol/latest/QGC.version.txt");
#endif
}