mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
map-widget: don't crash if the map QML failed to load
If the QML modules for QtLocation and QtPositioning are missing the QML in mapwidget.cpp will fail to load, which can lead to crashes. To solve the issue check if the QML has loaded and set a flag 'isReady' to true. If the loading has failed load another QML which is for showing a red error text in the lines of `MapWidget.qml failed to load!`. If the map QML has failed, use a macro in all relevant MapWidget members to turn them into a NOP. This approach leaves the rest of the codebase intact - e.g. no checks in classes which connect to the MapWidget class. Fixes #596 Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
This commit is contained in:
parent
d1a18b36b4
commit
174b414436
3 changed files with 38 additions and 5 deletions
|
@ -12,8 +12,14 @@
|
|||
#include "mainwindow.h"
|
||||
#include "divelistview.h"
|
||||
|
||||
static const QUrl urlMapWidget = QUrl(QStringLiteral("qrc:/MapWidget.qml"));
|
||||
static const QUrl urlMapWidgetError = QUrl(QStringLiteral("qrc:/MapWidgetError.qml"));
|
||||
static bool isReady = false;
|
||||
static bool skipReload = false;
|
||||
|
||||
#define CHECK_IS_READY_RETURN_VOID() \
|
||||
if (!isReady) return
|
||||
|
||||
MapWidget *MapWidget::m_instance = NULL;
|
||||
|
||||
MapWidget::MapWidget(QWidget *parent) : QQuickWidget(parent)
|
||||
|
@ -22,19 +28,23 @@ MapWidget::MapWidget(QWidget *parent) : QQuickWidget(parent)
|
|||
qmlRegisterType<MapLocationModel>("org.subsurfacedivelog.mobile", 1, 0, "MapLocationModel");
|
||||
qmlRegisterType<MapLocation>("org.subsurfacedivelog.mobile", 1, 0, "MapLocation");
|
||||
|
||||
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
connect(this, &QQuickWidget::statusChanged, this, &MapWidget::doneLoading);
|
||||
setSource(QUrl(QStringLiteral("qrc:/MapWidget.qml")));
|
||||
setSource(urlMapWidget);
|
||||
}
|
||||
|
||||
void MapWidget::doneLoading(QQuickWidget::Status status)
|
||||
{
|
||||
if (status != QQuickWidget::Ready) {
|
||||
qDebug() << "MapWidget status" << status;
|
||||
// the default map widget QML failed; load the error QML.
|
||||
if (source() == urlMapWidget && status != QQuickWidget::Ready) {
|
||||
qDebug() << urlMapWidget << "failed to load with status:" << status;
|
||||
setSource(urlMapWidgetError);
|
||||
return;
|
||||
} else if (source() == urlMapWidgetError) { // the error QML finished loading.
|
||||
return;
|
||||
}
|
||||
qDebug() << "MapWidget ready";
|
||||
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
|
||||
isReady = true;
|
||||
m_rootItem = qobject_cast<QQuickItem *>(rootObject());
|
||||
m_mapHelper = rootObject()->findChild<MapWidgetHelper *>();
|
||||
connect(m_mapHelper, SIGNAL(selectedDivesChanged(QList<int>)),
|
||||
|
@ -45,12 +55,14 @@ void MapWidget::doneLoading(QQuickWidget::Status status)
|
|||
|
||||
void MapWidget::centerOnDiveSite(struct dive_site *ds)
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
if (!skipReload)
|
||||
m_mapHelper->centerOnDiveSite(ds);
|
||||
}
|
||||
|
||||
void MapWidget::centerOnIndex(const QModelIndex& idx)
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
struct dive_site *ds = get_dive_site_by_uuid(idx.model()->index(idx.row(), 0).data().toInt());
|
||||
if (!ds || !dive_site_has_gps_location(ds))
|
||||
centerOnDiveSite(&displayed_dive_site);
|
||||
|
@ -60,11 +72,13 @@ void MapWidget::centerOnIndex(const QModelIndex& idx)
|
|||
|
||||
void MapWidget::repopulateLabels()
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
m_mapHelper->reloadMapLocations();
|
||||
}
|
||||
|
||||
void MapWidget::reload()
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
setEditMode(false);
|
||||
if (!skipReload)
|
||||
m_mapHelper->reloadMapLocations();
|
||||
|
@ -72,21 +86,25 @@ void MapWidget::reload()
|
|||
|
||||
void MapWidget::setEditMode(bool editMode)
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
m_mapHelper->setEditMode(editMode);
|
||||
}
|
||||
|
||||
void MapWidget::endGetDiveCoordinates()
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
setEditMode(false);
|
||||
}
|
||||
|
||||
void MapWidget::prepareForGetDiveCoordinates()
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
setEditMode(true);
|
||||
}
|
||||
|
||||
void MapWidget::selectedDivesChanged(QList<int> list)
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
skipReload = true;
|
||||
MainWindow::instance()->dive_list()->unselectDives();
|
||||
if (!list.empty())
|
||||
|
@ -96,6 +114,7 @@ void MapWidget::selectedDivesChanged(QList<int> list)
|
|||
|
||||
void MapWidget::coordinatesChangedLocal()
|
||||
{
|
||||
CHECK_IS_READY_RETURN_VOID();
|
||||
emit coordinatesChanged();
|
||||
}
|
||||
|
||||
|
|
13
mobile-widgets/qml/MapWidgetError.qml
Normal file
13
mobile-widgets/qml/MapWidgetError.qml
Normal file
|
@ -0,0 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: "red"
|
||||
text: qsTr("MapWidget.qml failed to load!
|
||||
The QML modules QtPositioning and QtLocation could be missing!")
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file alias="MapWidget.qml">mobile-widgets/qml/MapWidget.qml</file>
|
||||
<file alias="MapWidgetError.qml">mobile-widgets/qml/MapWidgetError.qml</file>
|
||||
<file alias="MapWidgetContextMenu.qml">mobile-widgets/qml/MapWidgetContextMenu.qml</file>
|
||||
<file alias="mapwidget-marker">mobile-widgets/qml/icons/mapwidget-marker.png</file>
|
||||
<file alias="mapwidget-marker-selected">mobile-widgets/qml/icons/mapwidget-marker-selected.png</file>
|
||||
|
|
Loading…
Reference in a new issue