diff --git a/images/images.qrc b/images/images.qrc
index 0cb5c552dc..41d98e4586 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -529,5 +529,6 @@
themes/qfield/nodpi/ic_arrow_drop_down_48dp.svg
themes/qfield/nodpi/ic_arrow_drop_up_48dp.svg
themes/qfield/nodpi/ic_shutdown_24dp.svg
+ themes/qfield/nodpi/ic_egeniouss_receiver_black_24dp.svg
diff --git a/images/themes/qfield/nodpi/ic_egeniouss_receiver_black_24dp.svg b/images/themes/qfield/nodpi/ic_egeniouss_receiver_black_24dp.svg
new file mode 100644
index 0000000000..f0cff592c2
--- /dev/null
+++ b/images/themes/qfield/nodpi/ic_egeniouss_receiver_black_24dp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 2328f5d004..24fb44288e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -29,6 +29,7 @@ set(QFIELD_CORE_SRCS
positioning/gnsspositioninformation.cpp
positioning/internalgnssreceiver.cpp
positioning/nmeagnssreceiver.cpp
+ positioning/egenioussreceiver.cpp
positioning/tcpreceiver.cpp
positioning/udpreceiver.cpp
positioning/positioning.cpp
@@ -150,6 +151,7 @@ set(QFIELD_CORE_HDRS
positioning/positioningdevicemodel.h
positioning/internalgnssreceiver.h
positioning/nmeagnssreceiver.h
+ positioning/egenioussreceiver.h
positioning/tcpreceiver.h
positioning/udpreceiver.h
positioning/geofencer.h
diff --git a/src/core/pluginmanager.cpp b/src/core/pluginmanager.cpp
index 9c2c48cd09..ab203f2b95 100644
--- a/src/core/pluginmanager.cpp
+++ b/src/core/pluginmanager.cpp
@@ -138,22 +138,28 @@ void PluginManager::handleWarnings( const QList &warnings )
void PluginManager::grantRequestedPluginPermission( bool permanent )
{
+ QSettings settings;
+ QString pluginKey = mPermissionRequestPluginPath;
+ pluginKey.replace( QChar( '/' ), QChar( '_' ) );
+ settings.beginGroup( QStringLiteral( "/qfield/plugins/%1" ).arg( pluginKey ) );
+ const QString uuid = settings.value( QStringLiteral( "uuid" ) ).toString();
+
if ( permanent )
{
- QSettings settings;
- QString pluginKey = mPermissionRequestPluginPath;
- pluginKey.replace( QChar( '/' ), QChar( '_' ) );
- settings.beginGroup( QStringLiteral( "/qfield/plugins/%1" ).arg( pluginKey ) );
settings.setValue( QStringLiteral( "permissionGranted" ), true );
- if ( !settings.value( QStringLiteral( "uuid" ) ).toString().isEmpty() )
+ if ( !uuid.isEmpty() )
{
settings.setValue( QStringLiteral( "userEnabled" ), true );
}
- settings.endGroup();
}
+ settings.endGroup();
loadPlugin( mPermissionRequestPluginPath, QString(), true );
mPermissionRequestPluginPath.clear();
+ if ( !uuid.isEmpty() )
+ {
+ callPluginMethod( uuid, "appWideEnabled" );
+ }
}
void PluginManager::denyRequestedPluginPermission( bool permanent )
@@ -272,10 +278,11 @@ void PluginManager::enableAppPlugin( const QString &uuid )
{
if ( mAvailableAppPlugins.contains( uuid ) )
{
- if ( !mLoadedPlugins.contains( mAvailableAppPlugins[uuid].path() ) )
+ const QString pluginPath = mAvailableAppPlugins[uuid].path();
+ if ( !mLoadedPlugins.contains( pluginPath ) )
{
QSettings settings;
- QString pluginKey = mAvailableAppPlugins[uuid].path();
+ QString pluginKey = pluginPath;
pluginKey.replace( QChar( '/' ), QChar( '_' ) );
settings.beginGroup( QStringLiteral( "/qfield/plugins/%1" ).arg( pluginKey ) );
settings.setValue( QStringLiteral( "uuid" ), uuid );
@@ -285,13 +292,19 @@ void PluginManager::enableAppPlugin( const QString &uuid )
}
settings.endGroup();
- loadPlugin( mAvailableAppPlugins[uuid].path(), mAvailableAppPlugins[uuid].name() );
+ loadPlugin( pluginPath, mAvailableAppPlugins[uuid].name() );
+
+ if ( mLoadedPlugins.contains( pluginPath ) )
+ {
+ callPluginMethod( uuid, "appWideEnabled" );
+ }
}
}
}
void PluginManager::disableAppPlugin( const QString &uuid )
{
+ callPluginMethod( uuid, "appWideDisabled" );
if ( mAvailableAppPlugins.contains( uuid ) )
{
if ( mLoadedPlugins.contains( mAvailableAppPlugins[uuid].path() ) )
@@ -455,3 +468,27 @@ QString PluginManager::findProjectPlugin( const QString &projectPath )
}
return QString();
}
+
+void PluginManager::callPluginMethod( const QString &uuid, const QString &methodName )
+{
+ if ( !mAvailableAppPlugins.contains( uuid ) )
+ {
+ return;
+ }
+
+ const QString pluginPath = mAvailableAppPlugins[uuid].path();
+ if ( !mLoadedPlugins.contains( pluginPath ) )
+ {
+ return;
+ }
+
+ const QPointer object = mLoadedPlugins[pluginPath];
+
+ const char *normalizedSignature = QMetaObject::normalizedSignature( ( methodName + "()" ).toStdString().c_str() );
+ const int methodIndex = object->metaObject()->indexOfSlot( normalizedSignature );
+
+ if ( methodIndex != -1 )
+ {
+ QMetaObject::invokeMethod( object.data(), methodName.toStdString().c_str() );
+ }
+}
diff --git a/src/core/pluginmanager.h b/src/core/pluginmanager.h
index 7be7e30b0d..2d6375ecfe 100644
--- a/src/core/pluginmanager.h
+++ b/src/core/pluginmanager.h
@@ -112,8 +112,10 @@ class PluginManager : public QObject
void installProgress( double progress );
void installEnded( const QString &uuid = QString(), const QString &error = QString() );
+
private slots:
void handleWarnings( const QList &warnings );
+ void callPluginMethod( const QString &uuid, const QString &methodName );
private:
QQmlEngine *mEngine = nullptr;
diff --git a/src/core/positioning/abstractgnssreceiver.h b/src/core/positioning/abstractgnssreceiver.h
index 84cb6b2e20..0688ea1e03 100644
--- a/src/core/positioning/abstractgnssreceiver.h
+++ b/src/core/positioning/abstractgnssreceiver.h
@@ -72,6 +72,7 @@ class AbstractGnssReceiver : public QObject
private:
friend class InternalGnssReceiver;
+ friend class EgenioussReceiver;
friend class NmeaGnssReceiver;
friend class BluetoothReceiver;
friend class TcpReceiver;
diff --git a/src/core/positioning/egenioussreceiver.cpp b/src/core/positioning/egenioussreceiver.cpp
new file mode 100644
index 0000000000..70266bb154
--- /dev/null
+++ b/src/core/positioning/egenioussreceiver.cpp
@@ -0,0 +1,141 @@
+#include "egenioussreceiver.h"
+
+#include
+#include
+#include
+
+EgenioussReceiver::EgenioussReceiver( QObject *parent )
+ : AbstractGnssReceiver( parent ), mTcpSocket( new QTcpSocket() )
+{
+ connect( mTcpSocket, &QTcpSocket::readyRead, this, &EgenioussReceiver::onReadyRead );
+ connect( mTcpSocket, &QTcpSocket::errorOccurred, this, &EgenioussReceiver::handleError );
+ connect( mTcpSocket, &QTcpSocket::connected, this, &EgenioussReceiver::connected );
+ connect( mTcpSocket, &QTcpSocket::disconnected, this, &EgenioussReceiver::disconnected );
+ setValid( true );
+}
+
+void EgenioussReceiver::handleConnectDevice()
+{
+ mTcpSocket->connectToHost( mAddress, mPort, QTcpSocket::ReadWrite );
+}
+
+void EgenioussReceiver::connected()
+{
+ mSocketState = QAbstractSocket::ConnectedState;
+ mSocketStateString = tr( "Successfully connected" );
+ emit socketStateChanged( mSocketState );
+ setValid( true );
+}
+
+void EgenioussReceiver::handleDisconnectDevice()
+{
+ mTcpSocket->disconnectFromHost();
+}
+
+void EgenioussReceiver::disconnected()
+{
+ if ( mTcpSocket->state() == QAbstractSocket::ConnectedState )
+ {
+ mSocketState = QAbstractSocket::UnconnectedState;
+ mSocketStateString = tr( "Disconnected" );
+ emit socketStateChanged( mSocketState );
+ }
+}
+
+QList> EgenioussReceiver::details()
+{
+ QList> detailsList;
+
+ if ( mPayload.isEmpty() )
+ {
+ return detailsList;
+ }
+
+ detailsList.append( qMakePair( "q", mPayload.value( "q" ).toDouble() ) );
+
+ return detailsList;
+}
+
+void EgenioussReceiver::onReadyRead()
+{
+ const int minimumDataSize = 9;
+ const uint8_t validStartByte = 0xFE;
+ const int payloadHeaderSize = 8;
+
+ QByteArray mReceivedData = mTcpSocket->readAll();
+ if ( mReceivedData.size() < minimumDataSize )
+ {
+ mLastError = tr( "Received data is too short to process" );
+ emit lastErrorChanged( mLastError );
+ return;
+ }
+ if ( static_cast( mReceivedData[0] ) != validStartByte )
+ {
+ mLastError = tr( "Invalid start byte" );
+ emit lastErrorChanged( mLastError );
+ return;
+ }
+ uint32_t payloadLength;
+ QDataStream dataStream( mReceivedData.mid( 4, 4 ) );
+ dataStream.setByteOrder( QDataStream::LittleEndian );
+ dataStream >> payloadLength;
+ if ( mReceivedData.size() < payloadHeaderSize + payloadLength )
+ {
+ mLastError = tr( "Received data is too short to contain the payload" );
+ emit lastErrorChanged( mLastError );
+ return;
+ }
+ QJsonDocument jsonDoc = QJsonDocument::fromJson( mReceivedData.mid( payloadHeaderSize, payloadLength ) );
+ if ( jsonDoc.isNull() || !jsonDoc.isObject() )
+ {
+ mLastError = tr( "Failed to parse JSON" );
+ emit lastErrorChanged( mLastError );
+ return;
+ }
+ mPayload = jsonDoc.object();
+ const double latitude = mPayload.value( "lat" ).toDouble() == 0 ? std::numeric_limits::quiet_NaN() : mPayload.value( "lat" ).toDouble();
+ const double longitude = mPayload.value( "lon" ).toDouble() == 0 ? std::numeric_limits::quiet_NaN() : mPayload.value( "lon" ).toDouble();
+ const double elevation = mPayload.value( "alt" ).toDouble() == 0 ? std::numeric_limits::quiet_NaN() : mPayload.value( "alt" ).toDouble();
+ mLastGnssPositionInformation = GnssPositionInformation(
+ latitude,
+ longitude,
+ elevation,
+ std::numeric_limits::quiet_NaN(),
+ std::numeric_limits::quiet_NaN(),
+ QList(),
+ 0,
+ 0,
+ 0,
+ std::numeric_limits::quiet_NaN(),
+ std::numeric_limits::quiet_NaN(),
+ QDateTime::fromMSecsSinceEpoch( mPayload.value( "utc" ).toDouble() / 1e6, Qt::UTC ),
+ QChar(),
+ 0,
+ 1 );
+
+ emit lastGnssPositionInformationChanged( mLastGnssPositionInformation );
+}
+
+void EgenioussReceiver::handleError( QAbstractSocket::SocketError error )
+{
+ switch ( error )
+ {
+ case QAbstractSocket::HostNotFoundError:
+ mLastError = tr( "Could not find the remote host" );
+ break;
+ case QAbstractSocket::NetworkError:
+ mLastError = tr( "Attempt to read or write from socket returned an error" );
+ break;
+ case QAbstractSocket::ConnectionRefusedError:
+ mLastError = tr( "The connection was refused by the remote host" );
+ break;
+ default:
+ mLastError = tr( "TCP receiver error (%1)" ).arg( QMetaEnum::fromType().valueToKey( error ) );
+ break;
+ }
+ mSocketState = QAbstractSocket::UnconnectedState;
+ mSocketStateString = mLastError;
+ qInfo() << QStringLiteral( "EgenioussReceiver: Error: %1" ).arg( mLastError );
+
+ emit lastErrorChanged( mLastError );
+}
diff --git a/src/core/positioning/egenioussreceiver.h b/src/core/positioning/egenioussreceiver.h
new file mode 100644
index 0000000000..d4de3c10a7
--- /dev/null
+++ b/src/core/positioning/egenioussreceiver.h
@@ -0,0 +1,37 @@
+#ifndef EGENIOUSSRECEIVER_H
+#define EGENIOUSSRECEIVER_H
+
+#include "abstractgnssreceiver.h"
+
+#include
+#include
+
+class EgenioussReceiver : public AbstractGnssReceiver
+{
+ Q_OBJECT
+
+ public:
+ explicit EgenioussReceiver( QObject *parent = nullptr );
+
+ private:
+ void handleConnectDevice() override;
+ void handleDisconnectDevice() override;
+ QList> details() override;
+
+ private slots:
+ void onReadyRead();
+ void handleError( QAbstractSocket::SocketError error );
+
+ private:
+ void processReceivedData();
+ void connected();
+ void disconnected();
+
+ private:
+ QTcpSocket *mTcpSocket = nullptr;
+ QJsonObject mPayload;
+ const QHostAddress::SpecialAddress mAddress = QHostAddress::LocalHost;
+ const int mPort = 1235;
+};
+
+#endif // EGENIOUSSRECEIVER_H
diff --git a/src/core/positioning/internalgnssreceiver.cpp b/src/core/positioning/internalgnssreceiver.cpp
index c7413af275..b99e372bb9 100644
--- a/src/core/positioning/internalgnssreceiver.cpp
+++ b/src/core/positioning/internalgnssreceiver.cpp
@@ -104,7 +104,7 @@ void InternalGnssReceiver::handleConnectDevice()
Qt::PermissionStatus permissionStatus = qApp->checkPermission( locationPermission );
if ( permissionStatus == Qt::PermissionStatus::Undetermined )
{
- qApp->requestPermission( locationPermission, [=]( const QPermission &permission ) {
+ qApp->requestPermission( locationPermission, this, [=]( const QPermission &permission ) {
if ( permission.status() == Qt::PermissionStatus::Granted )
{
mPermissionChecked = true;
diff --git a/src/core/positioning/positioning.cpp b/src/core/positioning/positioning.cpp
index 94e46a951d..49d010ad6e 100644
--- a/src/core/positioning/positioning.cpp
+++ b/src/core/positioning/positioning.cpp
@@ -20,6 +20,7 @@
#ifdef WITH_SERIALPORT
#include "serialportreceiver.h"
#endif
+#include "egenioussreceiver.h"
#include "internalgnssreceiver.h"
#include "positioning.h"
#include "positioningutils.h"
@@ -205,6 +206,10 @@ void Positioning::setupDevice()
const int port = mDeviceId.mid( portSeparator + 1 ).toInt();
mReceiver = new UdpReceiver( address, port, this );
}
+ else if ( mDeviceId.startsWith( QStringLiteral( "egeniouss:" ) ) )
+ {
+ mReceiver = new EgenioussReceiver( this );
+ }
#ifdef WITH_SERIALPORT
else if ( mDeviceId.startsWith( QStringLiteral( "serial:" ) ) )
{
diff --git a/src/core/positioning/positioning.h b/src/core/positioning/positioning.h
index 0c8a2ba322..11c4036fda 100644
--- a/src/core/positioning/positioning.h
+++ b/src/core/positioning/positioning.h
@@ -201,7 +201,6 @@ class Positioning : public QObject
void setLogging( bool logging );
signals:
-
void activeChanged();
void deviceIdChanged();
void deviceChanged();
diff --git a/src/core/positioning/positioningdevicemodel.cpp b/src/core/positioning/positioningdevicemodel.cpp
index 83ba568868..553f5e22b6 100644
--- a/src/core/positioning/positioningdevicemodel.cpp
+++ b/src/core/positioning/positioningdevicemodel.cpp
@@ -171,6 +171,9 @@ const QString PositioningDeviceModel::deviceId( const Device &device ) const
case SerialPortDevice:
return QStringLiteral( "serial:%1" ).arg( device.settings.value( QStringLiteral( "address" ) ).toString() );
+
+ case EgenioussDevice:
+ return QStringLiteral( "egeniouss:" );
}
return QString();
diff --git a/src/core/positioning/positioningdevicemodel.h b/src/core/positioning/positioningdevicemodel.h
index c358ca7fb2..4130c4da85 100644
--- a/src/core/positioning/positioningdevicemodel.h
+++ b/src/core/positioning/positioningdevicemodel.h
@@ -29,6 +29,7 @@ class PositioningDeviceModel : public QAbstractListModel
BluetoothDevice,
TcpDevice,
UdpDevice,
+ EgenioussDevice,
SerialPortDevice,
};
Q_ENUM( Type )
diff --git a/src/core/positioning/positioninginformationmodel.h b/src/core/positioning/positioninginformationmodel.h
index d574c0facd..570e8b8088 100644
--- a/src/core/positioning/positioninginformationmodel.h
+++ b/src/core/positioning/positioninginformationmodel.h
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef POSITIONINGINFORMATIONMODEL_H
+#define POSITIONINGINFORMATIONMODEL_H
#include "positioning.h"
@@ -118,3 +119,5 @@ class PositioningInformationModel : public QStandardItemModel
QgsCoordinateReferenceSystem mCoordinateDisplayCrs;
QMetaObject::Connection positioningSourceConnection;
};
+
+#endif // POSITIONINGINFORMATIONMODEL_H
diff --git a/src/core/positioning/tcpreceiver.cpp b/src/core/positioning/tcpreceiver.cpp
index 072e7de5b9..0c88b3df3b 100644
--- a/src/core/positioning/tcpreceiver.cpp
+++ b/src/core/positioning/tcpreceiver.cpp
@@ -119,7 +119,7 @@ void TcpReceiver::handleError( QAbstractSocket::SocketError error )
mLastError = tr( "The connection was refused by the remote host" );
break;
default:
- mLastError = tr( "UDP receiver error (%1)" ).arg( QMetaEnum::fromType().valueToKey( error ) );
+ mLastError = tr( "TCP receiver error (%1)" ).arg( QMetaEnum::fromType().valueToKey( error ) );
break;
}
qInfo() << QStringLiteral( "TcpReceiver: Error: %1" ).arg( mLastError );
diff --git a/src/qml/EgenioussDeviceChooser.qml b/src/qml/EgenioussDeviceChooser.qml
new file mode 100644
index 0000000000..74b2980a0f
--- /dev/null
+++ b/src/qml/EgenioussDeviceChooser.qml
@@ -0,0 +1,21 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import org.qfield
+import Theme
+
+Item {
+ width: parent.width
+
+ function generateName() {
+ return "Egeniouss";
+ }
+
+ function setSettings(settings) {
+ // nothing to save!
+ }
+
+ function getSettings() {
+ return {};
+ }
+}
diff --git a/src/qml/PositioningDeviceSettings.qml b/src/qml/PositioningDeviceSettings.qml
index a9b3d97e47..d6915faa7b 100644
--- a/src/qml/PositioningDeviceSettings.qml
+++ b/src/qml/PositioningDeviceSettings.qml
@@ -41,6 +41,20 @@ Popup {
return positioningDeviceItem.item.getSettings();
}
+ function handleEgenioussChange() {
+ if (positioningSettings.egenioussEnabled) {
+ positioningDeviceTypeModel.insert(0, {
+ "name": qsTr('Egeniouss'),
+ "value": PositioningDeviceModel.EgenioussDevice
+ });
+ } else {
+ positioningDeviceTypeModel.remove(0, 1);
+ positioningDeviceModel.removeDevice("Egeniouss");
+ positioningDeviceComboBox.currentIndex = 0;
+ }
+ positioningDeviceType.model = positioningDeviceTypeModel;
+ }
+
Component.onCompleted: {
if (withBluetooth) {
positioningDeviceTypeModel.insert(0, {
@@ -54,7 +68,14 @@ Popup {
"value": PositioningDeviceModel.SerialPortDevice
});
}
+ if (positioningSettings.egenioussEnabled) {
+ positioningDeviceTypeModel.insert(0, {
+ "name": qsTr('Egeniouss'),
+ "value": PositioningDeviceModel.EgenioussDevice
+ });
+ }
positioningDeviceType.model = positioningDeviceTypeModel;
+ positioningSettings.onEgenioussEnabledChanged.connect(handleEgenioussChange);
}
Page {
@@ -95,7 +116,7 @@ Popup {
id: positioningDeviceName
Layout.fillWidth: true
font: Theme.defaultFont
- placeholderText: displayText == '' ? qsTr('Leave empty to auto-fill') : ''
+ placeholderText: displayText === '' ? qsTr('Leave empty to auto-fill') : ''
}
Label {
@@ -130,6 +151,8 @@ Popup {
return Theme.getThemeVectorIcon('ic_udp_receiver_black_24dp');
case PositioningDeviceModel.SerialPortDevice:
return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp');
+ case PositioningDeviceModel.EgenioussDevice:
+ return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp');
}
return '';
}
@@ -154,6 +177,8 @@ Popup {
return Theme.getThemeVectorIcon('ic_udp_receiver_black_24dp');
case PositioningDeviceModel.SerialPortDevice:
return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp');
+ case PositioningDeviceModel.EgenioussDevice:
+ return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp');
}
return '';
}
@@ -193,6 +218,8 @@ Popup {
return "qrc:/qml/UdpDeviceChooser.qml";
case PositioningDeviceModel.SerialPortDevice:
return "qrc:/qml/SerialPortDeviceChooser.qml";
+ case PositioningDeviceModel.EgenioussDevice:
+ return "qrc:/qml/EgenioussDeviceChooser.qml";
}
return '';
}
diff --git a/src/qml/PositioningInformationView.qml b/src/qml/PositioningInformationView.qml
index d69454f7ae..5058e2b42a 100644
--- a/src/qml/PositioningInformationView.qml
+++ b/src/qml/PositioningInformationView.qml
@@ -35,7 +35,7 @@ Rectangle {
id: grid
readonly property real numberOfColumns: parent.width > 1000 ? 6 : parent.width > 620 ? 3 : 2
- readonly property real numberOfRows: grid.count / numberOfColumns
+ readonly property real numberOfRows: Math.ceil(grid.count / numberOfColumns)
flow: GridView.FlowTopToBottom
boundsBehavior: Flickable.StopAtBounds
@@ -44,15 +44,15 @@ Rectangle {
distanceUnits: projectInfo.distanceUnits
coordinateDisplayCrs: projectInfo.coordinateDisplayCrs
}
- height: numberOfRows * cellHeight
+ height: grid.numberOfRows * cellHeight
width: parent.width
cellHeight: positioningInformationView.cellHeight
cellWidth: parent.width / numberOfColumns
clip: true
delegate: Rectangle {
- readonly property real currentColumn: parseInt(index / (grid.count / grid.numberOfColumns))
- readonly property real currentRow: index % (grid.count / grid.numberOfColumns)
+ readonly property real currentColumn: parseInt(index / grid.numberOfRows)
+ readonly property real currentRow: index % grid.numberOfRows
width: grid.cellWidth
height: grid.cellHeight
diff --git a/src/qml/PositioningSettings.qml b/src/qml/PositioningSettings.qml
index 87c0a5b4e2..614c988edd 100644
--- a/src/qml/PositioningSettings.qml
+++ b/src/qml/PositioningSettings.qml
@@ -45,4 +45,5 @@ Settings {
property int digitizingMeasureType: 1
property bool geofencingPreventDigitizingDuringAlert: false
+ property bool egenioussEnabled: false
}
diff --git a/src/qml/QFieldSettings.qml b/src/qml/QFieldSettings.qml
index 35c191704f..180a914336 100644
--- a/src/qml/QFieldSettings.qml
+++ b/src/qml/QFieldSettings.qml
@@ -871,6 +871,8 @@ Page {
return Theme.getThemeVectorIcon('ic_udp_receiver_black_24dp');
case PositioningDeviceModel.SerialPortDevice:
return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp');
+ case PositioningDeviceModel.EgenioussDevice:
+ return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp');
}
return '';
}
@@ -897,6 +899,8 @@ Page {
return Theme.getThemeVectorIcon('ic_udp_receiver_black_24dp');
case PositioningDeviceModel.SerialPortDevice:
return Theme.getThemeVectorIcon('ic_serial_port_receiver_black_24dp');
+ case PositioningDeviceModel.EgenioussDevice:
+ return Theme.getThemeVectorIcon('ic_egeniouss_receiver_black_24dp');
}
return '';
}
diff --git a/src/qml/qgismobileapp.qml b/src/qml/qgismobileapp.qml
index 7626ec4903..2cece6ee17 100644
--- a/src/qml/qgismobileapp.qml
+++ b/src/qml/qgismobileapp.qml
@@ -243,6 +243,7 @@ ApplicationWindow {
PositioningSettings {
id: positioningSettings
+ objectName: "positioningSettings"
onPositioningActivatedChanged: {
if (positioningActivated) {
diff --git a/src/qml/qml.qrc b/src/qml/qml.qrc
index 63836d9ba2..ddcafd53dc 100644
--- a/src/qml/qml.qrc
+++ b/src/qml/qml.qrc
@@ -43,6 +43,7 @@
ScaleBar.qml
SensorInformationView.qml
Toast.qml
+ EgenioussDeviceChooser.qml
TcpDeviceChooser.qml
UdpDeviceChooser.qml
VariableEditor.qml